define-macro namespace in Gambit-C Scheme

1k views Asked by At

Four modules:

  1. Defines library functions
  2. Defines library macros that use library functions
  3. Defines application functions that use library macros
  4. Loads the other three

libfunc.scm:

(define (my-func ls) ...)

libmacro.scm:

(define-macro (my-macro ls) (define mfls (my-func ls)) `...

libapp.scm

(define app (begin (my-macro '(1 2 3 ...

libmain.scm

(load "libfunc.scm")
(load "libmacro.scm")
(load "libapp.scm")
(define (main . args) (app ...

Porting from another scheme where this works to Gambit-C where it doesn't. I'm starting to think it's impossible. Gambit-C has ##define-macro and ##namespace which might be relevant but are documented nowhere and un-googlable. One thing I did find in Meroon, which is a big library portable across many Schemes, is this code for working around Gambit-C.

Edit: I think Christian Queinnec, Meroon's author, had a good handle on the issues. He wrote 23 things I know about modules for Scheme. I feel like if I spoke both French and Scheme that it would give me all the answers.

Edit 2: I took a look at the original Scheme which was pretty-much purpose built to run the system I'm trying to port. It turns out they cheat. Every "function" that is called from a define-macro has a shadow-implementation in C that is attached to the macro-global namespace. That might be a trick I can copy in Gambit-C since it is very C oriented but I'm still researching that possibility.

I don't know if it's possible to call normally defined functions from a macro using syntax case. I can't find anything easy-to-understand about it (most documentation seems to be written by and for phds) but there's a very interesting tutorial on define-syntax and syntax-case which shows that you can implement any function as a macro. It even implements a basic Lisp in macros. So that's something. JRM's Syntax-rules Primer for the Merely Eccentric

Edit 3: Like @GoZoner says this can be done using for-syntax and define-syntax, at least in Racket. Remains to be seen if it can work in Gambit-C

#lang racket

(require srfi/1)
(require (for-syntax srfi/1))
(require (for-syntax syntax/stx))

(define-syntax (fnodup x)
  (define mydat (delete-duplicates (syntax->datum x)))

  (syntax-case mydat ()
    [(fnodup f) #'(f) ]
    [(fnodup f x0) #'(f x0) ]
    [(fnodup f x0 ...) #'(f '(x0 ...)) ]
     ))

(fnodup print "hi" "der" "hi")

(require (for-syntax ... is where the magic happens. Racket has it. Gambit-C doesn't.

1

There are 1 answers

3
GoZoner On

When 'new to Scheme', stick to Scheme. The syntactic form 'define-macro' is not part of any Scheme standard and is, from the example you've given, a highly inferior macro system compared to what is in the Scheme standard.

Look at R5RS, R6RS or R7RS to understand syntax-rules as your step #1. After that syntax-case in R6RS lets you do other stuff.