まず、numb-lambdaを起動します。
$ numb-lambda
>
行頭の>はプロンプトです。その後ろにカーソルが点滅しています。これで、numb-lambdaインタープリタのREPL(Read Evaluate Print Loop)が開始されます。
ここで、次のように入力してください。
> "hello, world"
"hello, world"
>
"hello, world"がエコーされた筈です。ひじょうに簡単ですが詐欺のようですね。それにダブルクォートで囲まれていて、一般的なhello, worldプログラムとは異ります。numb-lambdaは、
"hello, world"
という文字列リテラルを読んで(Read)、評価し(Evaluate)、印字して(Print)、次のプロンプトを表示しました。(Loop)
一般的なLISPはリテラルを評価するとリテラルそのものが得られます。
もう少しまともに書いてみましょう。
> (display "hello, world")
hello, world>
ダブルクォートが取れて少しマトモになりました。しかし、改行がされていないため、次のプロンプトがhello, worldの直後に表示されています。
> (begin
(display "hello, world")
(newline))
hello, world
>
はい、今度は期待どおりになったと思います。
begin
を使うと複数の文を逐次実行させることができます。このように、LISPでは通常、括弧内の最初の要素がオペレータとなり処理を行います。display
とnewline
は、共に印字とい副作用を期待されたオペレータです。今度は関数を使ってみましょう。
> ((lambda ()
(display "hello, world")
(newline)))
hello, world
>
難しいですか?ここでは、
(lambda () (display "hello, world")(newline))
が関数です。それが外側の括弧の最初の要素であるのでオペレータとして動作します。ですから、この行は関数を呼び出しているのです。lambda
の括弧の後ろは逐次実行されます。(begin
は必要ありません)あれ、でも、ちょっと待ってください。これでは関数が再利用できないではありませんか。そのとおり。再利用するには関数を変数にバインドする必要があります。次のようにします。
> (define say-hello
(lambda ()
(display "hello, world")
(newline)))
>
これで、関数がsay-helloという変数にバインドされました。これを呼び出すには次のようにします。
> (say-hello)
hello, world
>
関数に引数を与えることができるよう、少し変更します。
> (define say-hello-revised
(lambda (s)
(display "hello, ")
(display s)
(newline)))
> (say-hello-revised "namb")
hello, namb
>
"namb"
を様々に変更して再実行してみてください。最後に関数を定義するために構文糖(シンタックスシュガー)が利用できることを示して終りとします。
> (define (say-hello-revised^2 s)
(display "hello, ")
(display s)
(newline))
> (say-hello-revised^2 "foo bar")
hello, foo bar
>
今回は以上です。いかがですが、難しくはなかったでしょう。