Is there a way to ignore last parameter in function literal? #( ... %_3 ...)

Recently I needed to pass a function to another function with second parameter ignored. I realized that I can’t use partial and that I need to “pack it” in another function. So I did

(some-fun "foo" #(passed-fun %1 %3)) "bar")

and it worked great.

Then I needed to do that again with different function ignoring second and last arg and I realized that I need to do

(some-fun "foo" (fn [x _ y _] (passed-fun x y)) "bar")

Could you please tell me is there a way to use function literal for this?

Thank you :smiley:

Ralf

But is it a good idea?!

clj> (#(do %3 (+ %1 %2)) 2 4 6)
6

I try to avoid function literals. They feel a bit like a trap to me. I vote for your solution using the fn special form.

2 Likes

Function literals are fine for the cases they fit. This isn’t one of them. The reader basically finds the highest argument number and uses that as the number of parameters. Also, with 4 positional arguments one often considers using named arguments (maps).

1 Like

Not sure if it’s a good idea to rely on this, but in current Clojure, you can use the comment reader macro (#_):

(some-fun "foo" #(passed-fun %1 %3 #_%4)) "bar")

Here is the reader expansion of the above function literal:

user=> (read-string "#(passed-fun %1 %3 #_%4)")
(fn* [p1__4014# p2__4017# p3__4015# p4__4016#] (passed-fun p1__4014# p3__4015#))
3 Likes

I think Stuart Sierra has good advice in these two posts:

3 Likes

Thank you all for suggestions. I understand that some of you are not fan of fn literals but I love them since I don’t have to think about naming parameters.

This is cool. I need to read about reader macro to understand if this is some accidental feature when it comes to function literals. It’s probably not official feature and therefore better to avoid.

Thank you.