caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Parameter evaluation order
@ 2005-08-19 22:21 "Márk S. Zoltán"
  2005-08-20  9:12 ` [Caml-list] " Alain Frisch
  2005-08-22 16:50 ` Damien Doligez
  0 siblings, 2 replies; 26+ messages in thread
From: "Márk S. Zoltán" @ 2005-08-19 22:21 UTC (permalink / raw)
  To: caml-list

I was recently thinking about parameter evaluation order and how come it 
is unspecified in OCaml. Maybe this was already discussed here, but I do 
not recall it and cannot find it, either. Do not get me wrong, I do not 
have an unsurmontable problem with unspecified parameter evaluation 
ordering, and in a world full of languages with similar disclaimers I 
could not even have a problem. Also, side effects in parameters is just 
ugly. So the current shape of the language is fine with me.

But I do think that currying + strictness + side-effects => 
left-to-right evaluation order.  That is because a multi-parameter 
function application should be functionally equivalent to a closure 
taking the first (== leftmost) parameter and returning a closure which 
takes the second parameter etc. while parameters should be evaluated 
before passing, as per strictness. 

Consider the following code:

==== ordertest.ml =====
let f a b c d = ()

let () =
  let ff1 = f (print_string "1") in
  let ff2 = ff1 (print_string "2") in
  let ff3 = ff2 (print_string "3") in
  ff3 (print_string "4");
  print_newline ()

let () =
  let f2 = f (print_string "1") (print_string "2")
  in f2 (print_string "3") (print_string "4") ;
  print_newline ()

let () =
  f
    (print_string "1")
    (print_string "2")
    (print_string "3")
    (print_string "4");
  print_newline ()
==============

The three let ()'s should be functionally equivalent, and yet they are not:

---------------------
$ ocaml ordertest.ml
1234
2143
4321
---------------------

ocamlopt creates a different outcome, but that is well known: the last 
line reads 1234.

Of course, if this kind of logic was applied, labels and FFI's would be 
difficult to handle. Probably even enrichment of the type system with 
'has side effect' and forbidding the use of expressions with such types 
in parameters would be simpler than that, not that I advocate either 
solution. I do not say we should have left-to-right evaluation order, 
only that it would be more logical.  Am I wrong?

    M-







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

* Re: [Caml-list] Parameter evaluation order
  2005-08-19 22:21 Parameter evaluation order "Márk S. Zoltán"
@ 2005-08-20  9:12 ` Alain Frisch
  2005-08-26 17:53   ` "Márk S. Zoltán"
  2005-08-22 16:50 ` Damien Doligez
  1 sibling, 1 reply; 26+ messages in thread
From: Alain Frisch @ 2005-08-20  9:12 UTC (permalink / raw)
  To: "Márk S. Zoltán"; +Cc: caml-list

Márk S. Zoltán wrote:
> But I do think that currying + strictness + side-effects =>
> left-to-right evaluation order.  That is because a multi-parameter
> function application should be functionally equivalent to a closure
> taking the first (== leftmost) parameter and returning a closure which
> takes the second parameter 

It is, but your conclusion about left-to-right evaluation order is
wrong. It's just that the binary application operator evaluates first
its second argument (the function's argument), then its first argument
(the functional value), and finally applies the function to the
argument. An application (e1 e2) is semantically equivalent to:  (let y
= e2 in let x = e1 in x y). Hence you get right-to-left evaluation order
(but this is not specified).

-- Alain


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

* Re: [Caml-list] Parameter evaluation order
  2005-08-19 22:21 Parameter evaluation order "Márk S. Zoltán"
  2005-08-20  9:12 ` [Caml-list] " Alain Frisch
@ 2005-08-22 16:50 ` Damien Doligez
  2005-08-23  7:12   ` skaller
  2005-08-24  1:24   ` Hao-yang Wang
  1 sibling, 2 replies; 26+ messages in thread
From: Damien Doligez @ 2005-08-22 16:50 UTC (permalink / raw)
  To: caml-list

On Aug 20, 2005, at 00:21, Márk S. Zoltán wrote:

> But I do think that currying + strictness + side-effects => left-to- 
> right evaluation order.

The problem (and historical reason for OCaml's unspecified order) is  
that

currying + side-effects + left-to-right evaluation order => inefficiency

Suppose you want to evaluate a curried function call in left-to-right  
order:
f e1 e2 e3 e4

You must evaluate f first, then e1.  Then you must apply f to e1, giving
a new function g1.  Then you must evalue e2, then apply f1 to e2, giving
f2, etc.

That's because f might do some side effects between its arguments.   
Since
all functions are unary and you must encode n-ary functions with  
currying,
there is no way to specify (within the type system) a function that is
safe for efficient application.  You would like to evaluate f, then e1,
then e2, then e3, then e4, then the whole application at once, but you
cannot.

So the programmer wants to write a function call with 4 arguments, but
he cannot, and his code ends up doing 4 separate function calls, which
is a lot of overhead.

Hence there needs to be a notion of n-ary function at some point.  If  
not
in the type system, then within the compiler, which has to guess which
functions the programmer wants to use as n-ary, and which ones as  
curried,
and translate between the two versions as needed.  Fortunately, it's not
hard to guess, since true curried functions are almost nonexistent,  
so you
can't go wrong (efficiency-wise) if you always guess "n-ary".  The only
drawback is that you have to work harder to implement higher-order
functions, and you lose some efficiency there.

> ==== ordertest.ml =====
> let f a b c d = ()
>
> let () =
>  let ff1 = f (print_string "1") in
>  let ff2 = ff1 (print_string "2") in
>  let ff3 = ff2 (print_string "3") in
>  ff3 (print_string "4");
>  print_newline ()
>
> let () =
>  let f2 = f (print_string "1") (print_string "2")
>  in f2 (print_string "3") (print_string "4") ;
>  print_newline ()
>
> let () =
>  f
>    (print_string "1")
>    (print_string "2")
>    (print_string "3")
>    (print_string "4");
>  print_newline ()
> ==============

You'll see the problem if you try replacing your definition of f with
the following:

let f a =
   print_string "a";
   fun b ->
   print_string "b";
   fun c ->
   print_string "c";
   fun d ->
   print_string "d";
   ()
;;

Note the really strange results when compiled with ocamlopt.

All these problems disappear when you evaluate in right-to-left order,
which corresponds to a nice optimization in the original ZAM: evaluate
and push each argument on the stack, then jump to the function code.

-- Damien


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

* Re: [Caml-list] Parameter evaluation order
  2005-08-22 16:50 ` Damien Doligez
@ 2005-08-23  7:12   ` skaller
  2005-08-23 11:29     ` Damien Doligez
  2005-08-24  1:24   ` Hao-yang Wang
  1 sibling, 1 reply; 26+ messages in thread
From: skaller @ 2005-08-23  7:12 UTC (permalink / raw)
  To: Damien Doligez; +Cc: caml-list

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

On Mon, 2005-08-22 at 18:50 +0200, Damien Doligez wrote:

> Suppose you want to evaluate a curried function call in left-to-right  
> order:
> f e1 e2 e3 e4
> 
> You must evaluate f first, then e1.  Then you must apply f to e1, giving
> a new function g1.  Then you must evalue e2, then apply f1 to e2, giving
> f2, etc.
> 
> That's because f might do some side effects between its arguments.   

what data, and possibly annotations, would be required to solve this
problem?

For example if all functions are total and pure 
then the above problem vanishes.

Felix doesn't permit functions to have side-effects,
however this isn't enough for full optimisation in 
the presence of exceptions, for example. Additionally,
lazy evaluation can save the setting of a variable,
a sufficient condition being purity (non-dependence on variables
as well as having no side-effects) *and* totality.

Seems like these properties:

* writes variables (side-effect)
* reads variables (side-dependence)
* raises exception
* fails to terminate

impact evaluation strategy. It would be good to know which
properties of things would allow which evaluation strategies.


-- 
John Skaller <skaller at users dot sourceforge dot net>


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: [Caml-list] Parameter evaluation order
  2005-08-23  7:12   ` skaller
@ 2005-08-23 11:29     ` Damien Doligez
  2005-08-23 13:34       ` Igor Pechtchanski
  0 siblings, 1 reply; 26+ messages in thread
From: Damien Doligez @ 2005-08-23 11:29 UTC (permalink / raw)
  To: caml-list


On Aug 23, 2005, at 09:12, skaller wrote:



> On Mon, 2005-08-22 at 18:50 +0200, Damien Doligez wrote:
>
>
>
>
>> Suppose you want to evaluate a curried function call in left-to-right
>> order:
>> f e1 e2 e3 e4
>>
>> You must evaluate f first, then e1.  Then you must apply f to e1,  
>> giving
>> a new function g1.  Then you must evalue e2, then apply f1 to e2,  
>> giving
>> f2, etc.
>>
>> That's because f might do some side effects between its arguments.
>>
>>
>>
>
> what data, and possibly annotations, would be required to solve this
> problem?
>
>

The most direct solution is to introduce the notion of function arity
in the type system.  As far as I know, there is no theoretical  
difficulty,
the biggest problem is to find a syntax that satisfies everyone...

-- Damien




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

* Re: [Caml-list] Parameter evaluation order
  2005-08-23 11:29     ` Damien Doligez
@ 2005-08-23 13:34       ` Igor Pechtchanski
  2005-08-23 19:52         ` Damien Doligez
  0 siblings, 1 reply; 26+ messages in thread
From: Igor Pechtchanski @ 2005-08-23 13:34 UTC (permalink / raw)
  To: Damien Doligez; +Cc: caml-list

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1498 bytes --]

On Tue, 23 Aug 2005, Damien Doligez wrote:

> On Aug 23, 2005, at 09:12, skaller wrote:
>
> > On Mon, 2005-08-22 at 18:50 +0200, Damien Doligez wrote:
> >
> > > Suppose you want to evaluate a curried function call in left-to-right
> > > order:
> > > f e1 e2 e3 e4
> > >
> > > You must evaluate f first, then e1.  Then you must apply f to e1,
> > > giving a new function g1.  Then you must evalue e2, then apply f1 to
> > > e2, giving f2, etc.
> > >
> > > That's because f might do some side effects between its arguments.
> >
> > what data, and possibly annotations, would be required to solve this
> > problem?
>
> The most direct solution is to introduce the notion of function arity in
> the type system.  As far as I know, there is no theoretical difficulty,
> the biggest problem is to find a syntax that satisfies everyone...

Hi,

Been lurking on this thread, decided to chime in.

This may be a naïve question, but what's wrong with tuples?  It doesn't
seem like the order in which the tuple components are evaluated matters
(in terms of efficiency, that is).  Am I missing something?
	Igor
-- 
				http://cs.nyu.edu/~pechtcha/
      |\      _,,,---,,_		pechtcha@cs.nyu.edu
ZZZzz /,`.-'`'    -.  ;-;;,_		igor@watson.ibm.com
     |,4-  ) )-,_. ,\ (  `'-'		Igor Pechtchanski, Ph.D.
    '---''(_/--'  `-'\_) fL	a.k.a JaguaR-R-R-r-r-r-.-.-.  Meow!

If there's any real truth it's that the entire multidimensional infinity
of the Universe is almost certainly being run by a bunch of maniacs. /DA

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

* Re: [Caml-list] Parameter evaluation order
  2005-08-23 13:34       ` Igor Pechtchanski
@ 2005-08-23 19:52         ` Damien Doligez
  0 siblings, 0 replies; 26+ messages in thread
From: Damien Doligez @ 2005-08-23 19:52 UTC (permalink / raw)
  To: caml-list

On Aug 23, 2005, at 15:34, Igor Pechtchanski wrote:

> This may be a naïve question, but what's wrong with tuples?  It  
> doesn't
> seem like the order in which the tuple components are evaluated  
> matters
> (in terms of efficiency, that is).  Am I missing something?

Tuples, like currying, is only an encoding.  If you cannot distinguish
between a 4-argument function and a function that takes a 4-tuple as
argument, you have to allocate the tuple in the heap instead of passing
the 4 arguments directly in registers.  Inefficient.

Or you have to make your compiler guess which is which, compile some
functions as taking 4 arguments and some as taking a tuple, and  
translate
between the two representations as needed, in a way that is very similar
to what happens with curried functions, except that this time guessing
"n-ary" every time is not quite as good a heuristic.

Higher-order functions are particularly good at exposing this problem,
because you only know the type of their functional arguments, and you
have to deduce the calling convention from no more information than the
type itself.  But the problem also appears with separate compilation.

-- Damien


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

* Re: Parameter evaluation order
  2005-08-22 16:50 ` Damien Doligez
  2005-08-23  7:12   ` skaller
@ 2005-08-24  1:24   ` Hao-yang Wang
  2005-08-24 11:33     ` [Caml-list] " Damien Doligez
  1 sibling, 1 reply; 26+ messages in thread
From: Hao-yang Wang @ 2005-08-24  1:24 UTC (permalink / raw)
  To: caml-list


>Suppose you want to evaluate a curried function call in left-to-right
>order:
>f e1 e2 e3 e4
>
>You must evaluate f first, then e1.  Then you must apply f to e1, giving
>a new function g1.  Then you must evalue e2, then apply f1 to e2, giving
>f2, etc.

It seems to me that as long as evaluate f the last, we are ok. We can 
specify the evaluation order of the _parameters_ left-to-right (i.e., e1 
then e2, e3, e4, and finally f), without running into the efficiency 
problem.

Cheers,
Hao-yang Wang 



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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-24  1:24   ` Hao-yang Wang
@ 2005-08-24 11:33     ` Damien Doligez
  2005-08-24 14:39       ` Christophe Raffalli
  0 siblings, 1 reply; 26+ messages in thread
From: Damien Doligez @ 2005-08-24 11:33 UTC (permalink / raw)
  To: caml-list


On Aug 24, 2005, at 03:24, Hao-yang Wang wrote:


>> Suppose you want to evaluate a curried function call in left-to-right
>> order:
>> f e1 e2 e3 e4
>>
>> You must evaluate f first, then e1.  Then you must apply f to e1,  
>> giving
>> a new function g1.  Then you must evalue e2, then apply f1 to e2,  
>> giving
>> f2, etc.
>>
>>
>
> It seems to me that as long as evaluate f the last, we are ok.
>

Yes.


> We can specify the evaluation order of the _parameters_ left-to-right
> (i.e., e1 then e2, e3, e4, and finally f), without running into the
> efficiency problem.
>

No, that is a contradiction.  f is an arbitrary expression of the  
language,
for example (g e0), so the code above might well be in fact:

   g e0 e1 e2 e3 e4

Now, if you evaluate f last, you are obviously not evaluating the  
arguments
in left-to-right order, since you evaluate e0 after the others.  In  
order to
stay consistent, you have to evaluate them in right-to-left order.

In fact, when all your functions are curried there are only two possible
choices: evaluate the function first, or the argument first.  There is
no such thing as a multi-argument function application.  Evaluating f
last forces you to evaluate the arguments in right-to-left order in
expressions like the above.

-- Damien



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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-24 11:33     ` [Caml-list] " Damien Doligez
@ 2005-08-24 14:39       ` Christophe Raffalli
  2005-08-24 15:47         ` Berkeley DB Joel Reymont
  2005-08-24 16:08         ` [Caml-list] Re: Parameter evaluation order brogoff
  0 siblings, 2 replies; 26+ messages in thread
From: Christophe Raffalli @ 2005-08-24 14:39 UTC (permalink / raw)
  To: Damien Doligez; +Cc: caml-list


If you really want left-to-right evaluation order in ocaml, use camlp4 
to change the syntax with a postfix function application (with the 
argument to the left).

That will be homogenous with type application !

:-)

or with a right-associtive operator if you do not like camlp4:

# let (@) x f = f x
val ( @ ) : 'a -> ('a -> 'b) -> 'b = <fun>
# 1 @ 2 @ (+)
- : int = 3


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

* Berkeley DB
  2005-08-24 14:39       ` Christophe Raffalli
@ 2005-08-24 15:47         ` Joel Reymont
  2005-08-24 16:08         ` [Caml-list] Re: Parameter evaluation order brogoff
  1 sibling, 0 replies; 26+ messages in thread
From: Joel Reymont @ 2005-08-24 15:47 UTC (permalink / raw)
  To: caml-list

Folks,

How do I find out if my version of OCaml was built with Berkeley DB  
(SleepyCat) support?

Alternatively, how do I build OCaml from the source to support BDB?  
This is based on my understanding that BDB support is built-in since  
I'm not able to find any BDB packages for OCaml more recent than 2002.

     Thanks, Joel

--
http://wagerlabs.com/uptick




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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-24 14:39       ` Christophe Raffalli
  2005-08-24 15:47         ` Berkeley DB Joel Reymont
@ 2005-08-24 16:08         ` brogoff
  2005-08-24 20:05           ` Christophe Raffalli
  1 sibling, 1 reply; 26+ messages in thread
From: brogoff @ 2005-08-24 16:08 UTC (permalink / raw)
  To: Christophe Raffalli; +Cc: Damien Doligez, caml-list

On Wed, 24 Aug 2005, Christophe Raffalli wrote:
> If you really want left-to-right evaluation order in ocaml, use camlp4
> to change the syntax with a postfix function application (with the
> argument to the left).
>
> That will be homogenous with type application !
>
> :-)

Alas, it doesn't help with the evaluation of order of constructors,
which is where I'd find left-to-right most helpful. One of those places
where I think SML is better, even though I usually favor efficiency
over elegance.

-- Brian


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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-24 16:08         ` [Caml-list] Re: Parameter evaluation order brogoff
@ 2005-08-24 20:05           ` Christophe Raffalli
  2005-08-24 20:25             ` brogoff
  0 siblings, 1 reply; 26+ messages in thread
From: Christophe Raffalli @ 2005-08-24 20:05 UTC (permalink / raw)
  To: brogoff; +Cc: caml-list

brogoff a écrit :
> On Wed, 24 Aug 2005, Christophe Raffalli wrote:
> 
>>If you really want left-to-right evaluation order in ocaml, use camlp4
>>to change the syntax with a postfix function application (with the
>>argument to the left).
>>
>>That will be homogenous with type application !
>>
>>:-)
> 
> 
> Alas, it doesn't help with the evaluation of order of constructors,
> which is where I'd find left-to-right most helpful. One of those places
> where I think SML is better, even though I usually favor efficiency
> over elegance.
> 
Anyway, I always found that the application of constructor has a syntax 
to near the syntax of function application:

f (x,y) and A (x,y) are both meaningfull ...

I would prefer square bracket for constructor application, mandatory 
even for unary constructor (and maybe also constant constructor then you 
can lift the restriction about capital letter)

> -- Brian
> 


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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-24 20:05           ` Christophe Raffalli
@ 2005-08-24 20:25             ` brogoff
  2005-08-24 20:53               ` Jon Harrop
       [not found]               ` <430CE193.9000805@univ-savoie.fr>
  0 siblings, 2 replies; 26+ messages in thread
From: brogoff @ 2005-08-24 20:25 UTC (permalink / raw)
  To: Christophe Raffalli; +Cc: caml-list

On Wed, 24 Aug 2005, Christophe Raffalli wrote:
> Anyway, I always found that the application of constructor has a syntax
> to near the syntax of function application:
>
> f (x,y) and A (x,y) are both meaningfull ...
>
> I would prefer square bracket for constructor application, mandatory
> even for unary constructor (and maybe also constant constructor then you
> can lift the restriction about capital letter)

The examples that bother me most are record constructors, where I want to
read structured data from a file into a record. And of course :: (which is
just sugar) too.

If it were just functions, it would be less annoying, but left to right is
less surprising.

It's a fun topic to chat about, but if you were allowed one change in the
language, surely this wouldn't be it? :-)

-- Brian


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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-24 20:25             ` brogoff
@ 2005-08-24 20:53               ` Jon Harrop
       [not found]               ` <430CE193.9000805@univ-savoie.fr>
  1 sibling, 0 replies; 26+ messages in thread
From: Jon Harrop @ 2005-08-24 20:53 UTC (permalink / raw)
  To: caml-list

On Wednesday 24 August 2005 21:25, brogoff wrote:
> > I would prefer square bracket for constructor application, mandatory
> > even for unary constructor (and maybe also constant constructor then you
> > can lift the restriction about capital letter)

It would be nice if variant constructors were functions (as they are in SML, 
IIRC). So you could do this:

# type num = Int of int | Float of float;;
type num = Int of int | Float of float
# List.map Int [1; 2; 3];;
- : num list = [Int 1; Int 2; Int 3]

Rather than having to do "List.map (fun i -> Int i) ...". That wouldn't work 
with polymophic variants though, at least not trivially.

If variant constructors always accepted a single, tuple argument could it not 
be optimised away in most cases? Also, could constructors be curried instead 
of using tuples (or syntax that looks like tuples)?

> The examples that bother me most are record constructors, where I want to
> read structured data from a file into a record. And of course :: (which is
> just sugar) too.

Yes. It would be nice if (fun h t -> h::t) could be written infix as ( :: ), 
as operators are. In fact, couldn't that be added without breaking backward 
compatibility?

> It's a fun topic to chat about, but if you were allowed one change in the
> language, surely this wouldn't be it? :-)

Good question. :-)

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


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

* Re: [Caml-list] Re: Parameter evaluation order
       [not found]               ` <430CE193.9000805@univ-savoie.fr>
@ 2005-08-26  9:53                 ` Christophe Raffalli
  2005-08-26 10:10                   ` Jon Harrop
  0 siblings, 1 reply; 26+ messages in thread
From: Christophe Raffalli @ 2005-08-26  9:53 UTC (permalink / raw)
  To: Christophe Raffalli, caml-list



 >
 > The examples that bother me most are record constructors, where I want to
 > read structured data from a file into a record. And of course :: 
(which is
 > just sugar) too.
 >

I did not know and completely agree with you:

# type test = { a : int; b : int }
type test = { a : int; b : int; }
# { a = (print_string "a"; 1); b = (print_string "b"; 2)};;
ba- : test = {a = 1; b = 2}

This looks strange, because the semicolumn is used both to specify order 
evaluation left-to-right in sequence and right-to-left in record.

And the pb of function application is not there, you could evaluate with 
the same efficiency record in any order, you know the number of 
arguments and what you should do with them at compile time.

Moreover, if you want to unify record and modules ... then you have no 
choice, no body wants right-to-left (I should say bottom-to-top :-)
evaluation order in modules :-)




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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-26  9:53                 ` Christophe Raffalli
@ 2005-08-26 10:10                   ` Jon Harrop
  2005-08-26 12:09                     ` Christophe Raffalli
  0 siblings, 1 reply; 26+ messages in thread
From: Jon Harrop @ 2005-08-26 10:10 UTC (permalink / raw)
  To: caml-list

On Friday 26 August 2005 10:53, Christophe Raffalli wrote:
> This looks strange, because the semicolumn is used both to specify order
> evaluation left-to-right in sequence and right-to-left in record.

I haven't checked but it is probably undefined, rather than right-to-left in 
records.

Semicolons are used in many places in OCaml's grammar. Would you expect the 
members of a list literal to be evaluated left-to-right, for example?

# [print_endline "1"; print_endline "2"];;
2
1
- : unit list = [(); ()]

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


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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-26 10:10                   ` Jon Harrop
@ 2005-08-26 12:09                     ` Christophe Raffalli
  2005-08-26 12:26                       ` Diego Olivier Fernandez Pons
                                         ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Christophe Raffalli @ 2005-08-26 12:09 UTC (permalink / raw)
  To: Jon Harrop; +Cc: caml-list

Jon Harrop a écrit :
> On Friday 26 August 2005 10:53, Christophe Raffalli wrote:
> 
>>This looks strange, because the semicolumn is used both to specify order
>>evaluation left-to-right in sequence and right-to-left in record.
> 
> 
> I haven't checked but it is probably undefined, rather than right-to-left in 
> records.
> 
> Semicolons are used in many places in OCaml's grammar. Would you expect the 
> members of a list literal to be evaluated left-to-right, for example?
> 
> # [print_endline "1"; print_endline "2"];;
> 2
> 1
> - : unit list = [(); ()]
> 

yes I would ...

In fact, after though, the only place where evalauation order should be 
unspecified or better, specified right-to-left is function application 
and all other case (tuple, variants (and therefore list), should be 
left-to-right.

Let me explain:

- why function should be right-to-left:

because the syntax is somehow wrong, the argument should come first !
A good way to think about it is when you write the operationnal 
semantics of call-by-value

if v is a value then (fun x -> t) v evaluates t[x:=v]

in this sentence we are looking at v first.

Another point: if you use a stack (either to define the semantics or to 
implement), the left most argument should be on the top of the stack and 
therefore pushed last.

Why are most language left-to-right: because nobody wanted to reverse 
the notation of function aplpication :-) (and if you think, the standard 
notation for numbers should also be reversed ... and whe should read 
from right to left, which is what we do when we do an addition with 
paper and pencil)

- why other contructor (tuple, records, variants) should be 
left-to-right: because this is the most natural thing to do, and in fact 
there is no semantical reason to choose one evaluation order or another 
(except for variant constructor if you consider that they are function 
like others). (except that they are people around the world that writes 
right-to-left or top-to-bottom ... what are the camlp4 guys doing for 
this poor people ;-)

- why should the evaluation order be specified: this is needed if you 
want to formally reason about programs ... as far as I know. I had like 
to find a system where I can prove programs in call-by-value whatever 
evaluation order they use ... but I do not know how to do that, without 
proving programs for all the possible evaluation order as soon as the 
argument have side effect which is too much.

- Yes, this is a pity since you may want the compiler to interleave the 
code of the various arguments to fill the pileline. But I think doing 
this when the code has no side effect is enough (like with arithmetic 
expression in a + b + c, d + e + f).




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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-26 12:09                     ` Christophe Raffalli
@ 2005-08-26 12:26                       ` Diego Olivier Fernandez Pons
  2005-08-26 16:48                         ` Christophe Raffalli
  2005-08-26 12:36                       ` Ville-Pertti Keinonen
  2005-08-26 22:58                       ` skaller
  2 siblings, 1 reply; 26+ messages in thread
From: Diego Olivier Fernandez Pons @ 2005-08-26 12:26 UTC (permalink / raw)
  To: Christophe Raffalli; +Cc: caml-list

    Bonjour,

> why should the evaluation order be specified: this is needed if you
> want to formally reason about programs ... as far as I know.

Could you elaborate more on this ?

I see the evaluation order in Caml more as a compiler optimization
problem that a semantic one. If I need a specific evaluation order, I
just sequencialize my program explicitelly.

        Diego Olivier


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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-26 12:09                     ` Christophe Raffalli
  2005-08-26 12:26                       ` Diego Olivier Fernandez Pons
@ 2005-08-26 12:36                       ` Ville-Pertti Keinonen
  2005-08-26 14:17                         ` Fernando Alegre
  2005-08-26 17:00                         ` Christophe Raffalli
  2005-08-26 22:58                       ` skaller
  2 siblings, 2 replies; 26+ messages in thread
From: Ville-Pertti Keinonen @ 2005-08-26 12:36 UTC (permalink / raw)
  To: Christophe Raffalli; +Cc: Jon Harrop, caml-list

Christophe Raffalli wrote:

> Jon Harrop a écrit :

>> Semicolons are used in many places in OCaml's grammar. Would you 
>> expect the members of a list literal to be evaluated left-to-right, 
>> for example?

> yes I would ...

An OCaml list is built starting with the tail.  Left-to-right evaluation 
could end up using huge amounts of temporaries.

Consider an explicit implementation of lists:

type 'a list = Cons of 'a * 'a list | Nil

Now, you'd write the list [ a; b; c; d ] (where a, b, c and d could be 
complex expressions) as

Cons (a, Cons (b, Cons (c, (Cons (d, Nil)))))

You need to have Cons (d, Nil) before you can construct Cons (c, ...) 
etc.  It's the innermost expression, so evaluating it first makes sense 
in any sensible evaluation order.


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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-26 12:36                       ` Ville-Pertti Keinonen
@ 2005-08-26 14:17                         ` Fernando Alegre
  2005-08-26 17:00                         ` Christophe Raffalli
  1 sibling, 0 replies; 26+ messages in thread
From: Fernando Alegre @ 2005-08-26 14:17 UTC (permalink / raw)
  To: Ville-Pertti Keinonen; +Cc: caml-list

On Fri, Aug 26, 2005 at 03:36:31PM +0300, Ville-Pertti Keinonen wrote:

> Consider an explicit implementation of lists:
> 
> type 'a list = Cons of 'a * 'a list | Nil
> 
> Now, you'd write the list [ a; b; c; d ] (where a, b, c and d could be 
> complex expressions) as
> 
> Cons (a, Cons (b, Cons (c, (Cons (d, Nil)))))
> 
> You need to have Cons (d, Nil) before you can construct Cons (c, ...) 
> etc.  It's the innermost expression, so evaluating it first makes sense 
> in any sensible evaluation order.


Ignoring efficiency concerns, may I suggest that the correct way to
build lists is by appending elements, not prepending them:

# let append (element,list) = list @ [element];;
val append : 'a * 'a list -> 'a list = <fun>
# append('d', append('c', append('b', append('a', []))));;
- : char list = ['a'; 'b'; 'c'; 'd']

This will evaluate in the right order.

Fernando


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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-26 12:26                       ` Diego Olivier Fernandez Pons
@ 2005-08-26 16:48                         ` Christophe Raffalli
  2005-08-27 15:33                           ` Christophe TROESTLER
  0 siblings, 1 reply; 26+ messages in thread
From: Christophe Raffalli @ 2005-08-26 16:48 UTC (permalink / raw)
  To: Diego Olivier Fernandez Pons; +Cc: caml-list

Diego Olivier Fernandez Pons a écrit :
>     Bonjour,
> 
> 
>>why should the evaluation order be specified: this is needed if you
>>want to formally reason about programs ... as far as I know.
> 
> 
> Could you elaborate more on this ?
> 
> I see the evaluation order in Caml more as a compiler optimization
> problem that a semantic one. If I need a specific evaluation order, I
> just sequencialize my program explicitelly.
> 

Let us say you want to prove a program using references ...
one possible way is to translate is automatically in a purely functional 
program using a state monad ... then you need to specify the evaluation 
order to define the translation of

let x = f a_1 ... a_n in

which could approximately be (x' denotes the translation of x) ans s 
denotes the states holding the map table assigning values to addresses

let s,a_n  = a'_n s in
let s,a_(n-1) = a'_(n-1) s in
..
let s,a_1 = a'_1 s in
let s,x = f' s a_1 ... a_n in

to define this translation, you need to know the evaluation order and it 
is not reasonnable to
assume that the program you want to prove if fully sequentialized (and 
if you want to force sequentialized program then you should only allow 
variables as function arguments in the language definition ;-).

Remark: clearly, a good proof system should not show the monadic 
translation and hide it behind the scene ... but  such a system for full 
ML does not exist yes (as far as I know).


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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-26 12:36                       ` Ville-Pertti Keinonen
  2005-08-26 14:17                         ` Fernando Alegre
@ 2005-08-26 17:00                         ` Christophe Raffalli
  1 sibling, 0 replies; 26+ messages in thread
From: Christophe Raffalli @ 2005-08-26 17:00 UTC (permalink / raw)
  To: Ville-Pertti Keinonen; +Cc: Jon Harrop, caml-list

Ville-Pertti Keinonen a écrit :

 > Christophe Raffalli wrote:
 >
 >> Jon Harrop a écrit :
 >
 >
 >
 >>> Semicolons are used in many places in OCaml's grammar. Would you 
expect the members of a list literal to be evaluated left-to-right, for 
example?
 >
 >
 >
 >> yes I would ...
 >
 >
 >
 > An OCaml list is built starting with the tail.  Left-to-right 
evaluation could end up using huge amounts of temporaries.
 >

This is the same problem as the problem of a tail recursive map 
function, which is important and has reasonable solution.
the only risk is to charge the grey vals list of the GC if the 
evaluation of the list elements allocates enough memory to move 
partially constructed cons cell to the major heap.

But yet I quite agree this is a good point ... but you just need to 
redefine list as

type 'a rlist = Cons of 'a rlist * 'a | Nil

;-)

anyway one of the data type list or rlist as an efficiency problem 
whatever evaluation order you choose.

May be the good evaluation order for variants is recursive arguments 
last ? Or one should let the user choose ?

It is strange to note that records are less problematic since you can 
permutte the field to choose yourself the evaluation order ...

may be variant should have only one argument and list should be

type 'a record_list = Cons of { car : 'a; cdr : 'a list } | Nil



 > Consider an explicit implementation of lists:
 >
 > type 'a list = Cons of 'a * 'a list | Nil
 >
 > Now, you'd write the list [ a; b; c; d ] (where a, b, c and d could 
be complex expressions) as
 >
 > Cons (a, Cons (b, Cons (c, (Cons (d, Nil)))))
 >
 > You need to have Cons (d, Nil) before you can construct Cons (c, ...) 
etc.  It's the innermost expression, so evaluating it first makes sense 
in any sensible evaluation order.


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

* Re: [Caml-list] Parameter evaluation order
  2005-08-20  9:12 ` [Caml-list] " Alain Frisch
@ 2005-08-26 17:53   ` "Márk S. Zoltán"
  0 siblings, 0 replies; 26+ messages in thread
From: "Márk S. Zoltán" @ 2005-08-26 17:53 UTC (permalink / raw)
  To: caml-list

First of all, thank you for your answers. I thought a bit about this 
stuff - took a while. For reasons I am too embarrassed to explain, I 
prefer to answer a number of posts in one reply.

Alain Frisch wrote:

>
>It is, but your conclusion about left-to-right evaluation order is
>wrong. It's just that the binary application operator evaluates first
>its second argument (the function's argument), then its first argument
>(the functional value), and finally applies the function to the
>argument. An application (e1 e2) is semantically equivalent to:  (let y
>= e2 in let x = e1 in x y). Hence you get right-to-left evaluation order
>(but this is not specified).
>
>-- Alain
>  
>
I think I have to retract my equation completely: right now I do not see 
how *any* evaluation order would be implied by currying + strictness + 
side effects at all. Alain, in your model right-to-left evaluation is a 
consequence of defining (e1 e2) as you do; if it was defined to be (let 
x = e1 in let y = e2 in x y), we would have left-to-right evaluation. So 
the evaluation order is introduced by the definition of the functional 
application, not by strictness, currying etc.

I still wonder why did I implicitly assume this latter definition for 
function application. It seemed so straightforward, and it is also the 
order in which application of curried functions is usually explained 
(the explanation proceeds this way, it does not ever say that the actual 
ordering is also left-to-right). Sorry, guys.


Damien Doligez wrote:

> The problem (and historical reason for OCaml's unspecified order) is  
> that
>
> currying + side-effects + left-to-right evaluation order => inefficiency

That line of reasoning is fine with me, as I would not make use of a 
declared parameter evaluation order anyway, while I constantly rely on 
the performance of OCaml. Whoever relies on parameter evaluation order 
is probably capable of committing other hideous crimes, too.


brogoff wrote:

>It's a fun topic to chat about, but if you were allowed one change in the
>language, surely this wouldn't be it?  :-) 
>
Absolutely so. Tail recursion modulo cons is more important.

Regards

    M-






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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-26 12:09                     ` Christophe Raffalli
  2005-08-26 12:26                       ` Diego Olivier Fernandez Pons
  2005-08-26 12:36                       ` Ville-Pertti Keinonen
@ 2005-08-26 22:58                       ` skaller
  2 siblings, 0 replies; 26+ messages in thread
From: skaller @ 2005-08-26 22:58 UTC (permalink / raw)
  To: Christophe Raffalli; +Cc: Jon Harrop, caml-list

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

On Fri, 2005-08-26 at 14:09 +0200, Christophe Raffalli wrote:

> - why should the evaluation order be specified: this is needed if you 
> want to formally reason about programs ... 

Indeterminate order is just fine for reasoning: there is no need
for a system to be fully deterministic to reason about it,
you just end up with sets of possible results instead of 
a unique one.

You can assume determinism and proceed, noting where such
assumptions matter and reporting this as a coding 'bug'
to the programmer. Or, you can make deductions based
on the assumption the programmer knew what they were
doing.

Considering this case:

[print_endline "1"; print_endline "2"];;

it is NOT clear immediately the non-determinism matters:
certainly there are two possible results, but who said
that one is not doing:

ocaml < funny_code | sort

This issue arose on the Alioth Shootout with floating point
tests where various codes generated nice ray traced images
from Jon Harrops test .. but the actual numbers were slightly
different .. what matters is how the human eye sees the
output image, determinism was only required for an artificial
reason.

-- 
John Skaller <skaller at users dot sourceforge dot net>


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: [Caml-list] Re: Parameter evaluation order
  2005-08-26 16:48                         ` Christophe Raffalli
@ 2005-08-27 15:33                           ` Christophe TROESTLER
  0 siblings, 0 replies; 26+ messages in thread
From: Christophe TROESTLER @ 2005-08-27 15:33 UTC (permalink / raw)
  To: O'Caml Mailing List

On Fri, 26 Aug 2005, Christophe Raffalli <christophe.raffalli@univ-savoie.fr> wrote:
> 
> Remark: clearly, a good proof system should not show the monadic 
> translation and hide it behind the scene ...

Shouldn't a good proof system show the code to be correct regardless
of the evaluation order of function args, records,...?  After all,
different evaluation orders may be interesting on different platforms
and I think programs that rely on the evaluation order (say) of
functions arguments to be correct are fragile -- they have a great
potential to be broken at the first maintenance.

On Fri, 26 Aug 2005, Fernando Alegre <fernando@cc.gatech.edu> wrote:
> 
> Ignoring efficiency concerns, may I suggest that the correct way to
> build lists is by appending elements, not prepending them:
> 
> # append('d', append('c', append('b', append('a', []))));;
> - : char list = ['a'; 'b'; 'c'; 'd']

It is not.  You have to respect their recursive definition, from which
it is clear that "append" is not a primitive operation.  The data
structure that you contruct with "append" and deconstruct with "head"
is a FIFO queue.

I've been skimming through the discussion and basically I do not
understand you guys who want a given evaluation order for function
application, constructors,...  First there is a way of imposing
evaluation order of expressions if you need it and moreover, you are
using a functional language which emphasizes immutability for which
evaluation order does not matter...

My 2¢,
ChriS


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

end of thread, other threads:[~2005-08-27 17:39 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-08-19 22:21 Parameter evaluation order "Márk S. Zoltán"
2005-08-20  9:12 ` [Caml-list] " Alain Frisch
2005-08-26 17:53   ` "Márk S. Zoltán"
2005-08-22 16:50 ` Damien Doligez
2005-08-23  7:12   ` skaller
2005-08-23 11:29     ` Damien Doligez
2005-08-23 13:34       ` Igor Pechtchanski
2005-08-23 19:52         ` Damien Doligez
2005-08-24  1:24   ` Hao-yang Wang
2005-08-24 11:33     ` [Caml-list] " Damien Doligez
2005-08-24 14:39       ` Christophe Raffalli
2005-08-24 15:47         ` Berkeley DB Joel Reymont
2005-08-24 16:08         ` [Caml-list] Re: Parameter evaluation order brogoff
2005-08-24 20:05           ` Christophe Raffalli
2005-08-24 20:25             ` brogoff
2005-08-24 20:53               ` Jon Harrop
     [not found]               ` <430CE193.9000805@univ-savoie.fr>
2005-08-26  9:53                 ` Christophe Raffalli
2005-08-26 10:10                   ` Jon Harrop
2005-08-26 12:09                     ` Christophe Raffalli
2005-08-26 12:26                       ` Diego Olivier Fernandez Pons
2005-08-26 16:48                         ` Christophe Raffalli
2005-08-27 15:33                           ` Christophe TROESTLER
2005-08-26 12:36                       ` Ville-Pertti Keinonen
2005-08-26 14:17                         ` Fernando Alegre
2005-08-26 17:00                         ` Christophe Raffalli
2005-08-26 22:58                       ` skaller

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