Can clojure evaluate a chain of mixed arity functions and return a partial function if needed?

arity, clojure, combinators, lambda, partial

Solution

I'm not sure I fully understand what you are trying to do, but the `comp` function is useful for doing this kind of "function chaining" you seem to be talking about. For example:

user> ((comp vec rest list) 1 2 3 4 5)
=> [2 3 4 5]

Which is equivalent to:

user> (vec (rest (list 1 2 3 4 5)))
=> [2 3 4 5]

In your case, if you have the list `(I K S I I)`, and you want to evaluate it as `(I (K (S (I (I)))))`, I would use `(reduce comp ...)`, but you could also use `(apply comp ...)`.

user> ((reduce comp [vec rest list]) 1 2 3 4 5)
=> [2 3 4 5]
user> ((apply comp [vec rest list]) 1 2 3 4 5)
=> [2 3 4 5]

You may also be interested in the `->` or `->>` macros. These macros nest their arguments sequentially into the next arguments. The `->` macro will nest into the first position of the next expression, whereas the `->>` macro will nest into the last position of the next expression. If the "next thing" is a function, both will behave the same, and form an expression of `(function nested-things-so-far)`, and continue along.

Really, examples are best:

(-> 1 (+ 10) (- 100) inc)
;//Expands to...
(inc (- (+ 1 10) 100))
;//Evaluating in the REPL...
user> (-> 1 (+ 10) (- 100) inc)
=> -88

(->> 1 (+ 10) (- 100) inc)
;//Expands to...
(inc (- 100 (+ 10 1)))
;//Evaluating in the REPL...
user> (-> 1 (+ 10) (- 100) inc)
=> 90

However, it seems more like you want to do something involving auto-currying (although, again, I don't think I fully understand), and for that I don't know of anything pre-existing built-in way.

Problem

Suppose you have three functions of arity 1, 2 and 3 as below: ``` (defn I [x] x) (defn K [x y] x) (defn S [x y z] (x z (y z))) ``` Does clojure have an evaluation function or idiom for evaluating: ``` (I K S I I) as (I (K (S (I (I))))) ``` returning a parital function of arity 2? I am considering creating a macro that can take the simple function definitions above and expand them to multi-arity functions that can return partial results. I would not want to create the macro if there is already a built in or idiomatic way to accomplish this. Here is what the expanded macros would like for the above functions: ``` (defn I ([x] I x) ([x & more] (apply (I x) more))) (defn K ([x] (partial K x)) ([x y] x) ([x y & more] (apply (K x y) more))) (defn S ([x] (partial S x)) ([x y] (partial S x y)) ([x y z] (x z (y z))) ([x y z & more] (apply (S x y z) more))) ```

Original source