Hi fellow Gambitters,
I have a problem trying to dynamically load scheme files that contains macros. I know that when a file contains a macro, the macro definition must be in the same file as the macro usage. If not, one must use the (include ....) special form to import the macro definition.
I would like to be able to use (include ...) inside a function to programmatically include some files like (load ...) can do.
For example, if
(for-each (lambda (file) (include file)) '("file1" "file2" ...))
*** ERROR IN (console)@2.15 -- Filename expected
could work!
Is there any way to make this work without appending all the files together.
Thank you, Francois Magnan
Afficher les réponses par date
Include is an operation on source code (it includes the text of a file in the current one). A function call is an operation on scheme values.
So, it's going to be hard in scheme… (CL has ways to use macros at run-time I think) If you know your list, you can try something like
(define-macro (load-all-files . files) (if (null? files) #f `(begin (include ,(car files)) (load-all-files ,@(cdr files)))))
but you need to call it with the list of files in the source (that is, "(load-all-files f1 f2 f3)")
Another, dirtier way, I guess, would be to READ your files, append them to your quoted dynamic code, and to eval it all…
P!
2009/2/14 François Magnan francois.magnan@licef.ca
Hi fellow Gambitters,
I have a problem trying to dynamically load scheme files that contains macros. I know that when a file contains a macro, the macro definition must be in the same file as the macro usage. If not, one must use the (include ....) special form to import the macro definition.
I would like to be able to use (include ...) inside a function to programmatically include some files like (load ...) can do.
For example, if
(for-each (lambda (file) (include file)) '("file1" "file2" ...))
*** ERROR IN (console)@2.15 -- Filename expected
could work!
Is there any way to make this work without appending all the files together.
Thank you, Francois Magnan
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
On 13-Feb-09, at 12:27 PM, François Magnan wrote:
I would like to be able to use (include ...) inside a function to programmatically include some files like (load ...) can do.
That's possible with eval, as shown below.
(define (include-at-runtime fn) (eval `(include ,fn)))
But note that the scope of the macro definitions in those include files may not be what you expect. You can only use those macros in subsequent calls to eval, load, and compile-file/compile-file-to-c (if you are in gsc). For example, say you have two files containing alternate definitions of the macro "foo" and you want to select which one to include like this:
(define (f) ...)
(include-at-runtime (if (f) "my-macs-v1.scm" "my-macs-v2.scm"))
(foo 1)
(eval '(foo 2))
(load "bar.scm") ;; "bar.scm" contains the call (foo 3)
then the call (foo 1) will be treated as a function call because at the moment it mas compiled the "evaluation of the include" had not occurred yet. However (foo 2) and (foo 3) will be expanded using the macro definition of foo.
Alternatively you might be interested in this variant of include:
(define-macro (include-at-macro-expansion-time expr) `(include ,(eval expr)))
This will evaluate at macro expansion time the argument of include-at- macro-expansion-time. So the expression
(include-at-macro-expansion-time (if (f) "my-macs-v1.scm" "my-macs- v2.scm"))
will either do (include "my-macs-v1.scm") or (include "my-macs- v2.scm") depending on the value of the call to f **at macro expansion time**. So f can't be defined at top level in the same file as your call to include-at-macro-expansion-time. However you could force evaluations at macro expansion time with this macro:
(define-macro (eval-at-macro-expansion-time expr) (eval expr) '(begin))
so that you can write
(eval-at-macro-expansion-time (define (f) ...)) (include-at-macro-expansion-time (if (f) "my-macs-v1.scm" "my-macs- v2.scm"))
Marc