Shibuya.list TT #4に行ってきました

Lisp入門

  • 広域変数定義はdefine
(+ 1 2)

この+は演算子ではなく関数

  • 広域変数定義はdefine
(define a 1)
  • 変数上書き
(set! a (+ a 1)) 

set!は変数上書きkk

  • ローカル変数
(let ((x 1) (y 2) (+ x y)))
  • 関数定義もdefineで
(define (add3 n ) (+ n 3))

nは引数
(+ n 3)は関数本体

    • > function add3(n){return n+ 3 }のようなもの
  • quote

(quote (add3 1)) -> 省略 -> '(add3 1)
quoteで定義した式は値として認識される
"実行されない"

  • シンボルa,b,cってなに?
    • 変数や関数名のようなもの
  • carとは
(car '(1 2))
1

S式の先頭の要素が出力される

  • cdrとは
(car '(1 2))
2

S式の先頭の要素を除いたものが出力される

  • consとは

聞き逃した。。。

  • 階乗計算をしてみよう
(define (fact n)
         (if (= n 0)
           1
         (* n (fact (- n 1)))))

if関数の第一引数は条件、第二引数は 条件に合致した場合の処理(この場合は1) 第三引数は条件に合致しない場合の処理

  • S式をhtmlにコンバートする関数を作ってみよう
(define (print-html e)
    (if (list? e)
      (begin (format #t "<~a>" (car e))
        (print-html-list (cdr e))
        (format #t "</~a>" (car e)))
      (display e)));S式ではなかったら出力
(define (print-html-list l)
    (if (null? l)
      (begin (print-html (car l))
        (print-html-list (cdr l)))))
  • マクロ

????
あとで勉強する

1980年前後のLisp事情とUtiLisp

卒論で作ったMicro Lisp(1976)

実装
  • 16ビットをアドレスとして扱えるレジスタは1組だけ
    • car/cdrとるだけでも大変
  • Lispではまずcarを処理、cdrはあとでが多い
  • Lispのimplementはcdrの方を先のアドレスに書くことが多い
    • offset 0 はcdr
  1. HLレジスタペアをスタックにpush
  2. cdrをとってHLレジスタ
  3. HLの内容とスタックトップを交換
  4. carをとってレジスタ

1980年ころのLisp事情

  • Lisp 1.5(IBM 704;1960-)@MIT
    • Josh MacCarthy
  • Imterlisp(PDP-10;1967~)@Stanford
  • Maclisp(PDF-6/10;1970~)@MIT

1980年ころの日本のコンピュータ事情

    • 大学当で使っていたのはほとんど国産コンピュータ
  • 国内メーカが互換機を廉価(8割り引きくらい)で提供

1980年ころの日本のLisp事情

    • 中西 慶応 KLISP (TOSBAC 3400)
    • 安井 阪大 OLISP(NEAC)
    • 竹内、奥乃 NTT LIPQ ,LIPX(PDP-11)
    • 後藤、金田 東大 HLISP( HITAC 8800/8700)

修論で作ったPascal上のLisp

  • 占有して使える最大規模の計算機はFacom 230/38
    • 16bit x 64Kwordの空間が二つ(命令用、データ用)
  • Pascal処理系が多くのソフトベース
    • この上にLispを作ってみようと思った
  • Pascalのポインタは自由に操作不可能
    • ポインタはあるが、さす先を使えるだけ
    • heapを配列にとるので性能がでない
  • Pascal処理系のメンテナもしていた
    • Lispが使えるように言語仕様を変更
    • 秘密のオプションでポインタが増減できるように変更

UtiLisp

[http://gps.tanaka.ecc.u-tokyo.ac.jp/wadalabfont/pukiwiki.php?UtiLisp/C:title=UtiLisp( University of Tokyo Interactive Lisp)]

  • > utile = useful

各種の機能を整合性よく提供

    • 個別な機能とせず、なるべく一般化、ユーザ定義可能に
    • 可能なところは全て暗黙のprognに
  • 使いやすさを重視
    • オプショナル引数
    • マクロ機能
    • catch-throw
  • インタプリタ当基本部をアセンブラで(1980/7~12)
    • それまでのLisp処理系開発経験から、容易と判断
    • System/360系のアセンブラはかなり使いやすい
  • データ型の表現
    • 基本的にはポインタタグ
      • ポインタのさす先のデータ型をポインタ内にもつ
      • 上8bitは型情報、残り24bitがアドレス
      • データ型の判定にメモリAddressが不要
  • 組み込みデータ型
  • タグ(型情報)割り当て
    • signかunsignかを上手に割り当て

atom(x):x >= 0
symbolp(x):x>=7000

Lispの楽しさ

  • 気軽に構造を作って捨てられる
  • Lispはvon Neumann型言語
    • プログラムとデータを同じmemoryに格納
    • プログラムをデータとして扱える

Prologもプログラムとデータは同じ形式

  • 動作をPrologプログラムとして記述可能

質問

  • UtiLispのNILはどのように表現
    • atomとして実装
  • 30年も前の実装のことをどのように思い出したか
    • History of UtiLisp Hackingという論文をみた
    • 竹石先生のLisp記事をみる
    • それ以外はWikipedia
  • kUtiLispで満足いかなかったところ
    • 現在だったらポータビリティを重視してただろう
  • Common Lispの評価は?
    • Common Lispが出たときには既にLisp開発者じゃなかったので 評価できないが、
    • 機能がたくさんついているが、それを誇示しているような印象をうけた
  • collerは何個渡すか知っている,colleeは引数何個が最大化を知っている

ここで電池切れ

感想

  • Lispってlambdaというものさえあれば条件分岐も繰り返しもかけてすごい
  • 数もlambdaであらわせる->チャーチ数
  • 本体部分のimplementは意外と簡単に実装できるらしい