現在の変数環境に 《変数》 を追加する. 《式》 を評価して得た値を 《変数》 の値とし, 《変数》 を返す. トップ・レベルであれば大域変数として追加し, そうでなければ局所変数として追加する. define式は《変数》 を値とする.
define式は,このマニュアル中で 《本体》 と記した場所の 頭の部分に続けて置くことができる. つまり 《本体》 は,次の形を取る.
《 define式》《 define式》
《式》《式》
例:
> (define x 1)
x
> x
1
> (let () (define x 10) (+ x 20))
30
> x
1
define式が 《本体》 のはじめと トップ・レベルおよびトップ・レベルの begin式中以外で 使われた場合の動作は保証しない. 関数を定義するには, defineと lambdaを用いて
(define《関数名》
(lambda (《λリスト》)《本体》))
とする. またその簡略形として
(define (《関数名》《λリスト》)《本体》)
と書いてもよい.なお,
(define《関数名》(lambda《変数》《本体》))
は,
(define (《関数名》.《変数》)《本体》)
と略してよい.
例:
> (define (square x) (* x x))
square
> (square 3)
9
(let [《変数》]((《変数》《式》)(《変数》《式》))《本体》) 【特殊フォーム】
現在の変数環境に 《変数》 《変数》 を 局所変数として追加し, その外の環境のもとで各 《式》 を評価して対応する局所変数の値とする. その後に, 《本体》 を実行する. つまり,《本体》 の各フォームを順に実行し, 最後のフォームの値を let式の値とする. もし 《本体》 にフォームが1つもなければ let式の値は () である.
例:
(let ((x 2) (y 3))
(* x y))
6
《変数》 がある場合, 《変数》 を 《本体》 中の局所変数として追加し, 本体が 《本体》 で 仮引数が 《変数》 《変数》 である 関数を値とする. この特別な形(named letと呼ぶ)は繰り返しを行う場合に有用である.
例:
(let loop ((numbers '(3 -2 1 6 -5))
(nonneg '())
(neg '()))
(cond ((null? numbers) (list nonneg neg))
((negative? (car numbers))
(loop (cdr numbers)
nonneg
(cons (car numbers) neg)))
(else
(loop (cdr numbers)
(cons (car numbers) nonneg)
neg))))
((6 1 3) (-5 -2))
(let* ((《変数》《式》)(《変数》《式》))《本体》) 【特殊フォーム】
現在の変数環境に各 《変数》 を局所変数として順次追加してゆき, その環境のもとで各 《式》 を評価して対応する局所変数の値とする. つまり, 《本体》 の各フォームを順に実行し, 最後のフォームの値を let*式の値とする. もし 《本体》 にフォームが1つもなければ let*式の値は ()である.
例:
(let* ((x 1)
(y (+ x 1)))
y)
2
(letrec ((《変数》《式》)(《変数》《式》))《本体》) 【特殊フォーム】
現在の変数環境に各 《変数》 を局所変数として追加し, その環境のもとで各 《式》 を評価して対応する局所変数の値とする. その後に, 《本体》 を実行する. つまり,《本体》 の各フォームを順に実行し, 最後のフォームの値を letrec式の値とする. もし《本体》 にフォームが1つもなければ, letrec式の値は ()である.
各 《式》 の評価中は 《変数》 《変数》 の値は不定である. したがって, 《式》 がこれらの変数の値に依存してはならない. また,各 《式》 の評価中に 《変数》 《変数》 の値を 変更してはならない. letrec式は通常は再帰的な局所関数を定義するものであり, 以上の制限は全く支障とならない.
例:
(letrec ((even?
(lambda (x)
(if (zero? x)
#t
(odd? (- x 1)))))
(odd?
(lambda (x)
(if (zero? x)
#f
(even? (- x 1))))))
(even? 80))
#t