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

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

```