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)))
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:Which is equivalent to:
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 ...)
.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:
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.