4

Learning how to program I dont fully get the difference of /@ vs @

l = Table[n (n + 1) (n + 2) (n + 3), {n, 1, 10}]
{24, 120, 360, 840, 1680, 3024, 5040, 7920, 11880, 17160}

Sqrt[l + 1]
{5, 11, 19, 29, 41, 55, 71, 89, 109, 131}

Trying to obtain the same result

a = (#^(1/2)) &@ (# + 1) & /@ l
{5, 11, 19, 29, 41, 55, 71, 89, 109, 131}

b = (#^(1/2)) & /@ (# + 1) & /@ l
{25, 121, 361, 841, 1681, 3025, 5041, 7921, 11881, 17161}

c = (#^(1/2)) & /@ (# + 1) & @ l
{5, 11, 19, 29, 41, 55, 71, 89, 109, 131}

The way I understand /@ is to apply the function to every item of the list, so not sure why I get different results on a, b, c. Particularly why in b the function (#^(1/2)) & is not evaluated at all

Enrique Vargas
  • 327
  • 1
  • 5

1 Answers1

6

There are three things at play here:

  • The precedence of @,/@ and & (note the parentheses):

    HoldForm[#&@#&/@l]
    HoldForm[#&/@#&@l]
    HoldForm[#&/@#&/@l]
    (* ((#1&)[#1]&)/@l *)
    (* ((#1&)/@#1&)[l] *)
    (* ((#1&)/@#1&)/@l *)
    
  • The Listable attribute of functions like Plus and Power:

    1+#&@{x,y}
    #^2&@{x,y}
    (* {1+x,1+y} *)
    (* {x^2,y^2} *)
    
  • The behavior of Map applied to atomic expressions: (note: does not apply to all types: e.g. Association and SparseArray are handled differently - thanks @Alan for pointing this out)

    f /@ {x, y}
    f /@ x
    (* {f[x], f[y]} *)
    (* x *)
    

Putting everything together, you can easily explain what you're seeing (I'll leave it as an exercise to explain the individual cases)

Lukas Lang
  • 33,963
  • 1
  • 51
  • 97
  • You final point needs rephrasing, I believe. E.g., an association a = <|x -> 1, y -> 2|> is atomic (AtomQ@a==True) but f /@ a maps over the values. – Alan May 15 '18 at 13:36
  • @Alan Thanks, completely forgot about that part - I've added a note – Lukas Lang May 15 '18 at 13:41