> On Jun 3, 2019, at 11:52 AM, Eric Griffis <ded...@gmail.com> wrote:
> Several times now, I've run into one or another form of the following problem:
> 
> Say I want to build primitives to
> 
> declare an "interface" as a list of names, and
> implement and use those names at run time in a limited scope


The `implement` macro needs to place its identifiers (say, `say`) inside the 
lexical context of the calling site, so that they bind other code coming in 
from the calling site (for instance, `(say 'hello)`). Below, the submodules are 
not essential for the example, but are meant to show that the module (or file) 
boundaries don't affect the result. 

#lang racket

(module interface racket
  (provide interface)
  (define-syntax (interface stx)
    (syntax-case stx ()
      [(_ id member-id ...) #'(define-syntax id #'(member-id ...))])))

(module implement racket
  (require (for-syntax racket/syntax))
  (provide implement)
  (define-syntax (implement stx)
    (syntax-case stx ()
      [(_ class-id def ... expr)
       (with-syntax ([(id ...) (for/list ([stx (syntax-e (syntax-local-value 
#'class-id))])
                                 (format-id #'expr "~a" (syntax->datum stx)))])
         #'(letrec ([id def] ...) expr))])))

(require 'interface 'implement)

(interface Speaker say speak)
(implement Speaker displayln (say 'hello) speak)

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/4B458B0A-90EC-4364-B417-516E46E1B39A%40mbtype.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to