Anton Harald
Anton Harald

Reputation: 5934

calling a library function of arbitrary name

say there's a library l, which has two functions (a and b).

Calling both functions and merging the results into a vector could be done like this:

(concat (l/a) (l/b))

Is there a way to make this more generic? I tried something like this, but it threw an exception:

(apply concat (map #(l/%)  ['a 'b])) 

of course, this would work:

(apply concat [l/a l/b])

Upvotes: 0

Views: 49

Answers (2)

Lee
Lee

Reputation: 144136

It looks like you want a general way of invoking a function inside a namespace. You can construct a symbol and dereference it to find the functions, then combine the results using mapcat e.g.

(mapcat #((find-var (symbol "l" %))) ["a" "b"])

alternatively you could first find the namespace and use ns-resolve to find the vars e.g.

(let [ns (find-ns 'l)]
   (mapcat #((ns-resolve ns %)) ['a 'b]))

Upvotes: 0

johnbakers
johnbakers

Reputation: 24760

Calling both functions and merging the results into a vector could be done like this: (concat (l/a) (l/b))

No, you will not get a vector. And you will only get a sequence if those functions return sequences. Otherwise, definitely not, you will get a runtime exception with this code and your assumption.

It sounds like you have a bunch of functions and you want to concatenate the results of them all together? There is no need to quote them, just make a sequence of the functions:

[l/a l/b l/c ...]

And use apply with concat as you already are, or use reduce to accumulate values.

Call vec on the result if you need it to be a vector rather than a sequence.

Your other solutions are definitely making your code much much more complex, unnecessary, and difficult to read. (also, you almost never need to quote vars as you are doing)

Upvotes: 1

Related Questions