(* A simple illustration of let-insertion (traditional) *) (* See gengenlet.ml for a better, more convenient version *) (* We will be using delimited control. So we load it up and set up *) (* #directory "/home/oleg/Cache/ncaml4/caml-shift/";; #directory "/usr/local/src/ncaml4/caml-shift/";; #load "delimcc.cma";; *) open Delimcc;; open Runcode;; (* To run the code *) (* If we are going to use delimited control, we need to tell MetaOCaml, by adjusting its stackmark facility -- provide the implementation of stackmarks that works with delimcc. *) Trx.set_with_stack_mark {Trx.stackmark_region_fn = fun body -> let p = new_prompt () in push_prompt p (fun () -> body (fun () -> is_prompt_set p))} ;; (* genlet tells to let-bind the somewhere; with_prompt marks the place of that The communicate via a prompt. *) let genlet : 'w code prompt -> 'a code -> 'a code = fun p cde -> shift p (fun k -> ..)>.) let with_prompt : ('w prompt -> 'w) -> 'w = fun thunk -> let p = new_prompt () in push_prompt p (fun () -> thunk p) let t1 = with_prompt (fun p -> .<1 + .~(genlet p .<2+3>.)>.) (* val t1 : int code = .. *) let t2 = with_prompt (fun p -> . x + .~(genlet p .<2+3>.)>.) (* val t2 : (int -> int) code = . x_4 + t_5>. *) (* Attempting to move the open code past the binder for its free variable. Prior to BER N100, that attempt succeeded. Not any more. *) let t3 = with_prompt (fun p -> . x + .~(genlet p ..)>.) (* propagating exc Exception: Failure "Scope extrusion detected at Characters 89-117: for code built at Characters 62-65: . x + .~(genlet p ..)>.);; ^^^ for the identifier x_6 bound at Characters 39-40: . x + .~(genlet p ..)>.);; ^". *)