22
$\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$
2
  • 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$ Commented Dec 23, 2015 at 16:37
  • $\begingroup$ Clearly Listable satisfies ListableAll, so you don't anything new for that. $\endgroup$
    – m_goldberg
    Commented Dec 23, 2015 at 17:02

3 Answers 3

18
$\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$
2
  • $\begingroup$ f[{1, 2, 3}, Defer[{a, b, c}]] works too. $\endgroup$
    – Coolwater
    Commented Dec 24, 2015 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$ Commented Dec 24, 2015 at 20:12
4
$\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 and acknowledge you have read our privacy policy.

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