lisp の説明をする簡単なお仕事です
バイト先にコンピュータ関係の学科の大学生がいて、何を間違ったか lisp の勉強をし始めたらしく(プライベートで)、バイト中に lisp の質問をしてくる。
「2番目の要素」?
なにやら lisp の本を読んでるらしくて、例題にあった「与えられたリストの2番目の要素を返す関数を作れ」みたいなのを教えようとしたのだけど、説明してるうちに「2番目の要素」とはなんなのかわからなくなった。
そっこーで思いついたのが
(defun 2nd (list) (second list))
なのだけど、これじゃ元も子も無いので封印。
なんかまだ知ってる関数が '(define lambda car cdr cons) くらいだとか言い出したので、defun と define の違いは無視しつつ、car と cdr で2番目の要素を得るべくコンスセルの説明をしてみた。
(a b c d)
という list は
(a . (b . (c . (d . nil))))
という構造だというとこまでは(どうやら)理解してもらえたのだけど、ここで俺が混乱し始める。というのは list = 入れ子になったコンスセル と考えると、さっきの (a b c d) という list は (a . (b . (c . (d . nil)))) というコンスセルで、この (a . ...) つーコンスセルの2番目の要素というのは ... の部分= (b . (c . (d . nil))) で、つまり 2nd の定義はこうなる。
(defun 2nd (list) (cdr list))
な、なんだってー
でも常識的に考えて list (a b c d) の2番目の要素は symbol b だろ。
(defun 2nd (list) (car (cdr list)))
lisp の式は順番が逆
気を取り直して「与えられた list の cdr の car が2番目の要素なんで、それを返す関数を書けばおk」と言ったら、彼はこんな式を書いた。
(cdr (car list))
しむらー、ぎゃk
それ見て思ったのが、ふつーの言語というか C 風(?)の言語だと「この list の cdr の car」というのは
myList.cdr.car
みたいになって、ドットを「の」に置換すれば 'mylistのcdrのcar' となんともナチュラルに読める。lisp は逆から読まないといけない。
(cdr (car my-list)) ;1. my-list の ;2. car の ;3. cdr
英語だと "cdr of car of my-list" でむしろナチュラルなのか?
else ってなんて読むの
あと、lisp と言えば再帰だろってんで再帰の説明をしようと
(defun fact (x) (if (= x 1) 1 (+ x (fact (- x 1)))))
みたいなコードを書いたら「とりあえずその if から説明してください」というので、そっからかよ!と心の中で突っ込みつつ (if CONDITION THEN-FORM ELSE-FORM) とか書いて説明してあげたら、「イルスはいらないんですか?」とおっしゃる。
俺「イルス?」 大学生「イルス」 俺「・・・イルス?」 大学生「イルスw」 俺「・・・・・(!)エルス?」 大学生「エルス!?」
学校で他の言語を教授が教えるときに「イルス」って言ってるんだろうか。
それより、もっと読めないのが cdr。「くだー」って読んでるけど、cdar とどうやって区別しろと。