Hacker News new | ask | show | jobs
by 0PingWithJesus 3458 days ago
I'm not sure I understand what you mean when you say there's no currying in common lisp? If you write functions that are curried then you'll have currying. Am I missing something?
2 comments

Sorry, currying by default. In the ML-inspired languages, unless a function takes a tuple of its arguments it's curried. This doesn't seem to be the case in any of the Lisps I've looked at. You can certainly curry the functions yourself but the language doesn't seem to make that easy.
I'd count ubiquitous currying a design mistake in a dynamically typed language. All your "wrong number of arguments" errors get caught late.

(But the real problem with common lisp is that its version of (+ 2) is the ridiculously verbose (LAMBDA (x) (+ 2 x)) — far too many anonymous functions end up with more boilerplate than content. A decent reader macro might go a long way towards curing curry envy. If I remember correctly, it's [+ 2 _] in Paul Graham's Arc, not bad.)

Using reader macros for syntax is mostly a mistake - with exceptions. The Lisp tradition generally likes to use reader syntax on the level of s-expressions.

If verbose expressions are a problem, normal macros or functions would be sufficient.

    CL-USER 10 > (defmacro rlambda (fn &rest forms)
                  (let ((arg-sym (gensym "ARG-")))
                    `(lambda (,arg-sym)
                       (,fn ,@forms ,arg-sym))))
    RLAMBDA

    CL-USER 11 > (macroexpand-1 `(rlambda + 2))
    (LAMBDA (#:ARG-804) (+ 2 #:ARG-804))
    T
The 'real problem' is that many people have difficulties using and accepting a programmable programming language.
Your "solution" is still more boilerplate than content and befuddles people used to lisp by evaluating in the function namespace an argument in non-function position.

Common Lisp simply can't approach the succinctness and elegance of currying without adding some syntax.

Your resistance is puzzling, btw. You're not having difficulties using and accepting a programmable programming language, are you?

> used to lisp by evaluating in the function namespace an argument in non-function position.

True, macros can confuse people not used to the concept.

For example the DEFUN macro: (defun plus (a b) (+ a b))

'plus' is in the function namespace, even though it is in a non-function position.

Strange, isn't it?

> Common Lisp simply can't approach the succinctness and elegance of currying without adding some syntax.

That's true. But it doesn't even try, because the 'succinctness and elegance' of currying without adding some syntax is a non-goal for Common Lisp. Lisp has always preferred one expression for each function call and over the years it added complex argument lists (variable number of arguments, optional arguments, keyword arguments, ...).

Personally I don't miss things like 'automatic' currying, since they are making the code harder to read (-> currying is not explicitly visible in the source code) and debug.

In Scheme there is the "cut" macro:

    (cut + 2 <>)
GNU Guile specifically has a curried definition syntax:

    (define ((foo x) y)
      (list x y))
https://www.gnu.org/software/guile/manual/html_node/Curried-...

Or you can bind "lambda" to another, shorter identifier.

But anyway, Lisp's goal isn't to be extremely terse, so it doesn't bother me.

Lisp is not about microsyntax and code golf. If you worry about the number of characters and that is "the real problem" with Common Lisp, Perl or J may be a better choice for you.
In Clojure it's #(+ 2 %), pretty compact if cryptic. Actually no reason you couldn't make a reader macro in CL to look similar.
Slightly less cryptic would be (partial + 2).
Partial application and currying are two different things.
That's correct, I'm just responding to the specific case here.
You could make a macro that does the currying for you. You'd have to apply it explicitly, as opposed to ML, where it happens automatically. If you build the macro well, the generated machine code won't look much different from ML, though.