全5515文字
PR

関数が値になってしまうラムダの魔法

 どんどんいってみよう。次は関数の定義だ。

 Schemeでは関数の定義にもdefineを使う。与えられた引数に10を足す関数「add-ten」を定義してみよう。

(define (add-ten x)
  (+ x 10))

(add-ten 5)

 最初の2行が関数の定義で、最後に関数に5を渡して実行している。結果はもちろん「15」だ。関数定義では、defineの後の最初のかっこの中に関数名と引数を記述し、その後に関数の処理を書く。

 関数定義の途中で改行を入れているが、改行せずに1行で書いてもかまわない。かっこの対応さえ合っていれば自由に改行を入れられるので、見やすい位置で改行すればいい。

 ここから少し難しい話をしよう。先ほどの関数の定義は次のように書くこともできる。

(define add-ten
  (lambda (x) (+ x 10)))

 lambdaは「ラムダ」と読む。名前のない関数、いわゆる「無名関数」を記述するための記法だ。lambdaの直後に引数のリストを書き、その後に関数の処理を書く。無名関数は文字通り名前を持たない関数であり、「処理そのもの」を指す。

 ここではadd-tenという変数に無名関数を定義している。つまり、ただの変数定義にすぎない。これでadd-tenという変数が関数として機能するようになる。

 このあたりの感覚は、JavaScriptを知っている読者ならおなじみかもしれない。それは当然である。JavaScriptはSchemeの影響を強く受けて開発された言語だからだ。JavaScriptではlambdaの代わりに「function」というキーワードを使う。

 先ほどのlambdaを使わない関数定義の書き方は、実はこのlambdaを使う関数定義の「糖衣構文(シンタックスシュガー)」である。糖衣構文は、分かりにくい書き方のものを分かりやすく書けるようにする構文を指す。

 無名関数は関数の処理そのものなので、次のようにして値を適用することもできる。

((lambda (x) (+ x 10))
  5)

 一番外側のリストの第1要素は「(lambda(x)(+ x 10))」という無名関数である。そこに5という値を渡して実行するコードになる。したがって実行結果は15だ。