Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: John Harrison <jharriso@ra.abo.fi>
To: Jocelyn Serot <Jocelyn.Serot@lasmea.univ-bpclermont.fr>
Cc: caml-list@margaux.inria.fr, John Harrison <jharriso@ra.abo.fi>
Subject: Re: curried fns
Date: Mon, 20 Nov 1995 20:06:42 +0200	[thread overview]
Message-ID: <199511201806.UAA21038@tanichka.abo.fi> (raw)
In-Reply-To: Your message of "Mon, 20 Nov 1995 16:54:06 EET." <199511201556.QAA15838@concorde.inria.fr>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 3015 bytes --]



| Could someone please explain the difference(s) between:
|
|         let f x = function y -> y + x;;
|
| and
|
|         let f x y = y + x;;

Those should behave identically, even w.r.t evaluation. The two phrases
"let f x = t[x]" and "let f = fun x -> t[x]" are essentially identical.
However in the example you give below, you do additional computation
after getting the first argument:

| let h x = let z = fact x in fun y -> y + z;;

The evaluation strategy of ML is as follows: to evaluate "f x", first
evaluate "f", then evaluate "x" (to "x'"), then if "f" evaluates to a
lambda expression "\v. t[v]", recursively evaluate "t[x']"; otherwise
stop. Evaluation of "f x y" is, of course, just evaluation of "(f x) y",
so the above scheme means "f x" gets evaluated first. However ML will
*not* evaluate inside lambdas, so applying "\u. \v. t[u,v]" to a single
argument "x" just gives "\v. t[x,v]" and evaluation then stops, even if
the body is independent of v. However your example "h" then permits
further evaluation. (In the above I use "\x. t[x]" for "fun x -> t[x]".)

Of course, in a pure functional language one can safely evaluate inside
lambdas, but in a language like ML where there may be imperative bits
floating around, the distinction is important. Doing the kind of "partial
evaluation" you cite is a very important technique in writing efficient
code. (Having said that, I'm surprised compilers don't try to identify
"non-imperative" parts and evaluate them -- of course one has to be
careful with exceptions -- it's not really any different from constant
folding in C compilers.) Conversely, it can occasionally be useful to
delay evaluation by introducing eta-redexes (i.e. including additional
arguments), in particular when defining higher order functions
recursively. For example given:

  let I x = x;;

  let THEN f g x = g(f x);;
  #infix "THEN";;

  let ORELSE f g x = try f x with _ -> g x;;  (* Sorry, Xavier! *)
  #infix "ORELSE";;

the following will loop when applied:

  let rec REPEAT f = (f THEN (REPEAT f)) ORELSE I;;

whereas this works:

  let rec REPEAT f x = ((f THEN (REPEAT f)) ORELSE I) x;;

Something I sometimes wonder about is which of the following is more
efficient. Perhaps a CAML Light expert can comment.

  let map f =
    let rec mapf l =
      match l with
        [] -> []
      | (x::t) -> let y = f x in y::(mapf t) in
    mapf;;

or

  let rec map f l =
    match l with
      [] -> []
    | (x::t) -> let y = f x in y::(map f t);;

John.

=========================================================================
John Harrison                   | email: jharriso@ra.abo.fi
Åbo Akademi University          | web:   http://www.abo.fi/~jharriso/
Department of Computer Science  | phone: +358 (9)21 265-4049
Lemminkäisenkatu 14a            | fax:   +358 (9)21 265-4732
20520 Turku                     | home:  +358 (9)21 2316132
FINLAND                         | time:  UTC+2:00
=========================================================================




  reply	other threads:[~1995-11-20 19:17 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1995-11-20 15:54 Jocelyn Serot
1995-11-20 18:06 ` John Harrison [this message]
1995-11-21 10:48   ` Pierre Weis
1995-11-20 18:51 Laurent CHENO
1995-11-20 20:32 Fauque UPS
1995-11-21  5:17 Tarizzo Martial

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=199511201806.UAA21038@tanichka.abo.fi \
    --to=jharriso@ra.abo.fi \
    --cc=Jocelyn.Serot@lasmea.univ-bpclermont.fr \
    --cc=caml-list@margaux.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