One of the things that I really dislike about Mathematica is its lack of debuggability compared to many other programming languages. Some of the problems arises from the functional nature of Mathematica. However, some of them arises from the current state of Mathematica's development environment and might be improved in later versions. Here is an incomplete list of reasons why Mathematica is less-debuggable compared to other languages. I guess some of you may disagree with some of the reasons below, but most of you agree that such a problem exists.
- In Mathematica, function chaining is a common practice (by function chaining I mean calls like
f[g[h[x]]]). That is, fewer variables are introduced to the programs. As a result, there are fewer intermediate points to check for the expected values. It makes it difficult to narrow down the scope while searching for a problem.
- In Mathematica iterative constructs such as
Whileare usually replaced by block constructs such as
Array. Therefore, while in imperative languages one can narrow down the focus to a single iteration of a loop (and even narrower), in Mathematica, it's not an easy job.
Mathematica doesn't Fail-fast. For instance, if you have a call on an undefined function
f, it will continue computing. Note that, it may be the desired behaviour in some cases but generally it reduces debuggability. The problem becomes more severe when you pass such a function to another function or a function chain. Another (maybe more complicated) instanc follows:
Testis supposed to be called on Integers only, but it doesn't fail if it is called on other types. In some cases we can prevent such an issue by replacing the above line with:
Test[_] := Throw["Incorrect function call"];
Anonymous functions and lazy evaluation are commonly used in Mathematica.
Unlike many other languages such as Java, Mathematica doesn't produce a full stack trace while encounters an exception. It makes it difficult to trace the problem when an exception is thrown (there might be an option to turn on the stack traces that I am unaware of).
Now, the question is: what are the good practices to prevent errors in Mathematica and what are the best debugging techniques if you encountered a problem. I think that's a good idea to have one solution per answer so we can discuss about it easily.