JavaScriptでSICPを勉強する その3
「JavaScriptでSICPを勉強する その3」です。
1.3 高階手続きによる抽象 (p.31)
例えば
という計算がしたいときは関数を引数に取る関数sigmaを定義するとよいでしょう。
scheme
(define (sigma a b f) (if (> a b) 0 (sigma (f a) b sigma))) (define (f x) (* x x)) (define (g x) (* 2 x)) (sigma 1 3 f) ; => 14 (1 + 4 + 9) (sigma 1 3 g) ; => 12 (2 + 4 + 6)
function sigma(a, b, f) { if (a > b) return 0; else return sigma(a+1, b, f); } function f(x) { return x * x; } function g(x) { return 2 * x; } sigma(1, 3, f); // => 14 (1 + 4 + 9) sigma(1, 3, g); // => 12 (2 + 4 + 6)
このように関数を引数に取る関数のことを高階関数(higher-order function)といいます。高階関数は数学の世界では汎関数と呼ばれているようです。
1.3.2 lambdaを使う手続きの構築 (p.34)
schemeではlambdaは次のような書式で書きます。
(lambda (<引数の並び>) (<関数本体>))
これに対応するJavaScriptのコードは以下のようになります。
function (<引数の並び>) {<関数本体>}
lambdaを使って試しに数値を4増やして返す関数plus4というのを作ってみましょう。
(define plus4 (lambda (x) (+ x 4)))
var plus4 = function (x) {return x + 4;};
局所変数を創りだすletの使い方 (p.35)
また局所変数を使いたいときに便利なletというものがあります。書式は次のようになっています。
(let ((<変数名> <束縛する値>) (<変数名> <束縛する値>) ... (<変数名> <束縛する値>)) <本体>
束縛する変数は複数書くことができます。ちなみにletは次のシンタックスシュガー(構文糖)にすぎません。
((lambda (<変数1>...<変数n>) <本体>) <束縛する値1> ... <束縛する値n>)
例えば2点間の距離を返す関数をつくり、その中でletを使ってみましょう。
(define (dist x1 y1 x2 y2) (let ((x (- x1 x2)) (y (- y1 y2))) (sqrt (+ (* x x) (* y y))))) (dist 0 0 1 1) ; => 1.4142135623730951
今回は高階手続きによる抽象をやりました。次回はcar, cdr, consやlistのおなはしで「JavaScriptでSICPを勉強する その4」です。