Can I make a default for an optional argument the value of another argument?

You can't easily do this with optional arguments (but see Leonid's answer for a work around), but you can use the fact that you can have multiple definitions for a given function:

f[x_, y_:0] := {x, y, y}
f[x_, y_, z_] := {x, y, z}

will do what you want.

For further use of this style you could also do this as:

f[x_] := {x, 0, 0}
f[x_, y_] := {x, y, y}
f[x_, y_, z_] := {x, y, z}

which makes the "pattern" of your function even more explicit


Yes you can, although this is not completely trivial:

Module[{yy},
  f[x_, y_: 0, z_: yy] := Block[{yy = y}, {x, y, z}]
]

What is happening here is that I set the default to a local variable, which I then dynamically set (via Block) to a second argument. So,

{f[1,2],f[1]}

(*  {{1,2,2},{1,0,0}}  *)

A less elegant version than Gabriel's, and a less economic than Leonid's, using ReplaceAll:

f[x_, y_: 0, z_: Automatic] := {x, y, z /. Automatic -> y}