# Defining a general function f with slot-holder arguments #1, #2

I am trying to get a general function $$f$$ accept slot-holder arguments #1, #2, where the actual arguments are lists {a1, a2,...} and {b1, b2,....}. I thought that this would involve some combination of the functions "Map" and "Apply" - I have experimented with each function individually (I don't know how to combine them) but so far I have not managed to get the desired results.

1. I work only with "Apply", and this has no problem when the passed-in arguments are just single variables (not lists):

Apply[f[#1, #2] &, {0, 1}]

The outcome is: f[0, 1]

When I try to pass in lists, for example #1 should accept {0,2} and #2 should accept {1,2} to produce a list {f[0,1], f[2,2]}, the output is instead:

f[{0, 2}, {1, 2}]


The code I used is:

   Apply[f[#1, #2] &, {{0, 2}, {1, 2}}]


However, I noticed that if the function is explicitly defined, for example take a simple function like f[#1, #2]=#1+#2, then the output is correct.

Apply[#1 + #2 &, {{0, 2}, {1, 2}}]


which produces:

{1, 4}

1. I also try to use "Map" (or /@), but it only works with a single slot-holder argument. For example

f[#] & /@ {a, b, c, d, e}

gives:

{f[a], f[b], f[c], f[d], f[e]}


but if I put:

f[#1, #2] & /@ {{a, b, c, d, e}, {m, n, p, q, r}}


the result is:

{f[{a, b, c, d, e}, #2], f[{m, n, p, q, r}, #2]}


and not the desired result, which should be:

{f[a,m], f[b,n], f[c,p], f[d,q], f[e,r]}


I would be grateful if anyone could help me with this.

• If you try f @@@ {{0, 2}, {1, 2}} you will get {f[0,2], f[1,2]}. Or, Map[Apply[f], {{0, 2}, {1, 2}}] Apr 8, 2022 at 7:52
• I recommend reading the documentation for the functions MapThread and Thread and also for the Listable attribute. That should give you a better understanding of how to manipulate lists with functions. Apr 8, 2022 at 7:56
• Thank you for pointing out MapThread (also pointed out later by Daniel). Indeed that works. Apr 8, 2022 at 9:18
• f @@@ Transpose@{{a, b, c, d, e}, {m, n, p, q, r}}, too. May 8, 2022 at 22:07

Apply[f,arg] (or f /@ arg)is the same as f[arg]. If the function needs 2 arguments, you need to deliver 2 arguments. E.g.

(#1 + #2) &[{1, 2}, {3, 4}]
(* {4, 6} *)


Equally, the larger form needs a list of 2 arguments:

Apply[(#1 + #2) &, {{1, 2}, {3, 4}}]
(* {4, 6} *)


Map , on the other hand, applies the function to every element of the argument t. By default to the first level of the argument. E.g.:

Map[(# + 1) &, {1, 2}]
(* {2, 3} *)


or

(# + 1) & /@ {1, 2}
(* {2, 3} *)

• Thanks for taking time to post your answer. However, the problem with defining the general function f that can accept the slot-holder arguments (which are lists) remain. I understand that if I just specify the explicit form of f, there is no problem in passing in lists to #1, #2. The problem lies in keeping f general. Apr 8, 2022 at 8:43
• Your example f[#1, #2] & /@ {{a, b, c, d, e}, {m, n, p, q, r}} is wrong syntax. This needs MpThread, e.g.: MapThread[f[#1, #2] &, {{a, b, c, d, e}, {m, n, p, q, r}}] Apr 8, 2022 at 8:47
• Thank you for your comment. MapThread is what I need for my code ! Apr 8, 2022 at 9:18