# nested use of Apply/Map/MapThread in pure functions

1. My main question

I have a function with two argument slots. I wan't to apply this function to 2 lists with different length's. I thought in this solution:

Map[Map[f[# &, #], b] &, c]


But it doesn't work. Why is that?

Example

f[x_, y_] := Sin[x y]

b = {1, 2}
c = {1, 2, 3}


The output seems pretty close of what i wanted but not close enough:

{{Sin[#1 &][1], Sin[#1 &][2]}, {Sin[2 (#1 &)][1],
Sin[2 (#1 &)][2]}, {Sin[3 (#1 &)][1], Sin[3 (#1 &)][2]}}


2. It seems that i only need to take the &'s out of the square brackets.

a) Is it so? Why?

b) how can i do that?

Thanks

-
You can use Outer: Outer[f,c,b] for example. Your solution wasn't absolutely wrong the only problem was f[# &, #] It should have been: Map[Function[$x$,Map[f[# , $x$]&, b]], c] – Spawn1701D Apr 21 '13 at 11:08
If you define f like f[x_][y_]:=Sin[x y] then this works great f[#] /@ b & /@ c. – swish Apr 21 '13 at 11:50

But it doesn't work. Why is that?

It becomes visible when you inspect the inner Map only. I replace the slot for the outer function with 1, because we don't need it to see the error

b = {1, 2};
c = {1, 2, 3};
Map[f[# &, 1], b]

(* {f[#1 &, 1][1], f[#1 &, 1][2]} *)


This is not what you expect and when you look a bit closer, you instantly see that your function is not a Function

f[# &, 1] // FullForm
(* f[Function[Slot[1]],1] *)


Therefore, evaluating f[#&,1][blub] does not result in f[blub,1] as you need it. Now you may think, OK, the & is at the wrong place, it needs to be left to the closing ] of f like this f[#,1]&. Yes, but now you instantly run into trouble when you replace the 1 with your second # again, because now, the slot belongs to the inner function, which is not what you want.

The direct solution is fairly simple. Replace one anonymous function with an explicit Function where you can name the argument

b = {1, 2};
c = {1, 2, 3};
Map[Function[arg, Map[f[#, arg] &, b]], c]

(* {{f[1, 1], f[2, 1]}, {f[1, 2], f[2, 2]}, {f[1, 3], f[2, 3]}} *)


If you have understood your mistake, you may want to think using a more direct approach. The one suggested by Spawn in the comment is really short and readable

Outer[f, c, b]


The function Outer is probably not known by new Mathematica users. One function which is one of the first you learn is Table

Table[f[bi, ci], {ci, c}, {bi, b}]

-
Thank you. I was aware of outer. I was trying to do something more general. For instance, imagine that i want to "outer" in a subpart of the arguments of a function and then "thread" on another subpart.Not sure if this happens often, though – João Cortes Apr 21 '13 at 14:16