15
$\begingroup$

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?

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

How about

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}}}

$\endgroup$
7
$\begingroup$

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}}}*)
$\endgroup$
  • $\begingroup$ f[{1, 2, 3}, Defer[{a, b, c}]] works too. $\endgroup$ – Coolwater Dec 24 '15 at 10:02
  • $\begingroup$ @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}] $\endgroup$ – Algohi Dec 24 '15 at 20:12
3
$\begingroup$

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}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.