Hatena::ブログ(Diary)

みずぴー日記 Twitter

2008-12-18(木)

Schemeのdefineってレキシカルスコープじゃないよね

| Schemeのdefineってレキシカルスコープじゃないよねを含むブックマーク

Schemeの場合

Schemeのdefineはset!と似た感じになるので、変数を2回defineすると最初の値が変わる。

(define x 1)
(define (f) x)
(define x 2)

(print (f)) ;; => 2

OCamlの場合

で、みんな大好きOCamlの場合は、二回letしても最初の値は変わらない。

let x = 1

let f _ = x

let x = 2

let _ =
  print_int (f ());; (* => 1 *)

で、何が問題なの?

ボクの作ってるScheme-abcOCaml風のdefineを採用してるんだけど、これがわりとABCと相性悪いからどうしようかなぁ、と最近迷ってたりする。

できればOCaml風のdefineは維持したいんだけど、どうしようかなぁ・・。

shiroshiro 2008/12/19 05:47 R6RSではそもそも同一モジュール内トップレベルでの再定義が許されなくなりました。なのでこの問題は消滅 (いいのか?)

もっともR6RSの範囲外である、REPLでの挙動とかコードを再読み込みした場合の意味については処理系依存です。OCamlのはletがネストしているとみなすわけですよね? R6RS準拠で拡張としてREPLをつけた場合に、各defineがあたかもネストしたletであるかのように振る舞わせても構わないと思います。

ところでOCamlセマンティクスでトップレベルdefineでの相互再帰はどうなるのでしょう? define時点で未定義の場合は特別扱い?

mzpmzp 2008/12/19 07:47 おお、ありがとうございます! R6RSが再定義を禁止してるなら、再定義禁止もありですねぇ・・。
ちなみに、OCamlでの相互再帰は専用の文法があります。
let rec f x = g x
and g x = f x

shiroshiro 2008/12/19 19:19 はい、専用の構文を用意しないとトップレベルの相互再帰が書きにくいのでは、というのがコメントの趣旨でした。

bgnoribgnori 2008/12/20 10:16 xrangeはスピードもさることながら、空間節約がうれしいのでは?
たとえば要素数10万個のリストをfor文をまわすためだけに作るのはちょっと・・・。

wittenwitten 2008/12/20 22:54 文字列だけではなくてcallable objectも与えられます。

トラックバック - http://d.hatena.ne.jp/mzp/20081218/lexical