Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Damien Doligez <damien.doligez@inria.fr>
To: caml-list <caml-list@yquem.inria.fr>
Subject: Re: [Caml-list] Parameter evaluation order
Date: Mon, 22 Aug 2005 18:50:30 +0200	[thread overview]
Message-ID: <254E6767-A097-455B-872B-483725D26744@inria.fr> (raw)
In-Reply-To: <43065B83.6050503@dravanet.hu>

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


  parent reply	other threads:[~2005-08-22 16:50 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-08-19 22:21 "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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=254E6767-A097-455B-872B-483725D26744@inria.fr \
    --to=damien.doligez@inria.fr \
    --cc=caml-list@yquem.inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox