Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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

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

func[1]

Hello world !!!

func[2]

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.

share|improve this question
2  
There is one tiny syntactic subtlety in your code: (expr;) will return Null regardless of what expr evaluates to. –  amr Jan 31 '13 at 2:49

2 Answers 2

up vote 11 down vote accepted

The reason can be learned by inputting the following:

?func

This outputs the values currently assigned to your function func:

Global`func

func[1]=Null

func[2]=Null

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".

share|improve this answer
    
Of course, that makes complete sense. Thanks. –  Alan Renton Jan 31 '13 at 1:04
    
Glad I could help. –  kale Jan 31 '13 at 1:52
    
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. –  rcollyer Jan 31 '13 at 2:53
    
@rcollyer Yep, but the OP's conundrum exists in both cases with and without the semicolon, so I covered the most egregious issue. –  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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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