Debugging tips: nothing
This article contains a few debug tips. For all of them the solution is/involves core::nothing.
Caveat: The tips all involves recompiling the program, so they may not be applied to all kind of customer scenarios.
core::nothing is a predicate that takes any arguments and does nothing</vp>.
predicates nothing : (...) [deprecated("Should not be used in production code")]. % Not really deprecated % @short This predicate does nothing, but is useful in debug context. % For example to make sure that the variables are visible in the variables window. % @end
It is declared as deprecated so that usage issues a deprecated warning, which reminds you about removing it again, when it has served its debugging purpose.
Last call optimization
Due to last call optimization entries may be missing in the run stack window (and therefore the local variables are lost). It looks as if ppp called rrr, but actualy ppp called qqq which then called rrr; the qqq entry and the local variables there are not present at that debug time.
clauses ppp() :- qqq(). % "last call" disappears in the run stack and variables window clauses qqq() :- rrr(), ...
When placing nothing last in a clause it is the one that receives last call optimizations, so the "old" last call is no longer optimized:
clauses ppp() :- qqq(), % no longer last call, will appear in run stack core::nothing().
Non visible variable values
Due to other optimizations (this problem may become worse in the future, who knows) the values of variables may be "lost" at points where you would think they should still exist.
A typical example are semi-anonymous variables (e.g. _X) which often don’t show up in the variables window.
clauses rrr() :- get_some_things(_X, Y), qqq(Y). % _X is not shown in the variables window
By passing variables as argument to nothing, you can keep/make them alive, so that they can be seen in the variables window:
clauses rrr() :- get_some_things(X, Y), qqq(Y), core::nothing(X). % keep X alive/visible even though we don't really need it
Conditional break points
People often suggest that breakpoints should be conditional. Actually they are, but only very few knows the language, in which you write the conditions.
clauses rrr(X) :- qqq(X). % only break when X is "Special"
There is however one language you know, and in which you can write the appropriate condition: Visual Prolog.
clauses rrr(X) :- if "Special" = X then core::nothing() % "conditional" break point here, i.e. only break when X is "Special" end if, qqq(X).
I used to write succeed instead of nothing. It is just as good for breaking, but unfortunately it has a tendency to stay in the code, when it goes into production. nothing is deprecated, so there is a much larger chance that it is found in due time.