# Difference in how arguments are passed to functions

Given a custom function f, what is the difference between passing arguments like

f[x_][y_][w_]


and

f[x_,y_,w_]


or other such variations among these? It is often that I see functions using both/some notations, but I can't quite understand the underlying difference.

• See Currying and the currying tag on this site and this question from the times before this site existed :-) Feb 28, 2022 at 22:30
• @MarcoB Much appreciated! Feb 28, 2022 at 22:34
• In the second case you supply the arguments all at the same time and the function is evaluated right away. In the first case you supply x, then sometime later y and only after you supply the final w the function is evaluated. This is the most common use case. Feb 28, 2022 at 23:10

In addition to @Marco's comment on currying, see "operator forms", for instance V10's Operator Forms - what are they good for? and in the docs.

Note in f[x][y][w], any Attributes that f has apply only to f[x]; in f[x, y, w], the Attributes of f apply to f[x, y, z]. For instance HoldAll. If f has the attribute HoldAll, then in evaluating f[x][y][w], the argument x is passed to f unevaluated; but y and w are evaluated and their values are passed to f. In evaluating f[x, y, w], all arguments would be passed unevaluated.

If no attributes, the evaluation sequence is in the two cases shown by TracePrint:

TracePrint[f[x][y][w]]

f[x][y][w]   <- Expression to be evaluated
f[x][y]    <-  The head of f[x][y][w] (to be eval.)
f[x]     <-   The head of f[x][y] (to be eval.)
f      <-    The head of f[x] (evaluated)
x      <-    The arg of f[x] (evaluated)
y        <-   The arg of f[x][y] (evaluated)
w          <-  The arg of f[x][y][w] (evaluated)
f[x][y][w]    <- The result of f[x][y][w] (evaluated)

TracePrint[f[x, y, z]]

f[x,y,z]    <- Expression to be evaluated
f         <-  The head of f[x,y,w] (evaluated)
x         <-  The 1st arg of f[x,y,w] (evaluated)
y         <-  The 2nd arg of f[x,y,w] (evaluated)
z         <-  The 3rd arg of f[x,y,w] (evaluated)
f[x, y, z]    <- The result of f[x][y][w] (evaluated)


Note that in the curried/operator form f[x] or f[x][y] could evaluate to something else:

ClearAll[ff, gg];
ff[a_][b_] := gg[a + b];
TracePrint[ff[x][y][w]]
(*  Out[]= <exercise for the reader>  *)