caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Help me find this pdf
@ 2007-10-18  9:52 Tom
  2007-10-18 10:33 ` [Caml-list] " skaller
                   ` (2 more replies)
  0 siblings, 3 replies; 37+ messages in thread
From: Tom @ 2007-10-18  9:52 UTC (permalink / raw)
  To: Caml-list List

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

Not long ago I was searching the Internet on the topic "combining eager and
lazy evaluation", and have run over a paper which I obviously dismissed as
"not interesting enough", yet now I have realized that it could indeed be
useful, but am unable to find it.

I know it was talking about a useful primitive, I do not know how exactly it
was named, which checked whether values passed as arguments to functions
were lazy (blocks to be evaluated) or eager (already evaluated), and using
it some functions, e.g. map (this example was present in the paper) could be
implemented to be both eager and lazy at the same time, depending on the
arguments.

Does anyone recognize this description?

 - Tom

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

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18  9:52 Help me find this pdf Tom
@ 2007-10-18 10:33 ` skaller
  2007-10-18 11:01   ` Andreas Rossberg
  2007-10-18 12:25 ` Jon Harrop
  2007-10-18 20:48 ` Lauri Alanko
  2 siblings, 1 reply; 37+ messages in thread
From: skaller @ 2007-10-18 10:33 UTC (permalink / raw)
  To: Tom; +Cc: Caml-list List


On Thu, 2007-10-18 at 11:52 +0200, Tom wrote:
> Not long ago I was searching the Internet on the topic "combining
> eager and lazy evaluation", and have run over a paper which I
> obviously dismissed as "not interesting enough", yet now I have
> realized that it could indeed be useful, but am unable to find it. 
> 
> I know it was talking about a useful primitive, I do not know how
> exactly it was named, which checked whether values passed as arguments
> to functions were lazy (blocks to be evaluated) or eager (already
> evaluated), and using it some functions, e.g. map (this example was
> present in the paper) could be implemented to be both eager and lazy
> at the same time, depending on the arguments.
> 
> Does anyone recognize this description?

No, but Felix does it by default


-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18 10:33 ` [Caml-list] " skaller
@ 2007-10-18 11:01   ` Andreas Rossberg
  0 siblings, 0 replies; 37+ messages in thread
From: Andreas Rossberg @ 2007-10-18 11:01 UTC (permalink / raw)
  To: Tom; +Cc: Caml-list List

On Thu, 2007-10-18 at 11:52 +0200, Tom wrote:
>  Not long ago I was searching the Internet on the topic "combining
>  eager and lazy evaluation", and have run over a paper which I
>  obviously dismissed as "not interesting enough", yet now I have
>  realized that it could indeed be useful, but am unable to find it.
>
>  I know it was talking about a useful primitive, I do not know how
>  exactly it was named, which checked whether values passed as arguments
>  to functions were lazy (blocks to be evaluated) or eager (already
>  evaluated), and using it some functions, e.g. map (this example was
>  present in the paper) could be implemented to be both eager and lazy
>  at the same time, depending on the arguments.
>
>  Does anyone recognize this description?

I guess you mean this one:

  http://web.cecs.pdx.edu/~sheard/papers/ExplicitLazy.ps

The primitive you're alluding to is called "mimic" in it.

- Andreas


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18  9:52 Help me find this pdf Tom
  2007-10-18 10:33 ` [Caml-list] " skaller
@ 2007-10-18 12:25 ` Jon Harrop
  2007-10-18 12:40   ` Arnaud Spiwack
                     ` (2 more replies)
  2007-10-18 20:48 ` Lauri Alanko
  2 siblings, 3 replies; 37+ messages in thread
From: Jon Harrop @ 2007-10-18 12:25 UTC (permalink / raw)
  To: caml-list

On Thursday 18 October 2007 10:52:26 Tom wrote:
> Not long ago I was searching the Internet on the topic "combining eager and
> lazy evaluation", and have run over a paper which I obviously dismissed as
> "not interesting enough", yet now I have realized that it could indeed be
> useful, but am unable to find it.
>
> I know it was talking about a useful primitive, I do not know how exactly
> it was named, which checked whether values passed as arguments to functions
> were lazy (blocks to be evaluated) or eager (already evaluated), and using
> it some functions, e.g. map (this example was present in the paper) could
> be implemented to be both eager and lazy at the same time, depending on the
> arguments.
>
> Does anyone recognize this description?

Scala can do something similar by controlling evaluation simply by altering 
the signature. However, I've reviewed Haskell recently and I think complete 
laziness is more of a hindrance than a benefit. The only think I'd like to 
see added to eager FPLs is the ability to pattern match over lazy values, 
forcing them only when necessary.

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?e


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18 12:25 ` Jon Harrop
@ 2007-10-18 12:40   ` Arnaud Spiwack
  2007-10-18 13:17     ` Jon Harrop
  2007-10-18 12:46   ` Jacques Garrigue
  2007-10-18 20:07   ` Tom
  2 siblings, 1 reply; 37+ messages in thread
From: Arnaud Spiwack @ 2007-10-18 12:40 UTC (permalink / raw)
  To: caml-list


> Scala can do something similar by controlling evaluation simply by altering 
> the signature. However, I've reviewed Haskell recently and I think complete 
> laziness is more of a hindrance than a benefit. The only think I'd like to 
> see added to eager FPLs is the ability to pattern match over lazy values, 
> forcing them only when necessary.
>   
Which might simply need to have a support for views, wouldn't it ?


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18 12:25 ` Jon Harrop
  2007-10-18 12:40   ` Arnaud Spiwack
@ 2007-10-18 12:46   ` Jacques Garrigue
  2007-10-18 13:57     ` Jon Harrop
  2007-10-18 20:07   ` Tom
  2 siblings, 1 reply; 37+ messages in thread
From: Jacques Garrigue @ 2007-10-18 12:46 UTC (permalink / raw)
  To: jon; +Cc: caml-list

From: Jon Harrop <jon@ffconsultancy.com>
> On Thursday 18 October 2007 10:52:26 Tom wrote:
> > Not long ago I was searching the Internet on the topic "combining eager and
> > lazy evaluation", and have run over a paper which I obviously dismissed as
> > "not interesting enough", yet now I have realized that it could indeed be
> > useful, but am unable to find it.
> >
> > I know it was talking about a useful primitive, I do not know how exactly
> > it was named, which checked whether values passed as arguments to functions
> > were lazy (blocks to be evaluated) or eager (already evaluated), and using
> > it some functions, e.g. map (this example was present in the paper) could
> > be implemented to be both eager and lazy at the same time, depending on the
> > arguments.
> >
> > Does anyone recognize this description?
> 
> Scala can do something similar by controlling evaluation simply by altering 
> the signature. However, I've reviewed Haskell recently and I think complete 
> laziness is more of a hindrance than a benefit. The only think I'd like to 
> see added to eager FPLs is the ability to pattern match over lazy values, 
> forcing them only when necessary.

What! You want Caml V3.1 (released in 1991 IIRC)!
I remember writing a lazy prolog interpreter using this feature.

Lazyness in ocaml works too, but it's more verbose.

Actually Caml 3.1 had only lazy fields in records. To be complete, one
would like to mark as lazy any part of a datatype, like you could mark
as mutable fields of a constructor in later versions of caml-light.

But then I don't use lazyness in data structures very often. 

Jacques Garrigue


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18 12:40   ` Arnaud Spiwack
@ 2007-10-18 13:17     ` Jon Harrop
  2007-10-18 15:15       ` Till Varoquaux
  0 siblings, 1 reply; 37+ messages in thread
From: Jon Harrop @ 2007-10-18 13:17 UTC (permalink / raw)
  To: caml-list

On Thursday 18 October 2007 13:40:43 Arnaud Spiwack wrote:
> > Scala can do something similar by controlling evaluation simply by
> > altering the signature. However, I've reviewed Haskell recently and I
> > think complete laziness is more of a hindrance than a benefit. The only
> > think I'd like to see added to eager FPLs is the ability to pattern match
> > over lazy values, forcing them only when necessary.
>
> Which might simply need to have a support for views, wouldn't it ?

Yes. F# provides pattern matching over lazy lists using exactly that technique 
and views are more generally useful when dissecting data structures held in 
foreign formats without copying them.

However, implementing views is probably a lot harder than just implementing 
pattern matching over lazy values. I suspect pattern matching over lazy 
values could be implemented much more efficiently that the more general case 
of views.

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?e


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18 12:46   ` Jacques Garrigue
@ 2007-10-18 13:57     ` Jon Harrop
  2007-10-18 14:22       ` Brian Hurt
  0 siblings, 1 reply; 37+ messages in thread
From: Jon Harrop @ 2007-10-18 13:57 UTC (permalink / raw)
  To: caml-list

On Thursday 18 October 2007 13:46:10 you wrote:
> From: Jon Harrop <jon@ffconsultancy.com>
> > Scala can do something similar by controlling evaluation simply by
> > altering the signature. However, I've reviewed Haskell recently and I
> > think complete laziness is more of a hindrance than a benefit. The only
> > think I'd like to see added to eager FPLs is the ability to pattern match
> > over lazy values, forcing them only when necessary.
>
> What! You want Caml V3.1 (released in 1991 IIRC)!
> I remember writing a lazy prolog interpreter using this feature.
>
> Lazyness in ocaml works too, but it's more verbose.

How do you pattern match over lazy values in OCaml? If I've missed that, it 
would be really cool to find out! :-)

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?e


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18 13:57     ` Jon Harrop
@ 2007-10-18 14:22       ` Brian Hurt
  2007-10-18 14:52         ` Robert Fischer
  2007-10-18 17:18         ` Jon Harrop
  0 siblings, 2 replies; 37+ messages in thread
From: Brian Hurt @ 2007-10-18 14:22 UTC (permalink / raw)
  To: caml-list

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

Jon Harrop wrote:

>On Thursday 18 October 2007 13:46:10 you wrote:
>  
>
>>From: Jon Harrop <jon@ffconsultancy.com>
>>    
>>
>>>Scala can do something similar by controlling evaluation simply by
>>>altering the signature. However, I've reviewed Haskell recently and I
>>>think complete laziness is more of a hindrance than a benefit. The only
>>>think I'd like to see added to eager FPLs is the ability to pattern match
>>>over lazy values, forcing them only when necessary.
>>>      
>>>
>>What! You want Caml V3.1 (released in 1991 IIRC)!
>>I remember writing a lazy prolog interpreter using this feature.
>>
>>Lazyness in ocaml works too, but it's more verbose.
>>    
>>
>
>How do you pattern match over lazy values in OCaml? If I've missed that, it 
>would be really cool to find out! :-)
>
>  
>
You have to explicitly force the lazy value first- but other than it 
being explicit, this is no different from other languages that 
implicitly force the value for you.  Well, Haskell has an option where a 
pattern match can always succeed that doesn't necessarily force the lazy 
value (I forget what it's called at the moment), but baring that, even 
standard Haskell pattern matching forces the value for the match.

Brian


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

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  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
  1 sibling, 1 reply; 37+ messages in thread
From: Robert Fischer @ 2007-10-18 14:52 UTC (permalink / raw)
  To: Brian Hurt; +Cc: caml-list


> You have to explicitly force the lazy value first- but other than it 
> being explicit, this is no different from other languages that 
> implicitly force the value for you.  Well, Haskell has an option where 
> a pattern match can always succeed that doesn't necessarily force the 
> lazy value (I forget what it's called at the moment), but baring that, 
> even standard Haskell pattern matching forces the value for the match.
...which is pretty much how it is going to have to work until someone 
builds a programming language with psychic precognition.

~~ Robert.


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18 14:52         ` Robert Fischer
@ 2007-10-18 15:04           ` Eric Cooper
  0 siblings, 0 replies; 37+ messages in thread
From: Eric Cooper @ 2007-10-18 15:04 UTC (permalink / raw)
  To: caml-list

On Thu, Oct 18, 2007 at 09:52:22AM -0500, Robert Fischer wrote:
>> You have to explicitly force the lazy value first- but other than it being 
>> explicit, this is no different from other languages that implicitly force 
>> the value for you.  Well, Haskell has an option where a pattern match can 
>> always succeed that doesn't necessarily force the lazy value (I forget 
>> what it's called at the moment), but baring that, even standard Haskell 
>> pattern matching forces the value for the match.
> ...which is pretty much how it is going to have to work until someone 
> builds a programming language with psychic precognition.

Whose reference manual would have to be called
    The Minority Report on the Programming Language Foo :-)

-- 
Eric Cooper             e c c @ c m u . e d u


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18 13:17     ` Jon Harrop
@ 2007-10-18 15:15       ` Till Varoquaux
  0 siblings, 0 replies; 37+ messages in thread
From: Till Varoquaux @ 2007-10-18 15:15 UTC (permalink / raw)
  To: Jon Harrop; +Cc: caml-list

Lat time I checked Don Syme was working to optimize active patterns.
At the time there wasn't (AFAIK) any way to "group" computation
beetween active patterns.
In ocaml pattern matching happens on all the patterns at once, as you
go forward impossible cases are dropped, this is probably what is also
done in Haskell.
Ideally you'd want to:
_Have a number of comparaisons that, in worst case complexity is
O(n+m) where n is the length of your longest pattern and m is the
number of your patterns. I don't know how this could be achieved with
views.
_Force a minimal number of values.
I believe you need your pattern matching compilation to handle lazy
cases specifically in order to get both of the above requirements.
AliceML might do it.

Cheers,
Till


On 10/18/07, Jon Harrop <jon@ffconsultancy.com> wrote:
> On Thursday 18 October 2007 13:40:43 Arnaud Spiwack wrote:
> > > Scala can do something similar by controlling evaluation simply by
> > > altering the signature. However, I've reviewed Haskell recently and I
> > > think complete laziness is more of a hindrance than a benefit. The only
> > > think I'd like to see added to eager FPLs is the ability to pattern match
> > > over lazy values, forcing them only when necessary.
> >
> > Which might simply need to have a support for views, wouldn't it ?
>
> Yes. F# provides pattern matching over lazy lists using exactly that technique
> and views are more generally useful when dissecting data structures held in
> foreign formats without copying them.
>
> However, implementing views is probably a lot harder than just implementing
> pattern matching over lazy values. I suspect pattern matching over lazy
> values could be implemented much more efficiently that the more general case
> of views.
>
> --
> Dr Jon D Harrop, Flying Frog Consultancy Ltd.
> http://www.ffconsultancy.com/products/?e
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>


-- 
http://till-varoquaux.blogspot.com/


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18 14:22       ` Brian Hurt
  2007-10-18 14:52         ` Robert Fischer
@ 2007-10-18 17:18         ` Jon Harrop
  2007-10-19  1:16           ` skaller
                             ` (2 more replies)
  1 sibling, 3 replies; 37+ messages in thread
From: Jon Harrop @ 2007-10-18 17:18 UTC (permalink / raw)
  To: caml-list

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.

> but other than it being explicit,

And not lazy.

> this is no different from other languages that implicitly force the value
> for you. 

On the contrary, it fails to achieve laziness.

> Well, Haskell has an option where a pattern match can always succeed that
> doesn't necessarily force the lazy value

Exactly. Not "necessarily forcing" the lazy value is the essence of lazy 
evaluation and the only point to my suggestion.

> (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;;

# let rec f = function
    | Nil -> Nil
    | Cons(None, t) -> Cons(None, lazy(f(Lazy.force t)))
    | Cons(Some x as h, t) ->
        match Lazy.force t with
        | Nil -> Cons(h, lazy Nil)
        | Cons(None, t) -> Cons(h, lazy(Cons(None, lazy(f(Lazy.force t)))))
        | Cons(Some y, t) -> Cons(Some(x @ y), lazy(f(Lazy.force t)));;
val f : 'a list option llist -> 'a list option llist = <fun>

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

# forces(f(Cons(Some [1], lazy(Cons(Some [2;3], lazy(Cons(None, lazy(Cons(Some 
[4;5], lazy Nil)))))))));;
- : int list option list = [Some [1; 2; 3]; None; Some [4; 5]]

Because you can't pattern match over lazy values, this solution is about as 
beautiful as my first girlfriend.

This is no freakishly theoretical problem either, it crops up whenever I want 
to destructure a collection as a sequence. You can use an unfold but that 
only buys you 1 element look ahead whereas the power of pattern matching 
stems from its ability to dispatch based upon destructuring to arbitrary 
depths.

If it were possible to pattern match over lazy values, you would simply write 
a to_lazylist function in the module of each container and pattern match over 
its result to dissect any container with minimal copying.

In this case, you would write:

# let rec f = function
    | Nil -> []
    | Cons(Some x, lazy(Cons(Some y, lazy t))) -> f(Some(x @ y) :: t)
    | Cons(h, lazy t) -> h :: f t;;
val f : 'a list option llist -> 'a list option llist = <fun>

You could even define the primitives in terms of pattern matching:

  let force (lazy x) = x

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?e


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18 12:25 ` Jon Harrop
  2007-10-18 12:40   ` Arnaud Spiwack
  2007-10-18 12:46   ` Jacques Garrigue
@ 2007-10-18 20:07   ` Tom
  2007-10-19  0:59     ` skaller
  2 siblings, 1 reply; 37+ messages in thread
From: Tom @ 2007-10-18 20:07 UTC (permalink / raw)
  To: Jon Harrop; +Cc: caml-list

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

On 18/10/2007, Andreas Rossberg <rossberg@mpi-sws.mpg.de> wrote:
>
>
> I guess you mean this one:
>
>   http://web.cecs.pdx.edu/~sheard/papers/ExplicitLazy.ps
>
> The primitive you're alluding to is called "mimic" in it.


Exactly! Thanks! I owe my (future) success to you :)

On 18/10/2007, skaller <skaller@users.sourceforge.net> wrote:
>
>
> No, but Felix does it by default
>

What do you mean? You mean that if I write a map

   map f [] = []
   map f x:xs = f x : map f xs

I can apply it both to infinite and lazy lists?

   nums n = n : nums (n + 1)

   map (+1) (nums 4)

   map (print_int) [1; 5; 6]

On 18/10/2007, Jon Harrop <jon@ffconsultancy.com> wrote:
>
>
> Scala can do something similar by controlling evaluation simply by
> altering
> the signature. However, I've reviewed Haskell recently and I think
> complete
> laziness is more of a hindrance than a benefit. The only think I'd like to
> see added to eager FPLs is the ability to pattern match over lazy values,
> forcing them only when necessary.
>

I never said anything about complete laziness. Actually, I positively agree
with you, and I was searching for this paper as I don't want complete
laziness. However, I consider laziness very useful in particular situations!
For example, see this comment:
http://programming.reddit.com/info/2mxh4/comments/c2ngwb

 - Tom

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

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18  9:52 Help me find this pdf Tom
  2007-10-18 10:33 ` [Caml-list] " skaller
  2007-10-18 12:25 ` Jon Harrop
@ 2007-10-18 20:48 ` Lauri Alanko
  2 siblings, 0 replies; 37+ messages in thread
From: Lauri Alanko @ 2007-10-18 20:48 UTC (permalink / raw)
  To: Caml-list List

On Thu, Oct 18, 2007 at 11:52:26AM +0200, Tom wrote:
> Not long ago I was searching the Internet on the topic "combining eager and
> lazy evaluation", and have run over a paper which I obviously dismissed as
> "not interesting enough", yet now I have realized that it could indeed be
> useful, but am unable to find it.

Another paper that touches the subject from a somewhat different
direction is this one:

http://research.microsoft.com/~simonpj/papers/not-not-ml/


Lauri


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-18 20:07   ` Tom
@ 2007-10-19  0:59     ` skaller
  0 siblings, 0 replies; 37+ messages in thread
From: skaller @ 2007-10-19  0:59 UTC (permalink / raw)
  To: Tom; +Cc: Jon Harrop, caml-list


> On 18/10/2007, skaller <skaller@users.sourceforge.net> wrote:
>         
>         No, but Felix does it by default
> 
> What do you mean? You mean that if I write a map
> 
>    map f [] = []
>    map f x:xs = f x : map f xs
> 
> I can apply it both to infinite and lazy lists?

No, it means that when you write

	fun map[t] (f:t->u) (xs:list[t]) => ...

it is indeterminate whether f and/or xs are evaluated
before calling map (eager evaluation), or whether they're 
replaced by their arguments in the definition of map
(lazy evaluation). 

If the list itself is given by a formula, this means
the formula for the list may replace 'xs' in the map,
and only be evaluated when required. 

In particular the list may be enumerated eagerly
or lazily so it must be a list, not a stream,
or your program may fail to terminate.

In Felix a list is given by

	union list[t] = Empty | Cons of t * list[t];

and the combinators for | and * are eager, so all
inductive data types in Felix are eager. Only function
application has indeterminate timing.

I'm not sure I can fix this because, for example,
a product is just a C++ struct, and C++ operator. cannot
be overloaded. However operator->() and operator *() can
be overloaded, so it just might be possible to make
pattern matching lazy.

Thanks for asking this question .. forced me to think!



-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  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 13:00           ` [Caml-list] " Brian Hurt
  2 siblings, 0 replies; 37+ messages in thread
From: skaller @ 2007-10-19  1:16 UTC (permalink / raw)
  To: Jon Harrop; +Cc: caml-list


On Thu, 2007-10-18 at 18:18 +0100, Jon Harrop wrote:

> Because you can't pattern match over lazy values, this solution is about as 
> beautiful as my first girlfriend.

Hopefully both GF and wife class as 'eager' not 'lazy' .. :)

> This is no freakishly theoretical problem either, it crops up whenever I want 
> to destructure a collection as a sequence. You can use an unfold but that 
> only buys you 1 element look ahead whereas the power of pattern matching 
> stems from its ability to dispatch based upon destructuring to arbitrary 
> depths.

That's not quite right. Pattern matching in Ocaml has bound look ahead.
Although the bound depends on the actual patterns, there is always a
bound on the depth for any given match. The branch expression 
is evaluated lazily, so you can use recursion to unfold with bound
lookahead. 

Actually it isn't necessary to cache the lookahead values, and indeed
Felix does not: any bindings in the branch expression are actually
re-evaluated, independently of the matching. Caching forced values
isn't mandatory, and not necessarily efficient.

> If it were possible to pattern match over lazy values, you would simply write 
> a to_lazylist function in the module of each container and pattern match over 
> its result to dissect any container with minimal copying.

What it seems to come down to is the same as in Felix: it isn't enough
to have lazy application: the alternation and product 
combinators have to be lazy too, in both their introduction and
elimination parts. Hmm .. is this right?


-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: Help me find this pdf
  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
                               ` (2 more replies)
  2007-10-19 13:00           ` [Caml-list] " Brian Hurt
  2 siblings, 3 replies; 37+ messages in thread
From: Bárður Árantsson @ 2007-10-19  5:09 UTC (permalink / raw)
  To: caml-list

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.
> 
>> but other than it being explicit,
> 
> And not lazy.
> 
>> this is no different from other languages that implicitly force the value
>> for you. 
> 
[--snip-- lots of examples --snip--]

What you're saying is basically that lazy pattern matching should only 
force as much of the value under examination as is actually necessary to 
decide if there's a match. Do I have that right?

If so, then Haskell does exactly this. Here's a small example:

   import Debug.Trace

   x = trace "Evaluated x" "Hello"
   y = trace "Evaluated y" "World"

   main :: IO ()
   main = do
     let l = [x, y]
     case l of
       (a:_) -> do
              putStrLn "Non-empty list"
              putStrLn a
       _     -> putStrLn "Empty list"

This outputs

   Non-empty list
   Evaluated x
   Hello

Note that if you don't add that "putStrLn a" there, Haskell won't even 
force x!

You're definitely right that doing anything of this sort is currently 
quite painful in OCaml.

Cheers,

-- 
Bardur Arantsson
<bardurREMOVE@THISscientician.net>

It hovered above the ground, much in the way that bricks don't.
                  Douglas Adams, 'Hitchiker's Guide to the Galaxy'


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  2007-10-19  5:09           ` Bárður Árantsson
@ 2007-10-19  5:23             ` 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  8:55             ` Zheng Li
  2007-10-19 22:27             ` [Caml-list] " Jon Harrop
  2 siblings, 2 replies; 37+ messages in thread
From: Erik de Castro Lopo @ 2007-10-19  5:23 UTC (permalink / raw)
  To: caml-list

Bárður Árantsson wrote:

> What you're saying is basically that lazy pattern matching should only 
> force as much of the value under examination as is actually necessary to 
> decide if there's a match. Do I have that right?
> 
> If so, then Haskell does exactly this.

But haskell is lazy by default so of course it does it right.

Erik
-- 
-----------------------------------------------------------------
Erik de Castro Lopo
-----------------------------------------------------------------
"If you have an apple and I have  an apple and we  exchange apples then
you and I will still each have  one apple. But  if you have an idea and I
have an idea and we exchange these ideas, then each of us will have two
ideas." -- George Bernard Shaw


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: Help me find this pdf
  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
  1 sibling, 0 replies; 37+ messages in thread
From: Bárður Árantsson @ 2007-10-19  5:46 UTC (permalink / raw)
  To: caml-list

Erik de Castro Lopo wrote:
> Bárður Árantsson wrote:
> 
>> What you're saying is basically that lazy pattern matching should only 
>> force as much of the value under examination as is actually necessary to 
>> decide if there's a match. Do I have that right?
>>
>> If so, then Haskell does exactly this.
> 
> But haskell is lazy by default so of course it does it right.
> 

Indeed. I was just having a devil of time figuring out what people were 
actually trying to say and some people seemed to be talking past each 
other, so I just thought I'd try phrasing it as succinctly as possible. 
(Using Haskell as an example of how to do it right.)

Cheers,

-- 
Bardur Arantsson
<bardurREMOVE@THISscientician.net>

- Kittens give Morbo gas. In lighter news, the city of New New
York is doomed. Blame rests with known human Professor Hubert
Farnsworth and his tiny inferior brain.
                                                 Morbo, 'Futurama'


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: Help me find this pdf
  2007-10-19  5:09           ` Bárður Árantsson
  2007-10-19  5:23             ` [Caml-list] " Erik de Castro Lopo
@ 2007-10-19  8:55             ` Zheng Li
  2007-10-19 22:27             ` [Caml-list] " Jon Harrop
  2 siblings, 0 replies; 37+ messages in thread
From: Zheng Li @ 2007-10-19  8:55 UTC (permalink / raw)
  To: caml-list

Bárður Árantsson <spam@scientician.net> writes:
> What you're saying is basically that lazy pattern matching should only force as
> much of the value under examination as is actually necessary to decide if
> there's a match. Do I have that right?
>
> If so, then Haskell does exactly this. Here's a small example:
>
>   import Debug.Trace
>
>   x = trace "Evaluated x" "Hello"
>   y = trace "Evaluated y" "World"
>
>   main :: IO ()
>   main = do
>     let l = [x, y]
>     case l of
>       (a:_) -> do
>              putStrLn "Non-empty list"
>              putStrLn a
>       _     -> putStrLn "Empty list"
>
> This outputs
>
>   Non-empty list
>   Evaluated x
>   Hello

Isn't it just a matter of explicit and implicit?

let x = [<'(print_endline "evaluate x"; "hello")>]
let y = [<'(print_endline "evaluate y"; "hello")>]

let main () =
  let l = [x;y] in
  match l with
  | h::_ -> print_endline "Non-empty list"; print_endline (Stream.next h)
  | _ -> print_endline "Empty list"

Also look at the SDFlow [1] I released a few days ago. It's lazy, combinatorial
and non-strict (but deterministic). If you really want a lazy list in the exact
haskell style, I have no problem to provide a SDList later (given more time),
the only missing pieces from SDFlow to also be considered as lazy lists are:

  - destructive -> nondestructive (dozens of lines)
  - relax recursive value restriction (a camlp4 script) 

[1] http://www.pps.jussieu.fr/~li/software/index.html#sdflow


> Note that if you don't add that "putStrLn a" there, Haskell won't even force x!
>
> You're definitely right that doing anything of this sort is currently quite
> painful in OCaml.
>
> Cheers,
>
> -- 
> Bardur Arantsson
> <bardurREMOVE@THISscientician.net>
>
> It hovered above the ground, much in the way that bricks don't.
>                  Douglas Adams, 'Hitchiker's Guide to the Galaxy'

-- 
Zheng Li
http://www.pps.jussieu.fr/~li


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  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               ` Christophe Raffalli
  2007-10-19 12:47                 ` Luc Maranget
  2007-10-19 14:48                 ` Robert Fischer
  1 sibling, 2 replies; 37+ messages in thread
From: Christophe Raffalli @ 2007-10-19 12:25 UTC (permalink / raw)
  To: caml-list

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

Erik de Castro Lopo a écrit :
> Bárður Árantsson wrote:
> 
>> What you're saying is basically that lazy pattern matching should only 
>> force as much of the value under examination as is actually necessary to 
>> decide if there's a match. Do I have that right?
>>
>> If so, then Haskell does exactly this.
> 
> But haskell is lazy by default so of course it does it right.
> 

You mean that if I write (I use OCaml syntax)

match p, q with
| (true, true) ->
| _ ->

Haskell will first check if (p is evaluated and false) or (q is evaluated and false)
and then, if it is not the case will evaluate p, and finally if p is true it will evaluate q ?

This would mean that compilation of pattern matching in Haskell is a real nightmare ... (this is
already  very painfull in OCaml) ... In fact, this also means that it is not trivial to explain
to the programmer the semantics of deep pattern-matching chosen by a given lazy language ...

In Ocaml the programmer really needs to say what he/she wants and can implement the above test by
hand and it may be considered as a good thing ?


> Erik

Cheers,
-- 
Christophe Raffalli
Universite de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tel: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christophe.Raffalli@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI
---------------------------------------------
IMPORTANT: this mail is signed using PGP/MIME
At least Enigmail/Mozilla, mutt or evolution
can check this signature. The public key is
stored on www.keyserver.net
---------------------------------------------


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  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
  1 sibling, 1 reply; 37+ messages in thread
From: Luc Maranget @ 2007-10-19 12:47 UTC (permalink / raw)
  To: Christophe Raffalli; +Cc: caml-list

> 
> You mean that if I write (I use OCaml syntax)
> 
> match p, q with
> | (true, true) -> A
> | _ -> B
> 
> Haskell will first check if (p is evaluated and false) or (q is evaluated and false)
> and then, if it is not the case will evaluate p, and finally if p is true it will evaluate q ?
> 

Haskell has left-to-right semantics for PM. Basically this is expressed
by PM compilation.

"Semantics" of the above code is given by:

match p with
| true -> (match q with true -> A | _ -> goto next enclosing "_")
| _    -> B

Hence if _|_ is a symbol for looping computation, and ?
is a symbol for just anything (in {_|_, true, false}),
we have:

p   q -> result

_|_ ? -> _|_
true _|_ -> _|_
true true -> A
true false -> B
false ? -> B


> 
> 
> -- 
> Christophe Raffalli

In case you are really interested by the issue, may I mention
one of my recent papers on warnings for pattern matching
<http://pauillac.inria.fr/~maranget/papers/warn/index.html>
(See section 4.)

--Luc


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  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 13:00           ` Brian Hurt
  2007-10-19 13:49             ` Loup Vaillant
  2007-10-19 23:09             ` [Caml-list] " Jon Harrop
  2 siblings, 2 replies; 37+ messages in thread
From: Brian Hurt @ 2007-10-19 13:00 UTC (permalink / raw)
  To: Jon Harrop; +Cc: caml-list

[-- 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 --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-19 13:00           ` [Caml-list] " Brian Hurt
@ 2007-10-19 13:49             ` Loup Vaillant
  2007-10-19 14:41               ` Zheng Li
  2007-10-19 23:09             ` [Caml-list] " Jon Harrop
  1 sibling, 1 reply; 37+ messages in thread
From: Loup Vaillant @ 2007-10-19 13:49 UTC (permalink / raw)
  To: Brian Hurt; +Cc: Jon Harrop, caml-list

2007/10/19, Brian Hurt <bhurt@janestcapital.com>:
> 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.

(Disclaimer: I suspect I'm a bit off-topic)
If we really want to, we can delay the evaluation at all costs, by
delaying even the car of the Cons cells

type 'a node_t =
    | Empty
    | Cons of 'a Lazy.t * 'a lazylist
and 'a lazylist = 'a node_t Lazy.t
;;

For instance, when figuring out if the list is empty or not, the first
element isn't forced. You can even force the second element of the
list without forcing the first:

match Lazy.force zlst with
  | Cons(_, tl) ->
    match Lazy.force tl with
      | Cons(hd, _) ->
        let head = Lazy.force hd in
          [...]
;;

Or, assuming I can get away with unsafe code:

let hd zlst = match Lazy.force zlst with
  | Cons(h, _) = h
;;
let tl zlst = match Lazy.force zlst with
  | Cons(_, t) = t
;;

(* and finally *)
match Lazy.force hd (tl zlst)
with [...]
;;

Well, I think this is overdoing laziness: more often than not, the
rest of a lazy list depends on the value of it's head (e.g. the list
of all integers, of a Fibonacci list). In such cases, doubling the
cost of laziness is worth nothing.

Regards,
Loup Vaillant


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: Help me find this pdf
  2007-10-19 13:49             ` Loup Vaillant
@ 2007-10-19 14:41               ` Zheng Li
  0 siblings, 0 replies; 37+ messages in thread
From: Zheng Li @ 2007-10-19 14:41 UTC (permalink / raw)
  To: caml-list


Just for fun :>

----
# let rec f ?(pred=[]) s = 
    let conv = function [] -> [<>] | l -> [<'Some l>] in
    [< match s with parser
       | [<'Some x>] -> f ~pred:(pred@x) s
       | [<'h>] -> [<conv pred; 'h; f s>]
       | [<>] -> [<conv pred>] >];;
# open Sdflow;;
# of_list [Some[1]; Some[2; 3]; None; Some[4; 5]] |> f |> to_list;;
- : int list option list = [Some [1; 2; 3]; None; Some [4; 5]]
----

Note that any first element's evaluation is also lazy. 

The [f] above is defined with plain Stream, but you can archive the same with
SDFlow's high-order combinator here such as map, map_fold etc.

"Loup Vaillant" <loup.vaillant@gmail.com> writes:
> If we really want to, we can delay the evaluation at all costs, by
> delaying even the car of the Cons cells
>
> type 'a node_t =
>     | Empty
>     | Cons of 'a Lazy.t * 'a lazylist
> and 'a lazylist = 'a node_t Lazy.t
> ;;
>
> For instance, when figuring out if the list is empty or not, the first
> element isn't forced. You can even force the second element of the
> list without forcing the first:
>
> match Lazy.force zlst with
>   | Cons(_, tl) ->
>     match Lazy.force tl with
>       | Cons(hd, _) ->
>         let head = Lazy.force hd in
>           [...]
> ;;
>
> Or, assuming I can get away with unsafe code:
>
> let hd zlst = match Lazy.force zlst with
>   | Cons(h, _) = h
> ;;
> let tl zlst = match Lazy.force zlst with
>   | Cons(_, t) = t
> ;;
>
> (* and finally *)
> match Lazy.force hd (tl zlst)
> with [...]
> ;;

-- 
Zheng Li
http://www.pps.jussieu.fr/~li


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  2007-10-19 12:25               ` [Caml-list] " Christophe Raffalli
  2007-10-19 12:47                 ` Luc Maranget
@ 2007-10-19 14:48                 ` Robert Fischer
  2007-10-19 21:43                   ` Andreas Rossberg
  1 sibling, 1 reply; 37+ messages in thread
From: Robert Fischer @ 2007-10-19 14:48 UTC (permalink / raw)
  To: Christophe Raffalli; +Cc: caml-list


> You mean that if I write (I use OCaml syntax)
>
> match p, q with
> | (true, true) ->
> | _ ->
>
>   
> This would mean that compilation of pattern matching in Haskell is a real nightmare ... (this is
> already  very painfull in OCaml) ... In fact, this also means that it is not trivial to explain
> to the programmer the semantics of deep pattern-matching chosen by a given lazy language ...
>
> In Ocaml the programmer really needs to say what he/she wants and can implement the above test by
> hand and it may be considered as a good thing ?
>
>   
There's a philosophical difference here between Haskell and Ocaml.  
Haskell considers it harmful (they call it "impure") for the programmer 
to know when X is evaluated, and (by implication) therefore considers it 
acceptable for Heisenbugs and vague semantics to be standard aspects of 
the language.  Ocaml, on the other hand, requires much more 
explicitness, particularly around theoretically beautiful but 
potentially harmful things like lazy evaluation.

~~ Robert.


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  2007-10-19 14:48                 ` Robert Fischer
@ 2007-10-19 21:43                   ` Andreas Rossberg
  2007-10-19 21:51                     ` Robert Fischer
  2007-10-19 23:10                     ` Jon Harrop
  0 siblings, 2 replies; 37+ messages in thread
From: Andreas Rossberg @ 2007-10-19 21:43 UTC (permalink / raw)
  To: caml-list

On Oct 19, 2007, at 16.48h, Robert Fischer wrote:
> There's a philosophical difference here between Haskell and Ocaml.   
> Haskell considers it harmful (they call it "impure") for the  
> programmer to know when X is evaluated, and (by implication)  
> therefore considers it acceptable for Heisenbugs and vague  
> semantics to be standard aspects of the language.  Ocaml, on the  
> other hand, requires much more explicitness, particularly around  
> theoretically beautiful but potentially harmful things like lazy  
> evaluation.

Wow, that made my FUD sensors go wild. To counter some of the  
misinformation:

1. Purity and evaluation regime are separate issues. You can very  
well have a pure language that is eager.

2. However, in a pure language the details of evaluation order are  
largely immaterial to its semantics, which obviously is an advantage.

3. Lazy evaluation by itself is as precise an evaluation scheme as  
eager evaluation. There is no inherent vagueness.

4. In fact, the semantics of OCaml arguably is more vague than that  
of Haskell, because evaluation order is underspecified (and can vary  
between compilers) even where it matters semantically. Haskell only  
leaves it unspecified where it is not semantically observable.

5. The problem with Haskell and laziness on the other hand is not  
semantic bugs, but the fact that it can make space complexity hard to  
predict sometimes.

6. Nevertheless, evaluation is fully deterministic, thus it certainly  
cannot cause Heisenbugs, neither semantically nor performance-wise.

- Andreas


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  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
  1 sibling, 1 reply; 37+ messages in thread
From: Robert Fischer @ 2007-10-19 21:51 UTC (permalink / raw)
  To: Andreas Rossberg; +Cc: caml-list


>> There's a philosophical difference here between Haskell and Ocaml.  
>> Haskell considers it harmful (they call it "impure") for the 
>> programmer to know when X is evaluated, and (by implication) 
>> therefore considers it acceptable for Heisenbugs and vague semantics 
>> to be standard aspects of the language.  Ocaml, on the other hand, 
>> requires much more explicitness, particularly around theoretically 
>> beautiful but potentially harmful things like lazy evaluation.
>
> Wow, that made my FUD sensors go wild. To counter some of the 
> misinformation:
>
> 1. Purity and evaluation regime are separate issues. You can very well 
> have a pure language that is eager.
The way I understand it, the omnipresent laziness of Haskell is at least 
partly justified because it is a way of encouraging being functionally 
pure.  Is that wrong?
> 6. Nevertheless, evaluation is fully deterministic, thus it certainly 
> cannot cause Heisenbugs, neither semantically nor performance-wise.
If I put in a debug statement, it will like change the timing when 
something gets forced, right?  This, in turn, can change all kinds of 
time/space performance characteristics, and potentially even the code 
that is executed (through interrupting deforestation).  So your 
debugging statements might well change the very characteristic of the 
program that you're defining as a bug.

~~ Robert.


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  2007-10-19  5:09           ` Bárður Árantsson
  2007-10-19  5:23             ` [Caml-list] " Erik de Castro Lopo
  2007-10-19  8:55             ` Zheng Li
@ 2007-10-19 22:27             ` Jon Harrop
  2 siblings, 0 replies; 37+ messages in thread
From: Jon Harrop @ 2007-10-19 22:27 UTC (permalink / raw)
  To: caml-list

On Friday 19 October 2007 06:09:02 Bárður Árantsson wrote:
> What you're saying is basically that lazy pattern matching should only
> force as much of the value under examination as is actually necessary to
> decide if there's a match. Do I have that right?

Exactly right, yes.

> If so, then Haskell does exactly this.

Yes.

> You're definitely right that doing anything of this sort is currently
> quite painful in OCaml.

Indeed.

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?e


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Help me find this pdf
  2007-10-19 13:00           ` [Caml-list] " Brian Hurt
  2007-10-19 13:49             ` Loup Vaillant
@ 2007-10-19 23:09             ` Jon Harrop
  1 sibling, 0 replies; 37+ messages in thread
From: Jon Harrop @ 2007-10-19 23:09 UTC (permalink / raw)
  To: caml-list

On Friday 19 October 2007 14:00:38 you wrote:
> 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.

Ugly as hell in the general case: you're basically stuck writing Lisp.

> But it works.

Sure.

> And (modulo laziness around the options and appending) is the same as what
> Haskell would do. 

Yes.

> The only thing missing is some syntactic sugar to make the above pattern
> matching nicer-

I do not class pattern matching or laziness as "syntax". This would be 
non-trivial to implement.

> 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.

OCaml's pattern match compiler could be productively extended to generate that 
code for you, IMHO. Implementing this as a camlp4 macro might be quite 
feasible...

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?e


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  2007-10-19 21:43                   ` Andreas Rossberg
  2007-10-19 21:51                     ` Robert Fischer
@ 2007-10-19 23:10                     ` Jon Harrop
  2007-10-20  1:13                       ` skaller
  1 sibling, 1 reply; 37+ messages in thread
From: Jon Harrop @ 2007-10-19 23:10 UTC (permalink / raw)
  To: caml-list

On Friday 19 October 2007 22:43:42 Andreas Rossberg wrote:
> Wow, that made my FUD sensors go wild.

This whole thread made my FUD sensors go wild. :-)

> 1. Purity and evaluation regime are separate issues. You can very
> well have a pure language that is eager.

IIRC, you then need the option of laziness to be able to implement all 
programs with the same asymptotic complexity as impure/eager or pure/lazy.

> 2. However, in a pure language the details of evaluation order are
> largely immaterial to its semantics, which obviously is an advantage.

I'm not sure that unknown evaluation order is an "obvious" advantage in 
general. For example, when evaluating "f && g" where f is O(1) and g is O(n!) 
you might want to know that "f" gets evaluated first.

> 3. Lazy evaluation by itself is as precise an evaluation scheme as
> eager evaluation. There is no inherent vagueness.

Does a thunk preventing a large data structure from being deallocated count 
as "inherent vagueness"?

> 4. In fact, the semantics of OCaml arguably is more vague than that
> of Haskell, because evaluation order is underspecified (and can vary
> between compilers) even where it matters semantically. Haskell only
> leaves it unspecified where it is not semantically observable.

IIRC, ocamlc and ocamlopt really do evaluate in different orders sometimes.

> 5. The problem with Haskell and laziness on the other hand is not
> semantic bugs, but the fact that it can make space complexity hard to
> predict sometimes.

And time performance hard or impossible to achieve.

> 6. Nevertheless, evaluation is fully deterministic, thus it certainly
> cannot cause Heisenbugs, neither semantically nor performance-wise.

Perhaps I've missed something but surely evaluation order can alter asymptotic 
complexity? If so, moving from one compiler to another can change the 
asymptotic complexity of your program?

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?e


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  2007-10-19 23:10                     ` Jon Harrop
@ 2007-10-20  1:13                       ` skaller
  2007-10-20  6:36                         ` Tom
  0 siblings, 1 reply; 37+ messages in thread
From: skaller @ 2007-10-20  1:13 UTC (permalink / raw)
  To: Jon Harrop; +Cc: caml-list


On Sat, 2007-10-20 at 00:10 +0100, Jon Harrop wrote:

> > 6. Nevertheless, evaluation is fully deterministic, thus it certainly
> > cannot cause Heisenbugs, neither semantically nor performance-wise.
> 
> Perhaps I've missed something but surely evaluation order can alter asymptotic 
> complexity? If so, moving from one compiler to another can change the 
> asymptotic complexity of your program?

There's no need to do anything so radical. 
GHC uses the old fashioned compile/link technology.

All you need to do is copy and paste a file into another
and use the *same* compiler to gain speed improvements.

IMHO its about time this rubbish was eliminated.
Static linkers are a legacy technology from the '70s.


-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  2007-10-20  1:13                       ` skaller
@ 2007-10-20  6:36                         ` Tom
  2007-10-21 11:17                           ` skaller
  0 siblings, 1 reply; 37+ messages in thread
From: Tom @ 2007-10-20  6:36 UTC (permalink / raw)
  To: skaller; +Cc: Jon Harrop, caml-list

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

On 20/10/2007, skaller <skaller@users.sourceforge.net> wrote:
>
>
> IMHO its about time this rubbish was eliminated.
> Static linkers are a legacy technology from the '70s.



Is there an alternative?

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

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  2007-10-19 21:51                     ` Robert Fischer
@ 2007-10-20 13:10                       ` Andreas Rossberg
  0 siblings, 0 replies; 37+ messages in thread
From: Andreas Rossberg @ 2007-10-20 13:10 UTC (permalink / raw)
  To: caml-list

"Robert Fischer" <robert@fischerventure.com> wrote:
>
>> 1. Purity and evaluation regime are separate issues. You can very well 
>> have a pure language that is eager.
> The way I understand it, the omnipresent laziness of Haskell is at least 
> partly justified because it is a way of encouraging being functionally 
> pure.  Is that wrong?

I guess you are alluding to SPJ's famous quote that "one advantage of 
laziness is that it keeps the language designer honest". But that wasn't its 
motivation, rather a tongue in cheek observation, made after more than a 
decade of language evolution.

>> 6. Nevertheless, evaluation is fully deterministic, thus it certainly 
>> cannot cause Heisenbugs, neither semantically nor performance-wise.
> If I put in a debug statement, it will like change the timing when 
> something gets forced, right?  This, in turn, can change all kinds of 
> time/space performance characteristics, and potentially even the code that 
> is executed (through interrupting deforestation).  So your debugging 
> statements might well change the very characteristic of the program that 
> you're defining as a bug.

In an (otherwise pure) language, (even impure) debug output cannot hide a 
bug that is present without it. You are right that it can change the 
performance characteristics of a program by inducing additional strictness. 
But debug outputs are rather useless for performance tuning anyway, for 
which you would use more high-level tools.

"Jon Harrop" <jon@ffconsultancy.com> wrote:
>
>> 1. Purity and evaluation regime are separate issues. You can very
>> well have a pure language that is eager.
>
> IIRC, you then need the option of laziness to be able to implement all 
> programs with the same asymptotic complexity as impure/eager or pure/lazy.

Even with laziness you cannot always achieve the same complexity in a pure 
language, unless you have something like built-in state monads giving you 
constant-time update in a pure fashion - which is independent from laziness.

>> 2. However, in a pure language the details of evaluation order are
>> largely immaterial to its semantics, which obviously is an advantage.
>
> I'm not sure that unknown evaluation order is an "obvious" advantage in 
> general. For example, when evaluating "f && g" where f is O(1) and g is 
> O(n!) you might want to know that "f" gets evaluated first.

I didn't say it is an advantage if you don't know. It is an advantage if you 
don't *have to* know.

>> 3. Lazy evaluation by itself is as precise an evaluation scheme as
>> eager evaluation. There is no inherent vagueness.
>
> Does a thunk preventing a large data structure from being deallocated 
> count as "inherent vagueness"?

I don't think so. At least in principle, you always know when something is 
evaluated. In practice that can be hard to determine, of course, but that 
doesn't make it "vague".

The vagueness of garbage collection itself is a different issue that is not 
addressed in any major language I am aware of.

>> 5. The problem with Haskell and laziness on the other hand is not
>> semantic bugs, but the fact that it can make space complexity hard to
>> predict sometimes.
>
> And time performance hard or impossible to achieve.

Evaluating a given expression lazily can never take more steps than 
evaluating it eagerly. So in principle, achieving a certain time complexity 
is no harder than under eager evaluation (everything else being equal). But 
when you try to be smarter and actually exploit laziness you can certainly 
run into surprises.

>> 6. Nevertheless, evaluation is fully deterministic, thus it certainly
>> cannot cause Heisenbugs, neither semantically nor performance-wise.
>
> Perhaps I've missed something but surely evaluation order can alter 
> asymptotic complexity? If so, moving from one compiler to another can 
> change the asymptotic complexity of your program?

Well, that is a slightly different issue. Of course, certain high-level 
optimizations can cut down the complexity of programs. If you move to a 
compiler that does not perform them you may see a complexity increase. 
However, the naive unoptimized semantics will always be the upper bound.

On the other hand, this is simply an instance of a general problem you see 
with many languages: the more aggressive your compilers are the more careful 
you have to be with assumptions regarding performance that you rely on for 
coding.

- Andreas


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  2007-10-19 12:47                 ` Luc Maranget
@ 2007-10-20 14:26                   ` Christophe Raffalli
  0 siblings, 0 replies; 37+ messages in thread
From: Christophe Raffalli @ 2007-10-20 14:26 UTC (permalink / raw)
  To: Luc Maranget; +Cc: caml-list


[-- Attachment #1.1: Type: text/plain, Size: 1376 bytes --]

Luc Maranget a écrit :
>> You mean that if I write (I use OCaml syntax)
>>
>> match p, q with
>> | (true, true) -> A
>> | _ -> B
>>
>> Haskell will first check if (p is evaluated and false) or (q is evaluated and false)
>> and then, if it is not the case will evaluate p, and finally if p is true it will evaluate q ?
>>
>>     
>
> Haskell has left-to-right semantics for PM. Basically this is expressed
> by PM compilation.
>   
And this is not optimal (I was answering the sentence "Haskell does it
right"). In fact, there is no optimal
way of doing pattern matching in lazy languages (with deep pattern)
because the language can not
decide what is best to evaluate. Certainly left to right is a
reasonnable choice,
but letting the programmer choose (or even forcing him to choose has in
OCaml) is
a good choice (I think better).

-- 
Christophe Raffalli
Universite de Savoie
Batiment Le Chablais, bureau 21
73376 Le Bourget-du-Lac Cedex

tel: (33) 4 79 75 81 03
fax: (33) 4 79 75 87 42
mail: Christophe.Raffalli@univ-savoie.fr
www: http://www.lama.univ-savoie.fr/~RAFFALLI
---------------------------------------------
IMPORTANT: this mail is signed using PGP/MIME
At least Enigmail/Mozilla, mutt or evolution 
can check this signature. The public key is
stored on www.keyserver.net
---------------------------------------------


[-- Attachment #1.2: Christophe.Raffalli.vcf --]
[-- Type: text/x-vcard, Size: 310 bytes --]

begin:vcard
fn:Christophe Raffalli
n:Raffalli;Christophe
org:LAMA (UMR 5127)
email;internet:christophe.raffalli@univ-savoie.fr
title;quoted-printable:Ma=C3=AEtre de conf=C3=A9rences
tel;work:+33 4 79 75 81 03
note:http://www.lama.univ-savoie.fr/~raffalli
x-mozilla-html:TRUE
version:2.1
end:vcard


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 249 bytes --]

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Caml-list] Re: Help me find this pdf
  2007-10-20  6:36                         ` Tom
@ 2007-10-21 11:17                           ` skaller
  0 siblings, 0 replies; 37+ messages in thread
From: skaller @ 2007-10-21 11:17 UTC (permalink / raw)
  To: Tom; +Cc: caml-list


On Sat, 2007-10-20 at 08:36 +0200, Tom wrote:
> On 20/10/2007, skaller <skaller@users.sourceforge.net> wrote:
>         
>         IMHO its about time this rubbish was eliminated.
>         Static linkers are a legacy technology from the '70s.
> 
> 
> Is there an alternative? 

Of course: whole program analysis as in Felix and MLton.

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2007-10-21 11:18 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-18  9:52 Help me find this pdf 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           ` [Caml-list] " Brian Hurt
2007-10-19 13:49             ` 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

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).