Trying to get a NN code going

Richard A. O'Keefe ok@atlas.otago.ac.nz
Mon, 1 Mar 1999 10:57:15 +1300 (NZDT)


I wrote:
	> the program gets a 'rule X in module Y does not match' error.
	> This applies to both the SPARCstatation and the PowerMac.
	> I know what the immediate cause is (calling an elementary matrix
	> update function with arguments of the wrong sizes), but I don't
	> know _where_ it is happening in the program or what the sizes
	> actually are.

<Erik.Zuurbier@KLM.NL> replied
	I guess you don't expect any compiler to tell you about
	'index out of range' errors. But on the other hand, if you get
	'rule X in module Y does not match' I expect you had a
	warning about that when you compiled it.

This misses the point completely.  Yes, the compiler did tell me that
this function might fail.  The function in question looks like

    vupdate :: Matrix Vector Vector Number -> Matrix
    vupdate :: [] _ [] = []
    vupdate [r:rs] xs [y:ys] c = [vaddx r xs (y*c):vupdate rs xs ys c]

and it's basically an elementary matrix update.  It is totally
unsurprising that the function might fail; I *want* it to fail if
the Matrix and second Vector don't fit together; the compiler
correctly noted it; I am *happy* that I was told about it at
run time, because that shows there is a bug in my program.

SOMEWHERE *ELSE*.

What I *do* expect from a Pascal or Ada compiler is that it will
tell me not just where the 'index out of range' was detected, but
WHERE IT CAME FROM, e.g. a backtrace of some kind.

Telling me 'rule vupdate in module aplish does not match' is fine,
as far as it goes, but it doesn't go even microscopically far enough.
The bug is not THERE, but in the code that CALLED it, and this function
is called in several places.  This is altogether typical of functions
that "might fail" in my code; if they do fail, it indicates a bug
_somewhere else_.  What I need is something along the lines of

	'rule vupdate in module aplish does not match
	 called from line 123 of file foobar.icl'

where, thanks to tail recursion and other optimisations, I would not
expect the backtrace to include _every_ call, but I would expect it
to give me a useful bit more than *NOTHING*.

	>  and I'm wondering how other Clean programmers go
	> about debugging their code.

	My Mac occasionaly blows up (a bomb, system error window).
	I usually consider that a compiler bug, not a bug in my
	application. If I don't have the time to wait for the next version,
	I debug and may find a way around the bug.
	
That doesn't help me much, because my question is "HOW"?

But THIS does:
	You can put in some print commands in Clean too. For instance
	replace any expression x of class toString by (Debug "expr" x) where
	
	Debug :: !.String !a -> a | toString a
	Debug label a = KStrict file a
	where	file	= fwrites (label+++"="+++toString a+++",") stderr
			
	KStrict :: !.b .a -> .a
	KStrict b a = a
	
	If the expression does not belong to class toString, you can fiddle
	with Debug, or use DebugL below.
	
	DebugL :: !.String !u:a -> u:a
	DebugL label a = KStrict file a
	where	file	= fwrites label stderr
Thank you VERY much!