M2 icon indicating copy to clipboard operation
M2 copied to clipboard

Catching uncaught type errors

Open mahrud opened this issue 1 year ago • 9 comments

In the documentation node Tutorial: Divisors, there's this code:

i54 : effective = (D) -> (
          LB := globalSections D;
          L := LB#0;  -- the matrix of numerators
          if numgens source L == 0 
          then error(toString D + " is not effective")
          else divisor sectionIdeal(L_(0,0), LB#1, D));
i55 : effective(2 R - P)

o55 = Divisor{ideal (z, x), ideal 1}

o55 : Divisor

which seems fine on the surface, until you realize that toString D + " is not effective" is an error, since String + String is not defined! Perhaps this used to be defined, but was removed at some point and because that branch in the code was never tested in the documentation, nobody realized that this is an error now.

I'm curious whether other languages have mechanisms to detect type errors like this. @DanGrayson was there ever a plan for the interpreter to catch errors like this using the typicalValues hash table or pseudocode or disassemble?

I understand that a user may define a function like this and define the missing methods later, but is there a way to check if every method call in a function is well-defined at a given point in time? e.g. isWellDefined effective?

For instance, disassemble effective yields a lisp like string and I think this section contains the error:

(adjacent (global-fetch 410) (2-OP + (adjacent (global-fetch 1067) (fetch 0 0)) " is not effective"))

I can guess what adjacent and 2-OP mean and I presume global-fetch 410 is error and global-fetch 1067 is toString. Is there anyway to get the function corresponding to these numbers in the top level? If so, then from typicalValues#toString it would be apparent that the binary operator + is not defined for two strings.

This would be a very useful check for packages, and to make sure changes in the engine don't break untested code.

mahrud avatar Jul 10 '24 06:07 mahrud

@pzinn since you've been looking at this code, do you have any insight on this?

mahrud avatar Jul 18 '24 11:07 mahrud

it's not so clear how to use pseudocode for this: Screenshot from 2024-07-18 21-58-48 one can isolate the offending part of the code, but then one can't evaluate it because it contains a local variable...

pzinn avatar Jul 18 '24 12:07 pzinn

But the type of the local variables should be determinable (at least in some cases, and maybe eventually in most/all cases), no?

mahrud avatar Jul 18 '24 13:07 mahrud

how? M2 is not a typed language... except for arguments of methods I suppose?

pzinn avatar Jul 18 '24 13:07 pzinn

Like this:

i2 : typicalValues#toString

o2 = String

o2 : Type

That's the whole point of tvalues.m2 and typicalvalues.m2 and all that.

mahrud avatar Jul 18 '24 14:07 mahrud

okay. a related thing which annoys me is the content of robust.m2, all these "fake" methods that produce an error. for example a script might go through the code above, conclude that the two arguments of + are strings, then try

i1 : lookup(symbol +,String,String)

o1 = FunctionClosure[/home/pzinn/M2/M2/Macaulay2/m2/robust.m2:93:41-105:69]

o1 : FunctionClosure

and sure enough, there is a method, so no problem...

pzinn avatar Jul 19 '24 04:07 pzinn

That's a good point! Maybe if we had this feature, we could catch bugs like "abc" + "def" earlier and not have any need for the "robust" stuff.

mahrud avatar Jul 19 '24 08:07 mahrud

Incidentally (since it would in particular resolve the issue I pointed out above): As part 2 of my series of debugging-related PRs, I would like to get rid of most of the stuff in robust.m2 (and possibly some in methods.m2) so that errors are

  • handled entirely at the d level
  • printed entirely at the m2 level

and not a mixture of both like right now. I've already done part of the work but there's still a lot to do...

pzinn avatar Jul 20 '24 01:07 pzinn

  • handled entirely at the d level

That would be appreciated.

  • printed entirely at the m2 level

Why is this useful / what do you mean by it?

mahrud avatar Jul 20 '24 17:07 mahrud