2

This answer says that Listable just makes the function automatically apply MapThread to its arguments.

Does anyone have a simple example of when explicitly using MapThread is better (or simply more convenient) then just giving a function the Listable attribute?

My guess is that if I have a function that works on lists (concatenating, etc), this would be such a case. Or perhaps theres an easy example using Plot (since a list of plot may not be desirable).

user106860
  • 829
  • 4
  • 10

1 Answers1

2

Any function whose arguments are not "homogeneous" would be a candidate. Or any function whose arguments won't "align" properly during a threading. Or any function that expects some of its arguments to be lists with particular semantics in terms of size, position, etc. For example.

myF[a_String, {pre_String, post_String}] := pre <> a <> post

It works like this:

myF["hello", {"a", "b"}]

"ahellob"

But now,

SetAttributes[myF, Listable];
myF["hello", {"a", "b"}]

{myF["hello", "a"], myF["hello", "b"]}

We might want it to be Listable just on the first argument, so we could do this:

myF[{"hello", "goodbye"}, {"a", "b"}]

but that doesn't do what we want now: {myF["hello", "a"], myF["goodbye", "b"]}

If we want to MapThread, we could have done it explicitly:

ClearAttributes[myF, Listable];
MapThread[myF, {{"hello", "goodbye"}, {{"a", "b"}, {"c", "d"}}}]

{"ahellob", "cgoodbyed"}

Or, if we want to thread just on the first argument, we can provide that definition:

myF[as : {___String}, pad : {_String, _String}] := 
  Activate[Thread[Inactive[myF][as, pad], List, 1]];
myF[{"hello", "goodbye"}, {"a", "b"}]

{"ahellob", "agoodbyeb"}

lericr
  • 27,668
  • 1
  • 18
  • 64