Article View: comp.lang.functional
Article #666Re: Why curry? (Re: Why functional languages?)
From: Markus Freericks
Date: Wed, 07 Oct 1992 09:56
Date: Wed, 07 Oct 1992 09:56
102 lines
5779 bytes
5779 bytes
In article <1992Oct6.141724.29356@kth.se> kff@dentex.tds.kth.se (Karl-Filip Faxen) writes: In article <TMB.92Oct4181821@arolla.idiap.ch>, tmb@arolla.idiap.ch (Thomas M. Br euel) writes: |> |> Why _do_ people continue to use curried syntax when they just want a |> function with several arguments? It's difficult to optimize for the |> compiler, That is not correct (and I should know, I'm writing a Haskell compiler :-). First, it is not particularly difficult to generate good code for calls to curried functions (that is, functions with types like (a -> b -> c -> d -> e)). Every function is represented as a lambda-expression (e.g. (\x.\y.\z. e)), and in a compiled graph reduction implementation (e.g. the G machine and its derivates) the number of nested lambda bindings around the body of the function (3 in this case) gives the precise number of arguments that the compiled code for the function needs to in order to execute (partial applications are represented as a thunk (or closure) containing a pointer to the code of the supercombinator and a list of the (still to few) arguments it has been applied to). Now, if we have a simple, first order function application (where the applied function is a known supercombinator) we can look up the number of outermost lambdas, check if the function is applied with the right number of arguments and call an entrypoint that uses some efficient calling convention. Thus the curried style of function definition carries no additional cost in itself; it is calling "unknown" functions that cost, and that cost is regardless of the syntax used when defining the function. Your argumentation is based on a graph reduction implementation. I would think that such are only feasible for lazy languages, which SML (which started the thread) is not. Otherwise, you are of course quite right. Second, the tupling style also needs to be optimized, or you have to allocate the tuples explicitly in the heap and then explicitly destructure them immediately afterwards. This can of course be done, but it is not any simpler than the above mentioned optimization for curried functions (I think :-). Perhaps some of the SML/NJ implementors can comment on this? Well, if you have a CPS-based compiler, function call arguments will usually be held in registers, only closures have to be created on the heap (or on the stack, if they provably don't escape). And in such an environment, tupling is much cheaper! (Again, it is of course true that a very naive approach would allocate tuples as data objects on the heap.) |> it gives uninformative type signatures (is "'a -> 'a -> 'a" |> intended to be a function of one argument returning a function, or is |> it intended to be a function of two arguments returning a "'a"?), It is both. You are free to apply it to two arguments to get a "'a" in one place and apply it to one argument and get a function with type "'a -> 'a" that you e.g. map over a "'a list" in another place. I do these things all the time. Well, in my SML programs (I am writing a partial evalutor) i tend to have functions of 4-5 parameters, and missing parameters are one of the most typical typing errors I make. Of course, type check would catch most of these in a currying language, too. Oh yes: a lot of these are functions that are *never* applied partially. |> it's not what most programmers are used to, Sorry about this, but I _have_ to remind you that most programmers are not used to either Haskell or SML at all, but rather to COBOL, BASIC and FORTRAN. The question is: What is easiest to get used to, and, once gotten used to, most productive? And as that is difficult to measure, this point boils down to a matter of taste, and taste is not to be argued about. Well, for me the question is: does a language *force* me to use curried functions, or does it offer tupled functions, too? For me, tupling is a safety device, a little comparable to typing, that makes it possible to say "this function should be called with so many arguments". A language that does not support this device (or makes it overtly expensive, e.g. by explicitly creating/desctructing tupel objects) lacks a feature that makes life easier. |> and it seems to be difficult to indent automatically as well. In an Emacs mode, perhaps. In a pretty printer, certainly not (I've written one). Has anybody yet written a decent SML emacs mode? The one that comes with SML/NJ is, while not broken, quite irritating at times. Cheers, Karl-Filip Greetings, Markus ------------------------------------------------------------ Make the frequent case fast, and the fast case frequent! -- Markus Freericks | email: mfx@cs.tu-berlin.de TU Berlin Sekr.FR 2-2 | phone: +49-30-314-21390 Franklinstr.28/29 | priv.: +49-30-872523 D-1000 Berlin 10 |"Inertia makes the world go 'round."
Technical Details
Message-ID:
<MFX.92Oct7105619@lenin.cs.tu-berlin.de>Path:
arc1-ca.pugleaf.net!sparky!uunet!haven.umd.edu!darwin.sura.net!spool.mu.edu!umn.edu!math.fu-berlin.de!dct.zrz.tu-berlin.de!cs.tu-berlin.de!lenin!mfxReferences:
<TMB.92Sep28144424@arolla.idiap.ch> <annius.717696151@freyr> <TMB.92Oct4181821@arolla.idiap.ch> <1992Oct6.141724.29356@kth.se>Show Full Headers
Complete Article Headers
Newsgroups: comp.lang.functional Path: arc1-ca.pugleaf.net!sparky!uunet!haven.umd.edu!darwin.sura.net!spool.mu.edu!umn.edu!math.fu-berlin.de!dct.zrz.tu-berlin.de!cs.tu-berlin.de!lenin!mfx From: mfx@cs.tu-berlin.de (Markus Freericks) Subject: Re: Why curry? (Re: Why functional languages?) In-Reply-To: kff@dentex.tds.kth.se's message of Tue, 6 Oct 1992 14:17:24 GMT Message-ID: <MFX.92Oct7105619@lenin.cs.tu-berlin.de> Sender: news@cs.tu-berlin.de Organization: Technical University of Berlin, Germany References: <TMB.92Sep28144424@arolla.idiap.ch> <annius.717696151@freyr> <TMB.92Oct4181821@arolla.idiap.ch> <1992Oct6.141724.29356@kth.se> Date: Wed, 7 Oct 1992 09:56:29 GMT Lines: 102