I have been bitten hard by SaveDefinitions -> True. I'll describe in detail what happened below.
My questions are: Is this a bug? What is the most convenient workaround?
Consider a definition issued like this:
Block[{x, y}, f[x_, y_] = x + y;]
Why didn't I use := instead? Because the expression that stands in place of x+y in my actual problem is computed (symbolically) within the Block so (numerical) evaluations of f are going to be sufficiently fast.
We can check the definition:
?f
f[x_,y_]=x+y
Now let's give x a value ...
x = 1
... and test that f still works as expected:
f[0, 0]
0 (* as expected *)
Let's use f in Manipulate with SaveDefinitions -> True ...
Manipulate[f[a, b], {a, -1, 1}, {b, -1, 1}, SaveDefinitions -> True]
... and check that it works again:
f[0, 0]
1 (* oops!! *)
?f
f[x_, y_] = 1 + y
The definition of f has been rewritten and changed to something else as a side effect of SaveDefinitions.
What is the morale? Probably that SaveDefinitions and Set are not safe to use together.
Note that what happened here is different form the situation when the definition of f is overwritten just because a notebook containing a manipulate with SaveDefinitions has been opened.
My current workaround is to use the following hack to "neutralize" the HoldAll attribute of SetDelayed:
Block[{x, y},
(f[x_, y_] := #) &[x + y];]
Alternative suggestions are welcome.
Evaluateor your alternative – Rojo Sep 09 '13 at 19:51Manipulate– Rojo Sep 09 '13 at 19:56Manipulate, hasn't this behavior been a problem withSavefor a much longer time? I suspect that the dependency tracing mechanism used inSaveis just showing up again. – m_goldberg Sep 09 '13 at 23:21Withto inject the expr or make a function that returns a function. That will be much cleaner and much more modular. – Sep 10 '13 at 11:33SaveDefinitions. Just never. It's terribly convenient, but for my purposes, it is just not sufficiently predictable. And it can sometimes be incredibly inefficient (e.g., when it stores ridiculous amounts of definitions which were hidden behind aNeedsorGet). – John Fultz Sep 12 '13 at 06:02SaveDefinitionsdoes is to auto-construct anInitializationoption for you. I'm a control freak. Let me construct my ownInitializationoption. – John Fultz Sep 13 '13 at 19:52