# How to define a function that is Listable for some but not all arguments?

I want to define a function f[x,y] that is Listable for only the first argument, not the second. If we use SetAttributes[f, Listable], then f will be "Listable" for all arguments. For example, we define

f[x_, y_] := {x, y}
SetAttributes[f, Listable]

f[{1, 2, 3}, y]  (* -> {{1, y}, {2, y}, {3, y}} *)
f[{1, 2, 3}, {a, b, c}]  (* -> {{1, a}, {2, b}, {3, c}} *)


If f is Listable for only the first variable, I expect

f[{1, 2, 3}, {a, b, c}]
(* -> {{1, {a, b, c}}, {2, {a, b, c}}, {3, {a, b, c}}} *)


Namely, no matter what y is, I want to always get

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


Similar to HoldAll, HoldFirst, HoldRest, etc, I think it is natural to have something like ListableAll, ListableFirst, ListableRest, etc. I cannot understand why it is not a built-in capability of Mathematica. Is there a way to define a function that is Listable for some but not all variables?

• I have extensively discussed this problem in my book, here and also here, where you will find several possible solutions to it. – Leonid Shifrin Dec 23 '15 at 16:37
• Clearly Listable satisfies ListableAll, so you don't anything new for that. – m_goldberg Dec 23 '15 at 17:02

f[x_List, y_] := f[#, y] & /@ x
f[x_, y_] := {x, y}


With this definition

f[{1, 2, 3}, y]


{{1, y}, {2, y}, {3, y}}

and

f[{1, 2, 3}, {a, b, c}]


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

You can directly use your definition as follows:

ReleaseHold@f[{1, 2, 3}, Hold@{a, b, c}]

(*{{1, {a, b, c}}, {2, {a, b, c}}, {3, {a, b, c}}}*)

• f[{1, 2, 3}, Defer[{a, b, c}]] works too. – Coolwater Dec 24 '15 at 10:02
• @Coolwater, It works but it will stay in the output,. f[{1, 2, 3}, HoldForm[{a, b, c}]] works also but it will stay in the output too. Check this: f[{1, 2, 3}, Defer[{1+1, b, c}]] and compare it with ReleaseHold@f[{1, 2, 3}, Hold@{1+1, b, c}] – Algohi Dec 24 '15 at 20:12

Have a look at Thread

Thread[List[Range@3, y]]


{{1, y}, {2, y}, {3, y}}

Thread[List[Range@3, Sequence[x, y]]]


{{1, x, y}, {2, x, y}, {3, x, y}}