5

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.

miniplanck
  • 255
  • 1
  • 6

1 Answers1

4

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>  *)
Michael E2
  • 235,386
  • 17
  • 334
  • 747