I use continuation marks to extract the nearest named function (named loops
are also contained in the context):

(define-syntax (#%function stx) ; class method has a symbol name looks like
"[name] method in [class%]"
  #'(let use-next-id : Symbol ([stacks (continuation-mark-set->context
(current-continuation-marks))])
      (if (null? stacks) 'λ
          (or (caar stacks)
              (use-next-id (cdr stacks))))))

with

(define-syntax (throw stx)
  (syntax-parse stx
    [(_ st:id rest ...)
     #'(throw [st] rest ...)]
    [(_ [st:id argl ...] frmt:str v ...)
     #'(throw [st argl ...] (#%function) frmt v ...)]
    [(_ [st:id argl ...] src frmt:str v ...)
     #'(raise (st (format (string-append "~s: " frmt) src v ...)
(current-continuation-marks) argl ...))]))

this macro works much like `error`, and it allows you passing additional
arguments if the exception has more arguments:

(define (throw-exn) : Nothing
    (throw [exn:fail:network:errno (cons 1 'posix)] "message: ~a" (gensym)))

On Sat, Apr 1, 2017 at 4:00 AM, David Storrs <[email protected]> wrote:

> Imagine I have the following trivial module (ignore that things are
> defined out of sequence for clarity):
>
> #lang racket
>
> (define (foo arg)
>     (_baz arg)  ; do some checking, raise an exception if there's a problem
>     ...do stuff...
> )
>
> (define (bar arg)
>     (_baz arg)  ; do some checking, raise an exception if there's a problem
>     ...do stuff....)
>
> (define (_baz arg)  ; internal helper function
>     (when (equal? arg "bad value")
>         (raise-arguments-error '_baz "got a bad value" "val" val))) ;;
> <=== report is from _baz, not foo or bar
>
> (provide foo bar)
>
>
> In Perl I can use caller() [1] to access the stack so that I can have _baz
> report errors as though the error were coming from 'foo' or 'bar' as
> appropriate -- which is what the user expects to see, since their code
> called 'foo' or 'bar', not '_baz'.  (Even better, I could report as though
> the error were coming from the *caller* of foo / bar, which is the user's
> actual code and the real source of the problem.) How can I do the same in
> Racket?  I see the errortrace library, but that says "don't install this
> into a module and expect it to work."
>
> I could pass the name down, of course, but that's clumsy.  I could also
> create a parameter and set it every time I call the helper function that
> needs it, but that's even more clumsy / action-at-a-distance-y and easy to
> forget.  What's the right way?
>
>
> [1] https://perldoc.perl.org/functions/caller.html
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to