Unwanted evaluation in assignments in Mathematica: why it happens and how to debug it during the package-loading?

StackOverflow https://stackoverflow.com/questions/7408310

  •  29-10-2019
  •  | 
  •  

Question

I am developing a (large) package which does not load properly anymore. This happened after I changed a single line of code. When I attempt to load the package (with Needs), the package starts loading and then one of the setdelayed definitions “comes alive” (ie. Is somehow evaluated), gets trapped in an error trapping routine loaded a few lines before and the package loading aborts.
The error trapping routine with abort is doing its job, except that it should not have been called in the first place, during the package loading phase. The error message reveals that the wrong argument is in fact a pattern expression which I use on the lhs of a setdelayed definition a few lines later.

Something like this:

……Some code lines

Changed line of code 

g[x_?NotGoodQ]:=(Message[g::nogood, x];Abort[])

……..some other code lines

g/: cccQ[g[x0_]]:=True

When I attempt to load the package, I get:

g::nogood: Argument x0_ is not good

As you see the passed argument is a pattern and it can only come from the code line above.

I tried to find the reason for this behavior, but I have been unsuccessful so far. So I decided to use the powerful Workbench debugging tools .

I would like to see step by step (or with breakpoints) what happens when I load the package. I am not yet too familiar with WB, but it seems that ,using Debug as…, the package is first loaded and then eventually debugged with breakpoints, ect. My problem is that the package does not even load completely! And any breakpoint set before loading the package does not seem to be effective.

So…2 questions:

  1. can anybody please explain why these code lines "come alive" during package loading? (there are no obvious syntax errors or code fragments left in the package as far as I can see)
  2. can anybody please explain how (if) is possible to examine/debug package code while being loaded in WB?

Thank you for any help.

Edit

In light of Leonid's answer and using his EvenQ example: We can avoid using Holdpattern simply by definying upvalues for g BEFORE downvalues for g

notGoodQ[x_] := EvenQ[x];
Clear[g];
g /: cccQ[g[x0_]] := True
g[x_?notGoodQ] := (Message[g::nogood, x]; Abort[])

Now

?g

Global`g

cccQ[g[x0_]]^:=True



g[x_?notGoodQ]:=(Message[g::nogood,x];Abort[])



In[6]:= cccQ[g[1]]

Out[6]= True

while

In[7]:= cccQ[g[2]]

During evaluation of In[7]:= g::nogood: -- Message text not found -- (2)

Out[7]= $Aborted

So...general rule:

When writing a function g, first define upvalues for g, then define downvalues for g, otherwise use Holdpattern

Can you subscribe to this rule?

Leonid says that using Holdpattern might indicate improvable design. Besides the solution indicated above, how could one improve the design of the little code above or, better, in general when dealing with upvalues?

Thank you for your help

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top