Ok then, here are two simple examples of error traces.

In both examples we have the trace from common LISP and from racket.

In the first example I use a syntax proceedure as described in the guide
16.2.2 and as
shows up in my code.  In this example both traces match.  I did not have to
use
syntax-case to get a trace.

In the second example common lisp gives a correct trace, but racket leaves
a function
out of the trace back.  Not a macro, a function.  I show the macro involved
implemented
in all three ways described in the guide, as a proceedure as per the first
example, as
a syntax rule, and, yes, using syntax-case.  In all three cases it appears
that
racket leaves a function out of the trace, though common LISP does not.

In any case, functions missing from the trace are confusing to developers,
as one
looks in the wrong place for the erros.

Well hope I got these examples right anyway.  Apologies in advance if there
is
an error in here.  I hope you will point out where it is. ;-)


--------------------------------------------------------------------------------
1.1 in common LISP (gcl), error manifesting in well formed macro

  bt-example.gcl:
    (defmacro plus (x y) `(+ ,x ,y))
    (defun f (x y) (g x y))
    (defun g (x y) (plus x y))


      >(load "bt-example.gcl")

      Loading bt-example.gcl
      Finished loading bt-example.gcl
      T

      >(f 3 2)

      5

      >(f 3 'a)

      Error: TYPE-ERROR :DATUM A :EXPECTED-TYPE NUMBER
      Fast links are on: do (si::use-fast-links nil) for debugging
      Signalled by +.
      TYPE-ERROR :DATUM A :EXPECTED-TYPE NUMBER

      Broken at +.  Type :H for Help.
          1  Return to top level.
      >>:bt

      #0   +
{loc0=3,loc1=a,loc2=type-error,loc3=nil,loc4=+,loc5="",loc6="",loc7=:datum,loc8=...}
[ihs=6]
      #1   G {} [ihs=5]
      #2   F {} [ihs=4]
      #3   EVAL {loc0=nil,loc1=nil,loc2=nil,loc3=(system:lambda-block f (x
y) ...),loc4=3,loc5=a} [ihs=3]
      NIL
      >>

  Ok, so it gives a back trace to the function that called the macro, and
then to the
  expanded function that had the error. All functions are mentioned, but
the macro is not.

1.2. Same example in racket.

  bt-example.rkt

    #lang racket
    (define-syntax (plus stx)
      (let(
            [datum (syntax->datum stx)]
            )
        (let(
              [x (cadr datum)]
              [y (caddr datum)]
              )
          (define program `(+ ,x ,y))
          (datum->syntax stx program)
          )))
    (define (f x y) (g x y))
    (define (g x y) (plus x y))

    (f 3 2)
    (f 3 'a)

    §> racket -l errortrace -t "bt-example.rkt"
    5
    +: contract violation
      expected: number?
      given: 'a
      argument position: 2nd
      other arguments...:
       3
      errortrace...:
       /home/deep/3_doc/racket_err_mess/bt-example.rkt:15:16: (g x y)
       /home/deep/3_doc/racket_err_mess/bt-example.rkt:19:0: (f 3 (quote a))
      context...:
       /home/deep/3_doc/racket_err_mess/bt-example.rkt:15:0: f
       /home/deep/3_doc/racket_err_mess/bt-example.rkt: [running body]

    §>

  Similar result as per gcl.  All functions mentioned, no mention of the
  syntax transformer.

--------------------------------------------------------------------------------
2.1 in common LISP, this time the well formed macro calls a well formed
function,
where an error manifests:

  bt2-example.gcl:
    (defun h (x y) (+ x y))
    (defmacro plus (x y) `(h ,x ,y))
    (defun f (x y) (g x y))
    (defun g (x y) (plus x y))

    >(load "bt2-example.gcl")

    Loading bt2-example.gcl
    Finished loading bt2-example.gcl
    T

    >(f 3 2)

    5

    >(f 3 'a)

    Error: TYPE-ERROR :DATUM A :EXPECTED-TYPE NUMBER
    Fast links are on: do (si::use-fast-links nil) for debugging
    Signalled by +.
    TYPE-ERROR :DATUM A :EXPECTED-TYPE NUMBER

    Broken at +.  Type :H for Help.
        1  Return to top level.
    >>:bt

    #0   +
{loc0=3,loc1=a,loc2=type-error,loc3=nil,loc4=+,loc5="",loc6="",loc7=:datum,loc8=...}
[ihs=7]
    #1   H {} [ihs=6]
    #2   G {} [ihs=5]
    #3   F {} [ihs=4]
    #4   EVAL {loc0=nil,loc1=nil,loc2=nil,loc3=(system:lambda-block f (x y)
...),loc4=3,loc5=a} [ihs=3]
    NIL
    >>

 All functions cited.  F->G->H->+ then blam. The macro is not cited.


2.1 now in racket

  bt2-example.rkt
    #lang racket
    (define (h x y) (+ x y))
    (define-syntax (plus stx)
      (let(
            [datum (syntax->datum stx)]
            )
        (let(
              [x (cadr datum)]
              [y (caddr datum)]
              )
          (define program `(h ,x ,y))
          (datum->syntax stx program)
          )))
    (define (f x y) (g x y))
    (define (g x y) (plus x y))
    (f 3 2)
    (f 3 'a)

  §> racket -l errortrace -t bt2-example.rkt
  5
  +: contract violation
    expected: number?
    given: 'a
    argument position: 2nd
    other arguments...:
     3
    errortrace...:
     /home/deep/3_doc/racket_err_mess/bt2-example.rkt:3:16: (+ x y)
     /home/deep/3_doc/racket_err_mess/bt2-example.rkt:21:0: (f 3 (quote a))
    context...:
     /home/deep/3_doc/racket_err_mess/bt2-example.rkt:3:0: h
     /home/deep/3_doc/racket_err_mess/bt2-example.rkt: [running body]

  §>

  f -> + and blam .. and nice to know + is inside of 'h'.  ah .. but what
happened to g?
  Is leaving g out of the trace an error?  Because when I go looking for an
invocation
  of 'h' (or '+') inside of 'f', but in fact it is inside of 'g'.

2.2 racket using syntax rules, same result, no mention of g in the trace

  bt2-ex-rules.rkt:
    (define (h x y) (+ x y))

    (define-syntax plus
      (syntax-rules()
        [(plus x y) (h x y)]
        ))


    (define (f x y) (g x y))
    (define (g x y) (plus x y))

    (f 3 2)
    (f 3 'a)

  racket -l errortrace -t bt2-ex-rules.rkt
    5
    +: contract violation
      expected: number?
      given: 'a
      argument position: 2nd
      other arguments...:
       3
      errortrace...:
       /home/deep/3_doc/racket_err_mess/bt2-ex-rules.rkt:3:16: (+ x y)
       /home/deep/3_doc/racket_err_mess/bt2-ex-rules.rkt:15:0: (f 3 (quote
a))
      context...:
       /home/deep/3_doc/racket_err_mess/bt2-ex-rules.rkt:3:0: h
       /home/deep/3_doc/racket_err_mess/bt2-ex-rules.rkt: [running body]

2.3 racket using syntax case, same result, no mention of g in the trace:

  bt2-ex-case.rkt:
    #lang racket

    (define (h x y) (+ x y))

    (define-syntax (plus stx)
      (syntax-case stx ()
        [(plus x y) #'(h x y)]
        ))


    (define (f x y) (g x y))
    (define (g x y) (plus x y))

    (f 3 2)
    (f 3 'a)

  §> racket -l errortrace -t bt2-ex-case.rkt
  5
  +: contract violation
    expected: number?
    given: 'a
    argument position: 2nd
    other arguments...:
     3
    errortrace...:
     /home/deep/3_doc/racket_err_mess/bt2-ex-case.rkt:3:16: (+ x y)
     /home/deep/3_doc/racket_err_mess/bt2-ex-case.rkt:15:0: (f 3 (quote a))
    context...:
     /home/deep/3_doc/racket_err_mess/bt2-ex-case.rkt:3:0: h
     /home/deep/3_doc/racket_err_mess/bt2-ex-case.rkt: [running body]






On Fri, Nov 13, 2015 at 5:59 PM, Greg Hendershott <[email protected]
> wrote:

> On Thu, Nov 12, 2015 at 6:02 PM, Thomas Lynch
> <[email protected]> wrote:
> > It is not the very nature of errors that we do not expect them, and do
> not
> > predict them with specificity, so it is incumbant upon racket to give
> > location infomration with errors, rather than for the programmer to do
> so?
> > Or am I missing something here?
>
> I think you're missing where you discard the location information
> Racket gives you? :)
>
> Following Robby's cue and glancing at your `provide-with-trace` macro
> in test-lib.rkt, it seems like that's the source (no pun intended) of
> this?  View-from-orbit it seems to be:
>
> (define-syntax (provide-with-trace stx)
>   (datum->syntax
>     (manipulate-stuff-as-raw-s-expression
>       (syntax->datum stx)))
>
> This will "slice off" all the interesting source location information
> from the original syntax, `stx`. (Unlike some other lisps, Racket
> syntax transformers get not just the s-expression datum, but full
> syntax objects -- which also include information about things like
> source location and lexical scope.)
>
>
> I think it would be easier If you instead use `syntax-case` or
> `syntax-parse` in the usual way -- supplying a `#'` a.k.a. `syntax`
> template that uses pieces of the original syntax from the pattern.
> Most likely it will preserve all the source info you want,
> automatically.
>
>
> As a quick experiment, change it to a do-nothing "identity" macro that
> returns the original, full syntax-object as-is:
>
> (define-syntax (provide-with-trace stx)
>   stx)
>
> And see if this (plus errortrace) gives you good-enough error
> messages. (This assumes you can still run your program OK without the
> extra tracing stuff defined.)
>
> If it does, then you could look into rewriting the macro in the
> "normal" way to preserve syntax object info.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-dev/CAGxFmCOshjr6JZTdso%2BfjvR1oKDugV3bK40tdMxPvoAZSL%2BMyg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to