SICPを読む(24) 1.2.3(3) 局所変数let
やっと「変数」という物が登場しました。
letの書式は
(let binds body)
もうちょっと詳しく書くと
(let ((var exp) (var exp) ...) body)
letの中に囲まれた文が、変数の有効範囲になる。
lambdaのシンタックスシュガーなので、非常にわかりづらい。
では、コーディング。
3つの変数定義を見比べてみる。
define法
; define法 (define (f x y) (define (f-helpler a b) (+ (* x (square a)) (* y b) (* a b))) (f-helpler (+ 1 (* x y)) (- 1 y)))
慣れた方法。
lambda法
; lambda法 (define (f x y) ((lambda (a b) (+ (* x (square a)) (* y b) (* a b))) (+ 1 (* x y)) (- 1 y)))
((lambda params body) args)の形。
let法
; let法 (define (f x y) (let ((a (+ 1 (* x y))) (b (- 1 y))) (+ (* x (square a)) (* y b) (* a b))))
(let binds body)の形。
こう見ると、letが一番スッキリ見える。
インデントを揃えた方が見易いかな。
(define (f x y) (let ((a (+ 1 (* x y))) (b (- 1 y))) (+ (* x (square a)) (* y b) (* a b))))
う〜ん。結局、
(define (f x y) (define a (+ 1 (* x y))) (define b (- 1 y)) (+ (* x (square a)) (* y b) (* a b)))
defineでいいんでない?(汗
慣れるまで時間がかかりそう・・・。
問題1.34
MzSchemeだとエラーメッセージが不親切なので、gaucheを使った。
gosh> (use slib)(require 'trace) #<undef> #t gosh> (define (f g) (g 2)) f gosh> (trace f) #<closure (debug:trace-procedure debug:trace-procedure)> gosh> (f f) CALL f #[proc] CALL f 2 *** ERROR: invalid application: (2 2)
(f f)→(f 2)→(2 2)
と評価されて、2でエラー。