caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Lazy evaluation in Caml Light
@ 1992-10-06 12:26 Xavier Leroy
  0 siblings, 0 replies; only message in thread
From: Xavier Leroy @ 1992-10-06 12:26 UTC (permalink / raw)
  To: caml-list; +Cc: rbrena

I've been asked questions about lazy evaluation in Caml Light several
times already, so I'd like to summarize.

- It is straightforward to implement delayed expressions, as with the
"delay" function in Scheme, using mutable data structures. I have
enclosed a sample implementation below. This solution is certainly not
elegant --- the user's code is cluttered by explicit "freeze" and
"unfreeze" operations --- but at least you can really understand
what's going on.

- As pointed out by Michel Mauny, streams do not provide a general
lazy evaluation mechanism: granted, they are lazily evaluated, but the
"discard after use" semantics for stream matching is generally not
what you want to implement e.g. potentially infinite data structures.

- I'm reluctant to integrate lazy evaluation in the Caml Light system,
not only because I'd like Caml Light to remain small and simple, but
also because there is no obvious, universally accepted way to
integrate lazy evaluation within a strict language. Also,
understanding the interaction between lazy evaluation and side-effects
is quite hard; the best way I know is to think in terms of the
underlying implementation in terms of mutable structures --- just as
in the first point above.

- Xavier Leroy

(* The poor man's lazy evaluation in CAML Light *)

(* Interface file: lazy.mli *)

type 'a suspension;;

value freeze : (unit -> 'a) -> 'a suspension
  and unfreeze : 'a suspension -> 'a;;

(* Implementation file: lazy.ml *)

type 'a suspension =
  { mutable state: 'a suspension_state }
and 'a suspension_state =
    Unevaluated of (unit -> 'a)
  | Evaluated of 'a
;;

let freeze expr =
  { state = Unevaluated expr }
;;

let unfreeze susp =
  match susp.state with
    Unevaluated f ->
      let val = f () in
        susp.state <- Evaluated val; val
  | Evaluated val ->
      val
;;

(* An example: lazy streams *)

type 'a stream =
  { head : 'a;
    tail : 'a stream suspension }
;;

(* Getting the Nth element of a stream *)

let rec nth_stream stream n =
  if n <= 0 then stream.head else nth_stream (unfreeze stream.tail) (n-1)
;;

(* Mapping on a stream *)

let rec map_stream f stream =
  { head = f stream.head;
    tail = freeze(fun () -> map_stream f (unfreeze stream.tail)) }
;;

(* The stream of all positive integers *)

let rec positive_integers =
  { head = 0;
    tail = freeze(fun () -> map_stream (fun x -> x+1) positive_integers) }
;;

nth_stream positive_integers 10;;
positive_integers;;





^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~1992-10-06 12:52 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1992-10-06 12:26 Lazy evaluation in Caml Light Xavier Leroy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).