12

I am new to Mathematica and just experimenting with the different programming constructs. I have been looking at Map and how to evaluate a function for a list of values and there seems to quite a number of different ways of doing this. I have used Trace to look at what goes on in more detail but is there any difference in the approaches shown below other than syntax? In my example, both @ and /@ appear to be equivalent to Map.

f[x_] := x^2;    
f /@ {1, 2, 3} // Trace

{f /@ {1, 2, 3}, {f[1], f[2], f[3]}, {f[1], 1^2, 1}, {f[2], 2^2, 4}, {f[3], 3^2, 9}, {1, 4, 9}}

f @ {1, 2, 3} // Trace

{f[{1, 2, 3}], {1, 2, 3}^2, {1^2, 2^2, 3^2}, {1^2, 1}, {2^2, 4}, {3^2, 9}, {1, 4, 9}}

f[{1, 2, 3}] // Trace

{f[{1, 2, 3}], {1, 2, 3}^2, {1^2, 2^2, 3^2}, {1^2, 1}, {2^2, 4}, {3^2, 9}, {1, 4, 9}}

{1, 2, 3} // f // Trace

{f[{1, 2, 3}], {1, 2, 3}^2, {1^2, 2^2, 3^2}, {1^2, 1}, {2^2, 4}, {3^2, 9}, {1, 4, 9}}

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
David McHarg
  • 1,643
  • 1
  • 15
  • 28
  • 1
    If you test with f[x_]:=g[x] instead you'll see a difference. The three last examples are just different notations for the same thing. f@x is f[a] is a//f, in FullForm they are all represented as f[a] – jVincent Feb 07 '13 at 10:59
  • 2
    They are not equivalent, but Power has attribute Listable which automatically threads over lists... – Yves Klett Feb 07 '13 at 11:01
  • ok. Thanks. I can see differences when i used the example f[x_]:=g[x]. If i use SetAttributes/ClearAttributes i can make f Listable. Very interesting that you can set attributes to control function evaluation. – David McHarg Feb 07 '13 at 11:09

1 Answers1

9

It seems to me that your tracing gives the answer to your question. The output of the last three traces show identical evaluation and, indeed, this is true in general -- @ is the prefix form of [] and // is the postfix form.

The first trace, the one using /@ (which is just the infix form of Map) yields the same result as the other three, but arrives at it differently, so there is a real difference between Map and function calls. Map gives the same result in your examples because Power (^) has the Listable attribute, which means it automatically maps across lists. But in general, you can't expect a function passed a list to give the same result as when it is mapped across a list, because Listable is not an attribute of most functions. However, it is an attribute of all built-in functions that also have the NumericFunction attribute.

Edit

I implied above that, in general, there is no difference among @, [] and //. That is not quite accurate because these operators do differ in precedence.

The operators [ ] and @ have very high precedence, so it's hard find an example where precedence matters. However, ++ is one the few operators that has precedence lower than [ ] but higher than @. With ++ an example can be contrived.

f[1] = 1; ++f[1]

2

f[1] = 1; ++f@1

PreIncrement::rvalue: f is not a variable with a value, so its value cannot be changed. >>

(++f)[1]
f[1] = 1; ++(f@1)

2

On the other hand, // has a rather low precedence, so it easy to get an unexpected results with the // operator.

x -> y[z]

x -> y[z]

x -> y@z

x -> y[z]

x -> z // y

y[x -> z]

x -> (z // y)

x -> y[z]

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
  • 2
    You could probably also add a note on the difference in precedence between @, [] and //, since a new user is quite likely to not know that and trip up. – rm -rf Apr 14 '13 at 14:23
  • @rm-rf. I think you changed the scope of the question with your recent edit. I'll work on an update to my answer that addresses the additional issue you introduced. I can't do it immediately because I find I need to refresh my understanding of precedence between @, [ ] and // – m_goldberg Apr 15 '13 at 01:39
  • I didn't change the scope; I only gave it a title that reflected what the OP described in the question and the examples (or what I understood it to be). It so happened that the OP's confusion was because of the Listable property. No rush on the update :) – rm -rf Apr 15 '13 at 01:49
  • 1
    Another common and important precedence difference appears with Part: a@b[[c]] vs a[b][[c]] – Mr.Wizard Apr 16 '13 at 08:17