HOME | 5. 分岐 | もうひとつの Scheme 入門 | 7. 繰り返し | 書き込む |
(let binds body )binds の部分で、変数を宣言し、初期値を設定します。 body には任意の個数の式を書くことができます。
[binds] → ((p1 v1) (p2 v2) ...)変数 p1, p2 ... を宣言し、初期値をそれぞれ v1, v2 ... にセットします。 変数の有効範囲は body の部分です。
例 1:局所変数 i, j を宣言し、初期値をそれぞれ 1, 2 にセットし、それらを足し合わせる。
> (let ((i 1) (j 2))
(+ i j))
3
let 式は入れ子にすることができます。 例 2:局所変数 i, j を宣言し、初期値をそれぞれ 1, i+2 にセットし、それらを掛け合わせる。
> (let ((i 1))
(let ((j (+ i 2)))
(* i j)))
3
変数の有効範囲は定義の body だけですから、次のように書くとエラーになります。
これは、j の初期化式内に現れる i が定義されていないからです。
> (let ((i 1) (j (+ i 2)))
(* i j))
reference to undefined identifier: i
=== context ===
D:\WBIN\MzScheme\collects\scheme\private\misc.ss:68:7
let* を使えば、直前に定義した変数を参照することができます。
> (let* ((i 1) (j (+ i 2)))
(* i j))
3
例 3: 二次方程式の解を求める関数 quadric-equation。
係数 a, b, c (a x2 + b x + c = 0) を引数にとり、解のリストを(実数の範囲)で返します。
let を使ってこまめに局所変数を定義すると無駄な計算をせずに解が求まります。
;;;変数 d,e,f の有効範囲はそれぞれの背景色の範囲です。 (define (quadric-equation a b c) (if (zero? a) 'error ; 1 (let ((d (- (* b b) (* 4 a c)))) ; 2(if (negative? d) '() ; 3 (let ((e (/ b a -2))) ; 4(if (zero? d) (list e) (let ((f (/ (sqrt d) a 2))) ; 5(list (+ e f) (- e f)))))))))
> (quadric-equation 3 5 2) ; solution of 3x2+5x+2=0
(-2/3 -1)
実は let は lambda 式を使って次のように表されます。
(let ((p1 v1) (p2 v2) ...) exp1 exp2 ...) ⇒ ((lambda (p1 p2 ...) exp1 exp2 ...) v1 v2)lambda 式は関数なので、変数の有効範囲を制限する働きがあります。
次回は繰り返しについて説明します。繰り返しができればとりあえず、普通にプログラムが書けるようになります。
(define (throw v a) (let ((r (/ (* 4 a (atan 1.0)) 180))) (/ (* 2 v v (cos r) (sin r)) 9.8)))
HOME | 5. 分岐 | もうひとつの Scheme 入門 | 7. 繰り返し | 書き込む |