Remembering Previously Evaluated Function Values with Optional Argument

You can name the user-call with a pattern and use that for memoization:

call : myFun2[x_, y_: 23] := call = (Pause[1]; x + y);

call : myFun3[x_, y_: 23] := call = myFun3[x, y] = (Pause[1]; x + y);

The first memoizes just the call:

AbsoluteTiming[myFun2[3]]
(*  {1.00087, 26}  *)

AbsoluteTiming[myFun2[3]]
(*  {1.*10^-6, 26}  *)

AbsoluteTiming[myFun2[3, 23]]  (* not memoized *)
(*  {1.00064, 26}  *)

The second memoizes the call, if the call was of the form myFun3[x], and it will memoize the call with the default, myFun3[x, 23], too:

AbsoluteTiming[myFun3[3]]
(*  {1.00028, 26}  *)

AbsoluteTiming[myFun3[3]]
(*  {1.*10^-6, 26}  *)

AbsoluteTiming[myFun3[3, 23]]
(*  {1.*10^-6, 26}  *)

The double assigment call = myFun3[x, y] =... is innocuously redundant if the call is of the form myFun3[x, y].


There might be more elegant ways to handle this, but a very simple one is to use an extra definition. That means instead of:

f[x_, n_: 2] := (f[x, n] = (Pause[1]; x^n))

(note that it usually is a good idea to include a minimal working example in your questions so that people who answer have something to start with...)

use this:

ClearAll@f
f[x_] := f[x, 2]
f[x_, n_] := (f[x, n] = (Pause[1]; x^n))

Tags:

Functions