Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Jon Harrop <jon@ffconsultancy.com>
To: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Generators/iterators and lazy evaluation?
Date: Thu, 5 Apr 2007 00:53:41 +0100	[thread overview]
Message-ID: <200704050053.41426.jon@ffconsultancy.com> (raw)
In-Reply-To: <CCF54B6E-E0E6-48B3-93A2-458FFF5FD769@rice.edu>

On Wednesday 04 April 2007 17:33, Raj B wrote:
> A generator in Python can be thought of as an arbitrarily generated
> 'lazy list'. As an example
> the following is a generator capable of generating powers of 2 upto a
> max value.
>
> def pow2(max):
>     start = 0
>     while (start .lt. max):
>        yield 2^start
>        start += 1
>
> The 'yield' statement is the point where the function returns the
> next value and suspends itself until the next time it is 'forced'. At
> that time it resumes execution where it left off.
>
> OCaml makes this particularly hard to implement this due to lack of
> 'control flow' features

Might I suggest deferring judgement until you have seen some OCaml solutions.

$ ocaml -rectypes camlp4o.cma
        Objective Caml version 3.10.0+beta

        Camlp4 Parsing version 3.10.0+beta

#

Use a lazy list sum type:

# type 'a llist = Nil | Cons of 'a * 'a llist lazy_t;;
type 'a llist = Nil | Cons of 'a * 'a llist lazy_t

# let rec pow2 ?(i=1) n =
    if n>0 then Cons(i, lazy(pow2 ~i:(2*i) (n-1))) else Nil;;
val pow2 : ?i:int -> int -> int llist = <fun>

For example:

# let rec list_of = function
    | Nil -> []
    | Cons(h, t) -> h :: list_of(Lazy.force t);;
val list_of : 'a llist -> 'a list = <fun>

# list_of(pow2 10);;
- : int list = [1; 2; 4; 8; 16; 32; 64; 128; 256; 512]

Use an inferred lazy list type (polymorphic variant):

# let rec pow2 ?(i=1) n =
    if n>0 then `Cons(i, lazy(pow2 ~i:(2*i) (n-1))) else `Nil;;
val pow2 : ?i:int -> int -> ([> `Cons of int * 'a lazy_t | `Nil ] as 'a) =
  <fun>

Return a lazy tail (using -rectypes):

# let rec pow2 ?(i=1) n =
    if n>0 then Some(i, lazy(pow2 ~i:(2*i) (n-1))) else None;;
val pow2 : ?i:int -> int -> ((int * 'a lazy_t) option as 'a) = <fun>

Return a functional tail (using -rectypes):

# let rec pow2 ?(i=1) j n () =
    if n>0 then Some(i, pow2 ~i:(2*i) (n-1)) else None;;
val pow2 : ?i:int -> int -> (int -> unit -> (int * 'a) option as 'a) = <fun>

Return a lazy stream (using camlp4 stream parsing syntax extension):

# let rec pow2 ?(i=1) n =
    if i<n then [<'i; pow2 ~i:(2*i) (n-1)>] else [<>];;
val pow2 : ?i:int -> int -> int Stream.t = <fun>

The moral is: don't try to write idiomatic Python in OCaml.

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
OCaml for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists


  parent reply	other threads:[~2007-04-04 23:58 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-04 16:33 Raj B
2007-04-04 20:10 ` [Caml-list] " Mathias Kende
2007-04-04 20:46 ` Alain Frisch
2007-04-04 21:16   ` Erik de Castro Lopo
2007-04-04 21:37     ` Erik de Castro Lopo
2007-04-04 22:55     ` Bill Wood
2007-04-05  2:49     ` skaller
2007-04-05 16:41     ` Richard Jones
2007-04-04 23:53 ` Jon Harrop [this message]
2007-04-05  3:13   ` Erik de Castro Lopo
2007-04-05  5:58   ` Alain Frisch
2007-04-05 20:35     ` Jon Harrop

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200704050053.41426.jon@ffconsultancy.com \
    --to=jon@ffconsultancy.com \
    --cc=caml-list@yquem.inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox