[racket] macro for broken abstraction?

From: George Neuner (gneuner2 at comcast.net)
Date: Tue Dec 9 14:19:39 EST 2014

Hi Gustavo,

I'm going to have to spend some quality time studying syntax-case.  I'm 
not really fluent, but I think I understand what you're doing.  I like 
that it is able to encapsulate the connection ("db") variable while 
still making it available in the scope of the body.

The only issue then is that the user is locked into using the name used 
in the macro.   No perfect solutions  8-)

Thanks,
George


On 12/9/2014 7:40 AM, Gustavo Massaccesi wrote:
> I think that you want to capture the variables. I made a simplified
> example. The other variables (for example "hidden") are not capture,
> as usual.
>
> ;--- boilerplate.rkt ---
> #lang racket
> (define (call-with-?? proc) (proc)); just for the example
> (define exn:fail:network? exn:fail?); just for the example
> (provide with-db)
> (define-syntax with-db
>    (lambda (stx)
>      (syntax-case stx ()
>        [(_ body ...)
>         (with-syntax ([err-msg (datum->syntax stx 'err-msg stx stx)]
>                       [db (datum->syntax stx 'db stx stx)])
>           ; --- start boilerplate
>           (syntax-protect
>            (syntax/loc stx
>              (let/ec fail-network
>                (with-handlers [(exn:fail:network? (lambda (e)
>                                                     (set! err-msg
> "database connection error")
>                                                     (fail-network)))]
>                  (define db 5)
>                  (define hidden 7)
>                  (call-with-?? (lambda () body ...))))))
>         ; --- end boilerplate
>           )])))
>
> ;--- main.rkt
> #lang racket
> (require "boilerplate.rkt")
> (define err-msg #f)
> (define hidden "BU")
> (with-db
>    (displayln db); ==> 5
>    (displayln hidden); ==> "BU"
>    (/ 1 0)
>    (display "never"))
> (when err-msg
>    (error 'error err-msg))
>
> ;-------
>
> There is a big red warning in the Racket documentation about macros
> with variable capture, but I can't find it. It recommends to use
> syntax-parameters, but the syntax parameter can't change the value of
> err-msg after the macro body had finished. The problem is that if you
> use the with-db macro inside a with-super-db macro, the results are
> strange.
>
> Gustavo
>


Posted on the users mailing list.