SICP 1.2.1 には、次のような有理数を作成する関数があります。
(define (make-rat n d)
(let ((g (gcd n d)))
(cons (/ n g) (/ d g))))
GCD を 2 回呼び出すことなく、let の代わりにラムダを使用して同じことを実装する方法に興味があります。私はそれを自分で理解できませんでした。
SICP セクション 1.3.2を見ると、
(let ((<var1> <exp1>)
(<var2> <exp2>)
...
(<varn> <expn>))
<body>)
と同等です
((lambda (<var1> ...<varn>)
<body>)
<exp1>
...
<expn>)
だからあなたの手順、
(define (make-rat n d)
(let ((g (gcd n d)))
(cons (/ n g) (/ d g))))
と同等でなければなりません
(define (make-rat n d)
((lambda (g)
(cons (/ n g) (/ d g)))
(gcd n d)))
これら2つのことは同じです:
((lambda (p1 p2...) body) v1 v2...)
と
(let ((p1 v1) (p2 v2)...) body)
let をラムダで使用する関数をどのように書き直すことができるかを理解できるように、2 つの単純なケースを調べてみましょう。
最初のケースでは、let が 1 つあります。この関数は非常に単純で、与えられた入力に 10 を加算して返します。
(define (test x)
(let ((b 10))
(+ x b)))
これをラムダを使った式に変えてみましょう:
(define (test-lambda x)
((lambda (b)
(+ x b))
10))
ご覧のとおり、test-lambda は、値 10 で評価されるラムダ評価を返します。これをテストすると、次のように言えます。
(test-lambda 10)
これは 20 を返します。
let の場合、2 つの let ステートメントがあります。
(define (lets x)
(let ((a 10)
(b 20))
(+ x a b)))
これをラムダで次のように書くことができます。
(define (lets-lambda x)
((lambda (a)
((lambda (b)
(+ x a b))
20))
10))
これで、各ラムダ式を評価して値を与え、最も内側のラムダ式が、各ラムダ式に割り当てられた変数名を使用して計算したいものを処理します。
これが明確であり、他の人がより明確に見えるようになることを願っています!
(define-syntax let-as-lambda
(syntax-rules ()
((_ (x value) body)
(let ((x value))
body))))
(printf "~s~n" (let-as-lambda (x 1) (+ x 1)))