Here's what I've been trying and failing to do in Racket. The smallest 
example I
could think of is a macro that sets a key in a hash-table, so basically this
transformation:

  (set/define ht 'key 42)
  ;; =>
  (hash-set! ht 'key 42)


but if ht there is an unbound identifier it must bind it to a fresh hash 
table. So
basically introduce a (define ht (make-hash)) before setting the key. 
Assume we
run in a context where define is allowed.

Please, don't ask why I want something like this, I just do. So far tricks 
I could
use in other lisps failed in Racket. Here's one silly idea: catch unbound
identifier exn. You can do it as per below or in the handler itself but it 
doesn't
matter cause that define is local (I think) and doesn't happen in the macro 
use
context.

  (require (only-in syntax/macro-testing convert-compile-time-error))

  (define (unbound-id-error? err)
    (and (exn:fail:syntax? err)
         (regexp-match #rx"unbound identifier" (exn-message err))))

  (define-syntax-rule (set/define id key val)
    (unless (let/ec k
              (with-handlers ((unbound-id-error? (λ (_) (k #f))))
                (convert-compile-time-error
                 (hash-set! id key val))))
      (displayln "escaped")
      (define id (make-hash))
      (hash-set! id key val)))

  (set/define ht 'key 42)
  ;; =>
  ;; runs but appears that the (define ht ..) doesn't happen at top-level

This is already all sorts of ugly and it doesn't even work.

Another idea is to replace #%top for the extent of that transformer, perform
local-expand (or some equivalent) so that #%top expansion does the job. 
I've no
idea how to do that, but I'm sure Racket could be persuaded. Incidentally, 
I'm
curious how to create such local transformers e.g. something like 
(let-transformer((#%top ...)) body).

Even if I knew how to do the above (local-expand #'(set/define ht 'key 42) 
'())
run at compile time doesn't seem to wrap unbound ht in #%top. I thought it 
should?

So then, two questions:

1. What's the Racket way of getting what I want?

2. Is there a way to torture the above code into submission? Put 
differently is
   there a way to ensure (define id (make-hash)) runs in appropriate 
context? 

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to