|
|
|
|
|
by disentanglement
1648 days ago
|
|
The main issue with the evaluation rules is that Mathematica doesn't distinguish between creating a symbolic expression and evaluating code. That is if I type f[x]
and the function `f` is not defined, Mathematica will not give me an error but instead just assume that I meant to create a symbolic expression. If you know some Lisp, just imagine that everything came with an implicit `quote` which would automatically get invoked whenever a unbound variable or function would we encountered.That issue alone has caused me so many errors simply from mistyping some function or variable name. For simple expressions, such bugs are pretty obvious to spot but if the same occurs deep inside a chain of function calls, this often lead to completely wrong results because the bug got masked by some other manipulations I did on the result of the function call. Of course, there are tons of hacks and ad-hoc workarounds in Mathematica to get around this (imho fundamentally broken) behaviour to the tune of "just stick another `Evaluate` here" or "just change the function definition from `g[x_]` to `g[x_?NumericQ]` to call the function only when the argument is numeric and otherwise leave it unevaluated". The situation with the scoping rules is not much better. Consider for instance the following code: y = 1;
expression = Module[{y},1+y]; (* Module creates a new scope in which y is unbound *)
Can you guess what happens if I print out `expression` now? Print[expression]
1+y$4066
Yes, Mathematica has just renamed our variable. If now we wanted to set `y` in our expression to some concrete value, of course the obvious thing to try doesn't work, but just gives me some bullshit: Print[ReplaceAll[expression, y->10]]
10+y$4066
These are all only some simple examples of why doing any kind of metaprogramming in Mathematica just sucks. |
|
Anyway, to solve your first problem, add the definition f[_]:= Throw["Your error message here"}
To solve your second problem, use Block instead of Module (though in your simple example given here the solution is to just use neither).