2016年9月15日

実践common lisp第5章

関数ですね
defunですね
defunってなんなのかってことなんですけど、関数なんですよ、繰り返しますけど関数なんですよ
関数を定義する関数ってことなんですよね
でも本当はdefunはマクロなんですけどね
マクロについてまだ登場してないんで説明しにくいんですけど、関数を定義することも言語の機能の一部なんですよ
これがLispがすごいところでして、とにかく関数ばっかり
他の言語と圧倒的に違うところですね
Lispでは予約語が圧倒的にすくなくてですね、前章であったとおりなんでもかんでもあの形式ですまそうとしてるんで、こういうことになっちゃってるんですよ
他の言語だと関数定義はこれこれこういう風な文法で記述する、なになにはこの書式でやるっていう方法を取ってまして、それが要は高級言語ってことなんですけど、Lispはそのあたりは非常に低級な言語なんですよ
なんでもかんでも前章でのとおり記述できるようにしていますんで
んで、なんでこんなことになっているかってことなんですけど、今後登場するであろうことを先に言っておくと、関数定義すら自動生成しようって魂胆があるんですよね
早口言葉みたいですけど、関数定義をする関数とか作ることが可能になるんですよ
だからこんなことになっています
パラメータについてはここに書いてある通りです、そのままです
高階関数、匿名関数についてもこのままです

ついでなんで書いておきますけど、Lispと言うかCommon Lispは関数型じゃないっていう記述を見かけます
なんとなくLispは関数型って言う印象が強いっぽいのだけど、Lispでは関数型って言うのはSchemeのことが多くて、Common Lispは関数型もできるって言う立ち位置です
Schemeはあんまり詳しくない(SICPで扱ったことがあるだけ)から例題とか正確に記述できないのだけど、Common Lispは高階関数はfuncallでイチイチ実行しないといけないんだよね
例えばある関数に匿名関数を渡したとして、その関数を呼び出すためには、Schemeならそのまま直接引数を関数として扱えるのだけど、Common Lispの場合はfuncall、applyで呼び出さないといけない
これは前に説明した通り関数定義テーブルと変数定義テーブルが別になっているからなんだよね

defunなんですけど、気にしなければどうでもいいことなのかもしれませんけどね、マクロなんで関数を定義するソースコードを生成してるんですよね
気になる人は以下を実行するといいと思います
(macroexpand-1 '(defun f(a b) (+ a b)))
これを実行すると(defun f(a b) (+ a b))からどういうソースコードが生成されるかわかりますんで
で、Common Lispにおいて関数を定義しようと思うと要はこういうソースコードを描かないといけないんですよ
でもdefunって言うマクロっていうものが用意されてて、そのマクロを使うと
(defun f(a b) (+ a b))
でfが定義できるっていうことですよね