How to add an option to a Listable custom function?

Hello everyone,

If I create a custom function and want to make it Listable, is the function restricted to one argument, namely, the input list? For example, here’s a function that computes the square root of a number or list of numbers.

mySqrt[num_] := Sqrt[num]
SetAttributes[mySqrt, Listable]

mySqrt[{4,9}] returns {2,3} as expected. But say I want to add a second argument, an option to display the result as a table.

mySqrt[num_] := Sqrt[num]
mySqrt[num_, "Table"] := TableForm[mySqrt[num]]
SetAttributes[mySqrt, Listable]

mySqrt[{4,9},“Table”] still returns {2,3}, not a table. Any way to pull off what I am trying to do?

Greg

You could try Options, OptionsPattern, and OptionValue.

newFunc[x_, OptionsPattern[]] := newHead[x, OptionValue[Form]]

Options[newFunc] = {Form -> "Table"}

SetAttributes[newFunc, Listable]

newFunc[{1, 2, 3}]
(*{newHead[1, "Table"], newHead[2, "Table"], newHead[3, "Table"]}*)

newFunc[{1, 2, 3}, Form -> "Special"]
(*{newHead[1, "Special"], newHead[2, "Special"], newHead[3, "Special"]}*)

Actually, looking at your example again, that might not be what you want. What Listable does is cause your function to be automatically threaded over Lists. Your code actually worked. What you ended up with for mySqrt[{4, 9}, "Table"] was this: List[TableForm[2], TableForm[3]]. It’s just that for atomic values, TableForm doesn’t have a noticeable effect on the appearance.

So, are you wanting a special definition for lists, or are you really wanting to make your function Listable?

mySqrt[{4,9},“Table”] still returns {2,3}, not a table. Any way to pull off what I am trying to do?

It actually does not return {2,3} but

{TableForm[2], TableForm[3]}

because it threaded over the first argument before calling TableForm. Personally I avoid the Listable attribute except for dead-simple numeric functions. For anything else just make a definition that uses Map appropriately, as discussed here.

If you want different handling for Lists and non-Lists, you could use pattern matching:

mySqrt[nums_List] := TableForm[mySqrt /@ nums];
mySqrt[num_] := Sqrt[num]

Hmmmm, I should have output in StandardForm.

That would do the trick. Thanks!

I was just curious to know whether making a function Listable would make it faster than if I used Map.