[plt-scheme] Source location infromation and tracebacks (was: match-lambda and source location)
On 1/3/09 8:11 PM, Matthew Flatt wrote:
> At Sat, 03 Jan 2009 00:54:53 +0100, Jakub Piotr Cłapa wrote:
>> match-lambda creates a lambda without overriding syntax information.
>> This greatly reduces the information content in stack traces.
>>
>> OTOH overriding the source information for the lambda keyword greatly
>> reduces the clarity of the macro code...
>
> I don't understand what you mean. Can you provide an example, describe
> how it behaves, and describe how it should behave instead?
Ok. I think I misinterpreted the problem since I last stumbled upon it.
Here is the test case:
(define test-1
(match-lambda
[(list a b) #t]))
(define (test-2 l)
(match l
[(list a b) #t]))
Notice the difference in tracebacks between (test-1 #t) and (test-2 #t).
This is as far as I (now) understand related to source location
information of the match form.
The problem with readability of the macros was in my own code:
(define-syntax (on-notif stx)
(syntax-case stx ()
[(on-notif (notif arg ...)
expr expr+ ...)
(with-syntax ([fun (datum->syntax #'here
(syntax-e #'(lambda (arg ...)
expr expr+ ...))
#'on-notif)])
#'(begin
#;(** 'notif (list fun (notif-observers notif)))
(notif-add-observer! notif fun)))]))
Not very pretty and AFAIR I had to datum->syntax the whole expression
and not only the lambda keyword... Is there a better way to solve this?
(I wanted to differentiate the resulting closures when they were printed)
> I may misunderstand this part, too, but I think the first half is what
> Errortrace (in the "errortrace" collection) does. It instruments code
> to push continuation marks that indicates source locations, and then
> the exception handler collects the marks to reconstruct a stack trace.
> Errortrace doesn't try to track tail calls beyond the immediate one.
1. My (uneducated) idea was to add a note every time the source location
info suggests that we changed from macro generated code to user code and
vice versa.
2. Tracing several previous tail calls could ease the debugging of loops
and should be possible without breaking the space efficiency of tail calls.
This would provide for Scheme loops what tracebacks provide for normal
function calls. An answer to the question: How I got here? This is
something that Scheme style iteration could do much better than an
average imperative loop.
A related concern is that even when tail calls are not used for looping
we sometimes loose information:
(define (sqrt-inv a)
(let ([inv (/ a)])
(sqrt inv)))
(define (do-b b)
(sqrt-inv (* 2 b)))
(define (do-c c)
(if (< c 0)
#f
(do-b c)))
When we call (do-c 0) we don't get any of the do- functions in the
traceback.
I have only limited knowledge of how continuation marks (and the
traceback machinery) work in PLT Scheme so I apologize if my remarks are
not very good.
--
regards,
Jakub Piotr Cłapa