|
|
(let ((x 1) (y (+ 2 2))) (* (+ x y) v))は,x は 1,y は (+ 2 2) の値(つまり 4) であると宣言した下で,式 (* (+ x y) v) を評価する,という意味である.
(let ((<識別子1> <式1>) | ||
⋮ | ||
(<識別子n> <式n>)) | ||
<本体式>) |
(let ((x 2) (y 3)) (let ((x (+ x y))) (* x y)))において,最初の x の宣言の有効範囲は,内側の let 式全体で あるが,内側にも x が宣言されているので,(* x y) 中の x は内側の宣言に束縛される.また (+ x y) の x は外側 の宣言に束縛されるので,この式の値は,15 である.実は,最初の例でも x の宣言は,大域環境に束縛されている x のシャドウイングが 発生しているといえる.
|
<式> | ::= | … |
| | (let (<束縛リスト>) <本体>) | |
<束縛リスト> | ::= | (<識別子1> <式1>) … (<識別子n> <式n>) |
syntax.ml:
type exp = ... | Let of (id * exp) list * exp
parser.mly:
%token LET Exp : ... | LPAREN LET LPAREN Bindings RPAREN Exp RPAREN { Let ($4, $6) } ... Bindings: /* empty */ { [] } | LPAREN ID Exp RPAREN Bindings { ($2, $3) :: $5 }
lexer.mll:
let reservedWords = [ ... ("let", Parser.LET); ]
core.ml:
let rec eval_exp env = function ... | Let (bs, e) -> let ids, args = List.split bs in let arg_vals = eval_rands env args in eval_exp (extend_env ids arg_vals env) e
Figure 9: 局所定義
<式> | ::= | … |
| | (letseq (<束縛リスト>) <本体>) | |
<束縛リスト> | ::= | (<識別子1> <式1>) … (<識別子n> <式n>) |
(letseq ((x 4) (y (+ x 3))) (* x y))の実行結果は 52 ではなく 28 である.letseq 式をイン タプリタに実装・テストせよ.