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
=========================================================================
next prev parent 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