osiire’s blog

ふしぎなそふとやさん

SRFI-45

concurrent cellのFRPの実装においてfilterがメモリリークする問題があって、どうするべと悩んでいたのだけれど、まさに解決策があった。SRFI-45(http://srfi.schemers.org/srfi-45/)とその日本語訳(http://www.katch.ne.jp/~leque/translations/srfi-45/srfi-45j.html)。紹介してくれた&日本語訳を公開してくれているleque氏に感謝感激雨あられ。なにはともあれ、OCamlで同等のプログラムにしてみた。テストも何もしていないので怪しいけど、たぶんこんな感じ。OCamlにはdefine-syntaxなんてないので、そこはlazyにしてある。

let (!$) = Lazy.force
type 'a exp = 'a Lazy.t
and 'a t = ILazy of 'a promise exp | Eager of 'a exp
and 'a promise = { mutable v : 'a t }

let ilazy exp = { v = ILazy exp }
let eager x = { v = Eager x }
let delay exp = ilazy (lazy (eager exp))
let rec force promise =
  match promise.v with
      Eager x -> !$x
    | ILazy (lazy p) ->
        let _ =
          match promise.v with
              ILazy _  -> promise.v <- p.v
            | _ ->  ()
        in
        force promise