2010/03/24

(begin a b ...)と(let () a b ...)は同じじゃない

コメントでご指摘頂いてました。ここに改めてメモとして残しておきます。
Scheme の begin には面白い特徴があります。
新しいスコープを作らないのです。
なるほど。知りませんでした。(「RnRS読め」ですよね)
例えば ↓ こんなコードでエラーが起こりません。
(begin (define a 1))
(display a)
ホンマや。
Scheme
1
2
(begin (define x 100))
(display x)



Output:
1
100

a はトップレベルで定義されたことになります。
記事中のコードは begin と let のどちらを使っても問題ないと思いますが、同等と考えていると不意につまづくこともあるかもしれません。
begin のこの性質はマクロを書くときに必要になることがあります。
まんまと(let () a b ...)で(begin a b ...)と同じことできるなら、begin要らなくね?などと思っちゃってました。勉強になりました。ありがとうございました!


追記

(let ((x 1))
  (define x 2)
  x)
2

(let ((x 1))
  (let ()
    (define x 2))
  x)
1

(let ((x 1))
  (begin
    (define x 2))
  x)
2


0 件のコメント:

コメントを投稿