Version française
Home     About     Download     Resources     Contact us    

This site is updated infrequently. For up-to-date information, please visit the new OCaml website at ocaml.org.

Browse thread
Strange evaluation order
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2002-05-19 (10:52)
From: Nicolas Barbulesco <nbarbulesco@y...>
Subject: Re: "ocaml_beginners"::[] Strange evaluation order
> (math. note : none of sin(4), sin(9) are integers)

Right, eagle eye ;-)
 
> > So I wanted to test if Caml was thus-lazy (the answer seems to be no, by
> > the way).
> 
> It's not. The argument in a function call is always evaluated before the
> code of the function is triggered. This may or may not be in the reference
> manual, I don't have it handy, but it is a well known fact.

OK.

> Note that firstOfTheCouple takes _one_ argument, a pair, and thus this
> pair must be fully evaluated before applying firstOfTheCouple (Ocaml has
> no "half pairs"). The components of the pair are evaluated from right to
> left ... but this is unspecified in the language.

With a couple, it is normal that all items are evaluated. Caml needs the 
entire couple. (Does it with the Lazy module (below) ?) He just starts from 
the right, but the reason is maybe something like « It has to start from a 
place, so why left rather than right ? »...

> You can force a left-to-right evaluation order by stating it explicitely :
> 
> # let f = firstOfTheTwo (double 5) in f(double 6) ;;
> double 5
> double 6
> - : int = 10

How Caml can do something different ? I don't understand why specifying 
this changes. I thought that (because the function is curryfied) when I 
call firstOfTheTwo a b Caml did exactly that : applying firstOfTheTwo to a, 
and applying the result to b, which corresponds to what you wrote with the 
let f = firstOfTheTwo a in f b syntax. And which corresponds too with 
#trace : an intermediary function (firstOfTheTwo*) appears, and is applied 
to b.

> You can also get lazy evaluation with the "lazy" construct (see the ref.
> man) :

I'll see the man later : caml. and pauillac. are down.
 
> # let lazyfun a b = let aval = Lazy.force a in if aval > 0 then aval else
> Lazy.force b;;
> val lazyfun : int Lazy.t -> int Lazy.t -> int = <fun>
> # lazyfun (lazy(double 3)) (lazy(double 4));;
> double 3
> - : int = 6
> # lazyfun (lazy(double (-3))) (lazy(double 4));;
> double -3
> double 4
> - : int = 8

OK, thanx. This is even a little more lazy that what I told, because b is 
sometimes needed (not never) and evaluated only when needed. But, with this 
on-demand evaluation, is there the side effect that if b is needed twice it 
will be evaluated twice ? If there is not this side-effect, we can call 
this the ideal lazy evaluation, or ? By the way, is there any advantages of 
eager evaluation compared to ideal lazy evaluation ?

Nico