caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Brian Hurt <bhurt@janestcapital.com>
To: Jon Harrop <jon@ffconsultancy.com>
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Help me find this pdf
Date: Fri, 19 Oct 2007 09:00:38 -0400	[thread overview]
Message-ID: <4718AA76.3010103@janestcapital.com> (raw)
In-Reply-To: <200710181818.31430.jon@ffconsultancy.com>

[-- Attachment #1: Type: text/plain, Size: 2780 bytes --]

Jon Harrop wrote:

>On Thursday 18 October 2007 15:22:32 Brian Hurt wrote:
>  
>
>>You have to explicitly force the lazy value first-
>>    
>>
>
>If you force all lazy values before the pattern match then you are doing eager 
>evaluation, not lazy. Moreover, you must also generate an auxiliary data 
>structure to store the forced values in order to pattern match over them.
>
>  
>
You don't need to force all of them, you just need to force *one* (at 
least).

As an example, you might define a lazy list like:
type 'a node_t =
    | Empty
    | Cons of 'a * 'a lazylist
and 'a lazylist = 'a node_t Lazy.t;;

To see if the list is not empty, you have to first the first (but only 
the first!) element:

let is_empty zlst =
    match Lazy.force zlst with
    | Empty -> true
    | Cons _ -> false
;;

Etc.  Notice how the tail of the lazy list isn't forced in this 
example.  It works just fine on an infinite list.

Now, in a pattern with multiple lazy values, you need to be carefull not 
to over-force the result.

>>(I forget what it's called at the moment), but baring that... 
>>    
>>
>
>You can't ignore that: its the whole point! :-)
>
>Consider a function that concatenates adjacent "Some _" values in a list:
>
># let rec f = function
>    | [] -> []
>    | Some x :: Some y :: t -> f(Some(x @ y) :: t)
>    | h :: t -> h :: f t;;
>val f : 'a list option list -> 'a list option list = <fun>
># f [Some [1]; Some [2;3]; None; Some [4;5]];;
>- : int list option list = [Some [1; 2; 3]; None; Some [4; 5]]
>
>Thanks to pattern matching, this solution is almost as beautiful as my wife.
>
>An equivalent with lazy lists might be:
>
># type 'a llist = Nil | Cons of 'a * 'a llist lazy_t;;
>
>  
>
Bad definition of a lazy list- the first element always has to be 
forced.  Using my definition from above:

let rec f zlst = lazy (
    match Lazy.force zlst with
    | Empty -> Empty
    | Cons (None, xs) -> Cons (None, f xs)
    | Cons (Some x, xs) as t ->
       match Lazy.force xs with
          | Empty -> t
          | Cons(None, ys) -> Cons(Some x, lazy (Cons(None, f ys)))
          | Cons(Some y, ys) -> Cons (Some (x @ y), f ys)
);;

Not quite as pretty, I'll admit.  But it works.  And (modulo laziness 
around the options and appending) is the same as what Haskell would do.  
And note that the first two elements of the arguments are not forced 
until the first element of the result is forced- and I don't see how to 
avoid this.

The only thing missing is some syntactic sugar to make the above pattern 
matching nicer- computationally, the same values will need to be 
forced.  If you're arguing in favor of the syntactic sugar, I'm 
sympathetic.  If you're arguing that the compiler could somehow avoid 
forcing the same values, I don't see how.

Brian


[-- Attachment #2: Type: text/html, Size: 3547 bytes --]

  parent reply	other threads:[~2007-10-19 13:00 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-18  9:52 Tom
2007-10-18 10:33 ` [Caml-list] " skaller
2007-10-18 11:01   ` Andreas Rossberg
2007-10-18 12:25 ` Jon Harrop
2007-10-18 12:40   ` Arnaud Spiwack
2007-10-18 13:17     ` Jon Harrop
2007-10-18 15:15       ` Till Varoquaux
2007-10-18 12:46   ` Jacques Garrigue
2007-10-18 13:57     ` Jon Harrop
2007-10-18 14:22       ` Brian Hurt
2007-10-18 14:52         ` Robert Fischer
2007-10-18 15:04           ` Eric Cooper
2007-10-18 17:18         ` Jon Harrop
2007-10-19  1:16           ` skaller
2007-10-19  5:09           ` Bárður Árantsson
2007-10-19  5:23             ` [Caml-list] " Erik de Castro Lopo
2007-10-19  5:46               ` Bárður Árantsson
2007-10-19 12:25               ` [Caml-list] " Christophe Raffalli
2007-10-19 12:47                 ` Luc Maranget
2007-10-20 14:26                   ` Christophe Raffalli
2007-10-19 14:48                 ` Robert Fischer
2007-10-19 21:43                   ` Andreas Rossberg
2007-10-19 21:51                     ` Robert Fischer
2007-10-20 13:10                       ` Andreas Rossberg
2007-10-19 23:10                     ` Jon Harrop
2007-10-20  1:13                       ` skaller
2007-10-20  6:36                         ` Tom
2007-10-21 11:17                           ` skaller
2007-10-19  8:55             ` Zheng Li
2007-10-19 22:27             ` [Caml-list] " Jon Harrop
2007-10-19 13:00           ` Brian Hurt [this message]
2007-10-19 13:49             ` [Caml-list] " Loup Vaillant
2007-10-19 14:41               ` Zheng Li
2007-10-19 23:09             ` [Caml-list] " Jon Harrop
2007-10-18 20:07   ` Tom
2007-10-19  0:59     ` skaller
2007-10-18 20:48 ` Lauri Alanko

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=4718AA76.3010103@janestcapital.com \
    --to=bhurt@janestcapital.com \
    --cc=caml-list@yquem.inria.fr \
    --cc=jon@ffconsultancy.com \
    /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;
as well as URLs for NNTP newsgroup(s).