Four modules:
- Defines library functions
- Defines library macros that use library functions
- Defines application functions that use library macros
- 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 define
d 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.
(define-syntax (fnodup x) ...)
isn't Scheme either; but often Racket is not Scheme too. What is it you are trying to macrofy? – GoZoner