# Make input function listable

I have a function taking a function as input as well as other values, e.g.

f2[f_, a_, b_, c_, d_] = f[{a, b}, c, d];


Of course, the behavior differs for f1 being Listable or not. So if I define

f1[x_, y_, z_] = If[x > 0, x*y + z, -x + y + z]


it will yield

In= Attributes[f1] = {};f2[f1, 1, 2, 3, 4]
Out= If[{1, 2} > 0, {1, 2} 3 + 4, -{1, 2} + 3 + 4]


in contrast to

In= SetAttributes[f1, Listable]; f2[f1, 1, 2, 3, 4]
Out= {7, 10}


.

Now my question is: can I implement that f2 will always treat the given input function as Listable? So that I don't have to explicitely give the Attribute to the input function beforehand and still get the listable-ish output (in this case {7,10}.

I was trying

f3[f_, a_, b_, c_, d_] = Assuming[Element[Listable, Attributes[f]], f[{a, b}, c, d]];


but this behaves exactly like f2.

(Of course, in this simple case, I could map over the list {a,b} but let's assume this is not possible or not convenient.)

• Why not use Thread? Listable is just an automatic Thread. f3[f_, a_, b_, c_, d_] = Thread[f[{a, b}, c, d]]; – happy fish Mar 10 '17 at 14:48
• Right, this works, but I didn't come up with it because Thread didn't work in a similar though slightly different context – riddleculous Mar 10 '17 at 14:53
• Can you tell me in what cases Thread does not work? – happy fish Mar 10 '17 at 16:17
• What do we know about a, b, c, d arguments? Can they be lists themselves? Do you want f function to thread them simultaneously with list you create in f2 body? Explicit mapping is safest in this respect, since it won't accidentally thread where you don't want it. – jkuczm Mar 11 '17 at 9:21
• If performance is relevant then How can one write a robust ListableQ function? might be related. – jkuczm Mar 11 '17 at 9:35

If you don't want to modify f1 globally, then you can do it locally:

ClearAll[f1, f2listable];
f1[x_, y_, z_] := If[x > 0, x*y + z, -x + y + z]
f2listable[f_, a_, b_, c_, d_] :=
Module[{g}, g[x_, y_, z_] := f[x, y, z]; SetAttributes[g, Listable]; g[{a, b}, c, d]]

f2listable[f1, 1, 2, 3, 4]


{7, 10}

• Ah right, of course Module works nicely. However, other solutions would be interesting, too (if they exist) – riddleculous Mar 10 '17 at 14:42
• @riddleculous You mentioned in the OP you are not willing to use any of the functions that apply functions over lists. What is the reason for this? – Stitch Mar 10 '17 at 14:52
• For modifying attributes/general function behavior, I use InternalInheritedBlock which acts like Block except the original behavior is still present, i.e. you can modify the existing behavior, temporarily. So, I would use f2listable[...] := InternalInheritedBlock[{f1}, SetAttributes[f1, Listable]; f1[...]]. – rcollyer Mar 10 '17 at 14:53
• @rcollyer that is a very nice solution! – Stitch Mar 10 '17 at 14:54
• @Stitch because in my case, it's more complicated and I use Apply for other arguments of f1 which makes the use of Map impossible or at least very confusing here – riddleculous Mar 10 '17 at 14:55