5
$\begingroup$

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.

$\endgroup$
3
  • 3
    $\begingroup$ See Currying and the currying tag on this site and this question from the times before this site existed :-) $\endgroup$
    – MarcoB
    Feb 28, 2022 at 22:30
  • $\begingroup$ @MarcoB Much appreciated! $\endgroup$
    – miniplanck
    Feb 28, 2022 at 22:34
  • $\begingroup$ 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. $\endgroup$ Feb 28, 2022 at 23:10

1 Answer 1

4
$\begingroup$

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>  *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.