2017年07月15日

numb-lambdaの式とシンボル(1)

前回は、numb-lambdaを使って hello, world プログラムを作成しました。その際、筆者はという語を使いましたが、これは厳密に言うと正しくはありません。numb-lambdaは、LISPの方言ですので、前回、文と言ったところはと言い換えた方が正しいです。LISPのプログラムは式が集まって出来ています。ここで式の一般的な形を見てみましょう。

(<式> <式> <式> <式>... )

このように括弧の中に式がいくつも並んでいます。これをリストと呼びます。LISPでは、このリストが普通の言語でいうにもデータにもなります。今回は文となる式について述べます。

REPLでは、リストを読んだとき、それを式として把え評価し、結果を印字します。リストを式と把え評価するとは、どういうことでしょうか。

式となるリストを評価するとき、まず、リストの最初の式(開き括弧の、すぐ右の式)を評価します。この式の評価結果はオペレータになっていなくてはなりません。このオペレータには2種類あります。関数またはスペシャルフォームです。このオペレータが関数かスペシャルフォームかによって式の評価の仕方が変わってきます。
最も簡単な式としては、シンボルリテラル(定数)があります。まずは、シンボルを見てみましょう。それでは、numb-lambdaを起動してください。

$ numb-lambda
>

ここで、+-をそれぞれ入力してみてください。+-も、それぞれシンボルです。

> +
<procedure>
> -
<procedure>
>

<procedure>と返って来たと思います。このように、シンボルを評価して、<procedure>と返って来たときは、そのシンボルに関数がバインドされています。LISPでバインドと言ったときには、他の言語でいう代入に相当します。次に前回、関数を作るときに用いた、lambdaとdefineをそれぞれ評価してみてください。

> lambda
<special form>
> define
<special form>

このように、lambdaもdefineも<special form>と評価されたと思います。これは、シンボルにスペシャルフォームバインドされていることを示しています。

ところで、先程からシンボルと読んでいるものは、他の言語でいう変数に似ています。まさに、前回はこれらを変数と言っていました。LISPではシンボルと呼ぶのが正しいです。

関数とスペシャルフォームの違いは何でしょうか。リストの最初の式が、関数のとき、リストの残りの式は左から右に順に全て評価をされます。この後、実際の関数が適用されて評価を完了します。一方、スペシャルフォームでは、リストの残りの式は評価される場合もあるし、そうでない場合もあります。また、評価される順番も当該スペシャルフォームに応じて任意です。

それでは、関数の方を評価して、今回は終りとします。

> (+ (- 9 5) 2)
6
>

このとき、何が起きているでしょうか。先ずリストの最初の要素である+というシンボルが評価されます。これは関数でした。リストの要素の先頭が関数のときは、先にリストの残りの要素が全て左から順に評価されるのでした。ですから、次の要素となる(- 9 5)が評価されます。
この、(- 9 5)も式(リスト)になっています。ですから、このリストの最初の要素(シンボル)-が評価されます。-は関数でしたから、続いて残りの要素が左から順に全て評価されます。ここでは、9、5の順に評価されます。2つとも定数ですので、評価するとその値そのものとなります。ここで、シンボル-にバインドされた関数が適用されて、9-5の演算が行なわれ、4が評価結果となります。最も外側の括弧の2つめの式の評価結値は4です。リストの次の要素は2です。この評価値は定数ですから、2そのものとなります。これで、全ての要素が左から順に評価されて値が確定しました。ここで、シンボル+にバインドされた関数が適用されます。これにより、4+2の演算が行われ、評価値6が得られました。REPLはこの評価値を印字して次のプロンプトを表示しています。

今回は予定より、随分と長くなってしまいました。次回はスペシャルフォームについて述べる予定です。

* numb-lambdaの処理系が入っている prizo.jar が、いくつかのクォートを正しく処理できないことが判明しました。この処理系では、それなりに大きなシステムの一部として運用された実績があるのですが、いくつかのクォートについては利用していなかったようです。しかし、それらは、とても有用ですので、それらについてはデバッグして、近い将来、新しいバージョンのprizo.jarを公開する予定です。