Hacker News new | past | comments | ask | show | jobs | submit login

What if we had this:

  (defun foo (a0 a1 &curry a2 a3 &optional a4 ... &rest r) ...)
The &curry keyword would specify that if this fun is called with fewer than four args, it returns a function. If called with fewer than two, an error is signaled; two are required. If more than four are passed, they satisfy the optionals.

Thus (foo 1 2 3) would return a (lambda (&curry a3 &optional ...) ...).

The main disadvantage is that currying macros do this statically, purely at the call site's compile time, without cooperation from the callee.

Of course, this proposal can cheerfully coexist with currying macros.

In a Lisp dialect which can express multiple function signatures, things are more general; you can do the above yourself. You can make your three-arg function have zero, one and two-arg cases which curry.

For that matter, we can do it like this:

  (defun foo (a0 a1 &optional (a2 :curry) (a3 :curry) a4 ...)
    ;; handle a2 or a3 being :curry by returning lambda)
I'm well aware of presence-indicating arguments: (a2 default-val a2-present-p). With this simple :curry convention, we could simplify a semi-automatic implementation. It has a notational advantage.



I expect this to be useful, enough so that I planned on adding it to a (non-CL) language implementation. (But it hasn't happened yet, so I can't report from experience.)

BTW, while everybody in this thread seems to think that partial application is all there is to Haskell style currying, it isn't. Consider

    (defun foo (x) (lambda (y) (+ x y)))
If you can't call this as

    (foo 1 2)
to get 3, you still don't really have currying.


We cannot call that foo as (foo) either, so we have nothing. We have to do something in foo to make currying work. If (foo 1) is required to return a unary function, of course we support (foo 1 2) which passes 2 to that function.

Here is the problem case:

  (defun foo (x)
    (unknown x))
Suppose unknown can return a function of any number of arguments. The developer of foo doesn't know how many. If it returns a five-argument function, you expect the call (foo 1 2 3 4 5 6) to work.

Basically, we can make foo n-ary such that it calls unknown with the first arg, and passes the rest to the function that unknown returns.

A subtlety not mentioned in the thread is that (x) and x are distinct in Lisps. Applying an empty argument list is different from not applying arguments.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: