Re: [q-lang-users] Newbie questions and comments
Brought to you by:
agraef
From: Albert G. <Dr....@t-...> - 2005-03-18 11:32:27
|
Tim Haynes wrote: > For some reason, I'm getting > > | zsh, trough 6:59PM fsm/ % ./seq.q > | state 17, odd > | ! Error in conditional > | >>> main || quit > | ^ Better leave away all the shebang magic until a script has been tested. :) That's why you never saw a prompt from the debugger, because the interpreter assumed that you want to run in batch mode. You can also leave the shebang as it is, but run the script with q -i to force interactive mode. (Or just run the script in (x)emacs, that will add the -i option for you.) Ok, let's walk through a typical debugger session. Running the script with q -i seq.q, I get: ==> main state 17, odd ! Error in conditional >>> main ^ The interpreter tells us that some conditional failed (that's always because the condition didn't yield a truth value). Note that this message is from the interpreter, the debugger is *not* invoked by default. To tell the interpreter that we want the debugger to kick in when an exception like "Error in conditional" is encountered, we have to turn on "break" mode (you could also enable this by default, either in your .qinitrc file, or with the --break command line option of the interpreter): ==> break on ==> main state 17, odd ! Error in conditional 2> stdlib.q, line 134: filter ((...) . hd) [(...),(...),(...)] ==> [(...)|filter (...) [...]] if ((...) . hd) (odd,bounce_odd,_A (...)) (type ? for help) : (That ":" at the beginning of the line is the prompt of the debugger.) This doesn't tell us an awful lot yet, because of all the ...'s. By default, the debugger only prints two level of parentheses, but we can change this with the .detail command: : .detail=all Now just reprint the current rule with the . command: : . 2> stdlib.q, line 134: filter ((=odd) . hd) [(odd,bounce_odd,_A (printf "%d\n")),(even,bounce_even,_A (printf "%d\n")),(one,fsm::Stop,_A (printf "Stopped! %d\n"))] ==> [(odd,bounce_odd,_A (printf "%d\n"))|filter ((=odd) . hd) [(even,bounce_even,_A (printf "%d\n")),(one,fsm::Stop,_A (printf "Stopped! %d\n"))]] if ((=odd) . hd) (odd,bounce_odd,_A (printf "%d\n")) : Ok, so there we are: ((=odd) . hd) (odd,bounce_odd,_A (printf "%d\n")) is the culprit. Want to see what this actually evaluates to? Simple, just reenter the expression in the debugger: : ((=odd) . hd) (odd,bounce_odd,_A (printf "%d\n")) hd (odd,bounce_odd,_A (printf "%d\n"))=odd Right, hd of a tuple doesn't compute. Maybe you actually want a fst there? Or, better yet, use top, that works with both lists and tuples: : ((=odd) . top) (odd,bounce_odd,_A (printf "%d\n")) odd=odd Hmm, we got one step further but odd=odd still doesn't compute (you can't compare non-const function symbols). You should rather use eq (syntactical equality) there: : (eq odd . top) (odd,bounce_odd,_A (printf "%d\n")) true Right, that's what we want to have. Now let's see how we got here (we go up one rule in the call stack): : u 1> fsm.q, line 20: fsm::lookup [(odd,bounce_odd,_A (printf "%d\n")),(even,bounce_even,_A (printf "%d\n")),(one,fsm::Stop,_A (printf "Stopped! %d\n"))] odd ==> hd R where R = filter ((=odd) . hd) [(odd,bounce_odd,_A (printf "%d\n")),(even,bounce_even,_A (printf "%d\n")),(one,fsm::Stop,_A (printf "Stopped! %d\n"))] Ok, so that's the equation with the wrong filter predicate. If you've been running this in xemacs (as I did), you'd now just click on the last line above, xemacs then takes you to the equation in fsm.q and you can immediately correct it. Maybe it should read more like this: lookup M S = hd R if R where R=filter (eq S.top) M; = false otherwise; Rerunning the seq.q script now gives the next error: ==> main state 17, odd ! Error in conditional 1> fsm.q, line 20: fsm::lookup [(odd,bounce_odd,_A (printf "%d\n")),(even,bounce_even,_A (printf "%d\n")),(one,fsm::Stop,_A (printf "Stopped! %d\n"))] odd ==> hd [(odd,bounce_odd,_A (printf "%d\n"))] if [(odd,bounce_odd,_A (printf "%d\n"))] (type ? for help) : As you see we got one step further: The filter now works ok, but quite obviously you can't use the result (which is always a list, and never a truth value) as a conditional. "if R" is the culprit here; maybe you want something like "if not null R" instead? Or you could use a where clause like "lookup M S = R where [R|_] = filter (eq S.top) M;"? As I'm not sure what you're actually trying to do there, I leave the rest up to you now. You see, the Q debugger is actually much better than its reputation. ;-) With its help, I was able to spot two errors (and fix one of them) in just a few seconds. > which I can't make head or tail of. First, there's a surfeit of ellipses > where some symbols would've been nicer. Mostly, it's a lack of clarity > about what you've got versus what you're expecting, particularly as > pertains to datatypes at a given point in the code. I really want something > that says `got `foo Integer', using `foo A' as nearest/earliest match' - > not in so many words, but it should read that way pretty obviously. As I tried to point out above, there's a lot more to the debugger than its default output. You can determine the level of detail that is to be printed, you can specify when it should take over (using debug on, break on, or by explicitly setting permanent or temporary breakpoints on a certain function), you can inspect the entire call stack, you can step over reductions, and you can even use it to evaluate expressions on the fly in the context of the current rule. All this is described in more detail in Appendix D of the manual: http://q-lang.sourceforge.net/qdoc/qdoc_16.html#SEC152 When you want to make good use of the debugger, I'd also recommend getting familiar with the way that the interpreter evaluates an expression by performing reductions on its rule stack: http://q-lang.sourceforge.net/qdoc/qdoc_7.html#SEC32 Well, maybe the description in the manual is too terse? Do we need a debugger tutorial?? Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikwissenschaft.uni-mainz.de/~ag |