From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.6.10/8.6.6) id UAA14693 for caml-redistribution; Mon, 20 Nov 1995 20:17:19 +0100 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.6.10/8.6.6) with ESMTP id TAA14384 for ; Mon, 20 Nov 1995 19:07:08 +0100 Received: from margaux.inria.fr (margaux.inria.fr [128.93.8.2]) by concorde.inria.fr (8.7.1/8.6.9) with ESMTP id TAA18133 for ; Mon, 20 Nov 1995 19:07:08 +0100 (MET) Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by margaux.inria.fr (8.6.10/8.6.6) with ESMTP id TAA11526 for ; Mon, 20 Nov 1995 19:07:07 +0100 Received: from ra.abo.fi (ra.abo.fi [130.232.18.2]) by concorde.inria.fr (8.7.1/8.6.9) with SMTP id TAA18127 for ; Mon, 20 Nov 1995 19:07:01 +0100 (MET) Received: from tanichka.abo.fi (root@tanichka.abo.fi [130.232.209.102]) by ra.abo.fi (8.6.10/8.6.10) with ESMTP id UAA02467; Mon, 20 Nov 1995 20:06:06 +0200 Received: from tanichka.abo.fi (jharriso@localhost [127.0.0.1]) by tanichka.abo.fi (8.6.10/8.6.10) with ESMTP id UAA21038; Mon, 20 Nov 1995 20:06:48 +0200 Message-Id: <199511201806.UAA21038@tanichka.abo.fi> To: Jocelyn Serot cc: caml-list@margaux.inria.fr, John Harrison Subject: Re: curried fns In-reply-to: Your message of "Mon, 20 Nov 1995 16:54:06 EET." <199511201556.QAA15838@concorde.inria.fr> Date: Mon, 20 Nov 1995 20:06:42 +0200 From: John Harrison Sender: weis | 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 =========================================================================