currying in clojure for fixed number of arg functions

3,163 views
Skip to first unread message

Sunil S Nandihalli

unread,
Dec 17, 2010, 3:41:38 PM12/17/10
to clo...@googlegroups.com
Hello everybody,
 I remember that the key reasoning for not supporting currying in clojure was to be able to have variable number of arg functions.. So, I just thought a bit and realized that it should be possible to do that for fixed arity functions .. and then wrote the following macro to define a curry-able fixed-number-of-argument-function 


(def-curry-fn f [a b c d]
  (+ a b c d))

((f 1) 2 3 4)  => 10
(((f 1 2) 3) 4) => 10

I just thought of sharing it with everybody. Would love to hear any criticisms you may have.

Thanks for reading, 
Sunil

Eric Schulte

unread,
Dec 17, 2010, 4:32:40 PM12/17/10
to clo...@googlegroups.com
Hi Sunil,

This is already possible using `partial' function in clojure core, which
also works for variable arity functions, e.g.

(map (partial reduce +) [[1 2 3 4] [5 6 7 8]])

Best -- Eric

Sunil S Nandihalli

unread,
Dec 17, 2010, 8:51:19 PM12/17/10
to clo...@googlegroups.com
Hi Eric,
 I do know about partial. But what I am saying is that the extra function, partial, is not necessary if the function was created with def-curry-fn....... The function automatically returns a curried version when called with fewer number of arguments than necessary.... like it happens in haskell..
thanks,
Sunil.

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Sunil S Nandihalli

unread,
Dec 17, 2010, 9:00:58 PM12/17/10
to clo...@googlegroups.com
On Sat, Dec 18, 2010 at 7:21 AM, Sunil S Nandihalli <sunil.na...@gmail.com> wrote:
Hi Eric,
 I do know about partial. But what I am saying is that the extra function, partial, is not necessary if the function was created with def-curry-fn....... The function automatically returns a curried version when called with fewer number of arguments than necessary.... like it happens in haskell..
thanks,
Sunil.

On Sat, Dec 18, 2010 at 3:02 AM, Eric Schulte <schult...@gmail.com> wrote:
Hi Sunil,

This is already possible using `partial' function in clojure core, which
also works for variable arity functions, e.g.

(map (partial reduce +) [[1 2 3 4] [5 6 7 8]])

Best -- Eric

Sunil S Nandihalli <sunil.na...@gmail.com> writes:

> Hello everybody,
>  I remember that the key reasoning for not supporting currying in clojure
> was to be able to have variable number of arg functions.. So, I just thought
> a bit and realized that it should be possible to do that for fixed arity
> functions .. and then wrote the following macro to define a curry-able
> fixed-number-of-argument-function
>
> https://gist.github.com/745654
>
If the following was defined as
(defn f [a b c d]
  (+ a b c d)) 
> (def-curry-fn f [a b c d]
>   (+ a b c d))
>
> ((f 1) 2 3 4)  => 10
the above s-expression using partial would become ...

((partial f 1) 2 3 4) => 10 
> (((f 1 2) 3) 4) => 10

and ((partial (partial f 1 2) 3) 4) => 10 instead of (((f 1 2) 3) 4).. 

((((f 1) 2) 3) 4) => 10
would become
((partial (partial (partial f 1) 2) 3) 4) => 10 .....

I know there is no real practical utility .. .. it was just something I wrote for fun.. and thought of sharing it ...
Sunil. 

Robert McIntyre

unread,
Dec 18, 2010, 1:43:16 AM12/18/10
to clo...@googlegroups.com
I think your work is a wonderful idea. I've been wanting to do this
myself for some time.
Thanks for actually doing it instead of just thinking about it.

I have some humble thoughts/suggestions after reading your code; I'd
love to hear what you think about these points:

1. I think that auto-currying itself should be a higher order
function, which a macro then makes easier to use.
2. Your def-curry-fn doesn't allow for easy embedding of metadata like
defn does; it could take advantage of defn from core for all that.
3. Your def-curry-fn is similar in spirit to defn-memo from
clojure.contrib.def, but it's hard to combine it with that macro to
get both effects (both curried and memoized) I feel like this is
asking for a higher level of abstraction of "apply this unitary
higher-order transform to the following definition" than making a
defn-"higher-order-transform" macro for every transform those type of
functions are called decorators in some other languages.


I've sketched out a hopefully enhanced version of your code here:
https://gist.github.com/746185

While writing it, I found it convenient to extend the domain of
partial to include a single argument.
i.e. (= (partial f) f)
I think it might be a good enhancement of the partial function, as it
logically flows from the other airties.
Do people think it would be a good patch for core?

Please tell me what you think of my code :) All criticisms are
welcome; I too am still learning.

Sincerely,
--Robert McIntyre


On Fri, Dec 17, 2010 at 9:00 PM, Sunil S Nandihalli

Sunil S Nandihalli

unread,
Dec 18, 2010, 3:15:35 AM12/18/10
to clo...@googlegroups.com
 very cool implementation .. Something tells me that you didn't leave your python background behind.. :)
Sunil.

Eric Schulte

unread,
Dec 18, 2010, 1:19:02 PM12/18/10
to clo...@googlegroups.com
Ah, my apologies,

Thanks for clarifying, I should have looked more closely at your code
before responding. That is indeed a very nice idea (and an aspect of
Haskell that I sorely miss in Clojure).

I could see myself wanting to use this on a namespace level, e.g. have
all functions defined in a namespace curryable. I'll have to look at
your code when I have some time. I wonder if something like this can be
practical in a language where all functions aren't unary by default.

Thanks -- Eric

>>> clojure+u...@googlegroups.com<clojure%2Bunsu...@googlegroups.com>

Benny Tsai

unread,
Dec 18, 2010, 5:02:43 PM12/18/10
to Clojure
This is very cool!

Taken together with the following projects, Clojure now has some of
the nicest parts of Haskell/ML, IMHO :)

Matchure (pattern matching):
http://spin.atomicobject.com/2010/04/25/matchure-serious-clojure-pattern-matching

Algebraic Data Types:
http://clojure.github.com/clojure-contrib/types-api.html

On Dec 17, 7:00 pm, Sunil S Nandihalli <sunil.nandiha...@gmail.com>
wrote:
> On Sat, Dec 18, 2010 at 7:21 AM, Sunil S Nandihalli <
>
>
>
>
>
>
>
>
>
> sunil.nandiha...@gmail.com> wrote:
> > Hi Eric,
> >  I do know about partial. But what I am saying is that the extra function,
> > partial, is not necessary if the function was created with
> > def-curry-fn....... The function automatically returns a curried version
> > when called with fewer number of arguments than necessary.... like it
> > happens in haskell..
> > thanks,
> > Sunil.
>
> > On Sat, Dec 18, 2010 at 3:02 AM, Eric Schulte <schulte.e...@gmail.com>wrote:
>
> >> Hi Sunil,
>
> >> This is already possible using `partial' function in clojure core, which
> >> also works for variable arity functions, e.g.
>
> >> (map (partial reduce +) [[1 2 3 4] [5 6 7 8]])
>
> >> Best -- Eric
>
> >> clojure+u...@googlegroups.com<clojure%2Bunsu...@googlegroups.com >

Robert McIntyre

unread,
Dec 19, 2010, 12:13:02 PM12/19/10
to clo...@googlegroups.com
What do people think about extending the definition of partial in core
to work on just a single argument?

That is, if you call partial with just a function and no arguments, it
just returns the function.

It seems to follow logically from the other airties.

For a case where this is useful, see https://gist.github.com/746185

Sincerely,
--Robert McIntyre

ka

unread,
Dec 20, 2010, 11:53:52 AM12/20/10
to Clojure
+1 on partial with no args !

I have a doubt: using partial conveys the intent, but with automatic
currying one may get confused between "partial application" &
"function call", no?
Reply all
Reply to author
Forward
0 new messages