ecoologic
ecoologic

Reputation: 10420

Execute a vector of functions doesn't work when fns are passes as params

This code doesn't work as indended:

(((fn [& fns]
    (fn [& params]
      (reduce #(%2 %1) params fns)))
  rest reverse)
 [1 2 3 4]) ;; => () instead of (3 2 1)

Is there a way to fix it by only change inside #(%2 %1)?

I think this question is equivalent to: How to convert (#<core$rest>) into (rest)?

NOTE: This is my process to solve http://www.4clojure.com/problem/58 I've seen the other solutions but I was curious about this specific implementation.

Upvotes: 2

Views: 73

Answers (1)

Chris Murphy
Chris Murphy

Reputation: 6509

Try just using [params] rather than [& params], so:

(fn [params] (reduce #(%2 %1) params fns))

The [& params] argument was taking a collection [1 2 3 4] and wrapping it again, in a list, giving ([1 2 3 4]) as the seed for your reduce function.

If you wanted to only change inside #(%2 %1) then you would need to unwrap ([1 2 3 4]), but only the first time. You could see if first returned a collection, so (coll? (first %1)), and then call (first %1), otherwise just leave %1 as it is. Seems convoluted and won't work for other input data though.

Upvotes: 4

Related Questions