現在の変数環境に 《変数》 を追加する. 《式》 を評価して得た値を 《変数》 の値とし, 《変数》 を返す. トップ・レベルであれば大域変数として追加し, そうでなければ局所変数として追加する. 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