Can someone explain what is going on with the following ...

func[y_] := func[y] = (Print["Hello world !!!"];)


Hello world !!!


Hello world !!!

func[1] (*nothing printed*)

func[2] (*nothing printed*)

As I understand it () are used so the function remembers its values, but as you see when I repeat func[1], nothing.

If I take out the y in f[y], it prints. If I define the function as f[y_] := (...) (without f[y] = ), it prints.

I'm sure there is a simple explanation, any help is appreciated.

  • 2
    $\begingroup$ There is one tiny syntactic subtlety in your code: (expr;) will return Null regardless of what expr evaluates to. $\endgroup$ – amr Jan 31 '13 at 2:49

The reason can be learned by inputting the following:


This outputs the values currently assigned to your function func:




func[y_]:=func[y]=Print[Hello world !!!]

When a function is evaluated that only prints, it assigns it a value of Null which is remembered by the memoization. The documentation covers this under "Properties & Relations".

  • $\begingroup$ Of course, that makes complete sense. Thanks. $\endgroup$ – Alan Renton Jan 31 '13 at 1:04
  • $\begingroup$ Glad I could help. $\endgroup$ – kale Jan 31 '13 at 1:52
  • $\begingroup$ That isn't the only reason. The statement (Print[...];) is interpreted as CompoundExpression[Print[...], Null], and CompoundExpression returns the result of the last expression which is Null. So, the OP got hit with it twice, but only the CompoundExpression applies here. $\endgroup$ – rcollyer Jan 31 '13 at 2:53
  • $\begingroup$ @rcollyer Yep, but the OP's conundrum exists in both cases with and without the semicolon, so I covered the most egregious issue. $\endgroup$ – kale Jan 31 '13 at 4:19

In some languages Print behaves like the identity function. But as noted, Print in Mathematica returns Null.

I want to make clear what is going on with the memoization idiom, for those who might be confused by it. I know I didn't really understand it at first.

func[y_] := func[y] = Print["Hello world !!!"];

This is clearer if it's written like this:

func[y_] := (
    func[y] = Print["Hello world !!!"];

:= means evaluate each time.
= means only evaluate this once.

func[y_] means "match any singular pattern"
func[y] means "match only y's current value"

So the internal assignment is specifying an explicit value for a specific y. And the reason this idiom makes sense is because Mathematica essentially allows you to create multiple definitions for a single function. Examples:

myPrint[l_List] := Do[Print[x], {x, l}];
myPrint[else_] := Print[else];

f[1] = 1;
f[2] = 1;
f[n_] := f[n - 1] + f[n - 2];

So the memoization idiom is an automated version of this.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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