Guys,
I am a bit confused. I have a file with a simple macro in it
;; alias so compiler can inline for speed (define-syntax INSTANCE-DISPATCHER (syntax-rules () ((instance-dispatcher inst) (cdr inst))))
This is the only thing in the file (its been striped down). If I invoke gsi enter (load "~~/syntax-case") (load "oop.scm"), oop.scm is the name of the file, everything works great. However, if I change the file to contain
(load "~~/syntax-case")
;; alias so compiler can inline for speed (define-syntax INSTANCE-DISPATCHER (syntax-rules () ((instance-dispatcher inst) (cdr inst))))
invoke gsi and then enter (load "oop.scm") I get a "Ill-formed expression" error. I don't really understand why these two methods produce very different results. Obviously, I am missing something but I have yet to find out what. Any help is appreciated.
Afficher les réponses par date
(load "~~/syntax-case")
;; alias so compiler can inline for speed (define-syntax INSTANCE-DISPATCHER (syntax-rules () ((instance-dispatcher inst) (cdr inst))))
invoke gsi and then enter (load "oop.scm") I get a "Ill-formed expression" error. I don't really understand why these two methods produce very different results. Obviously, I am missing something but I have yet to find out what. Any help is appreciated.
This doesn't work because the (load "~~/syntax-case") is executed **after** macro expansion. Gambit uses a "classic" compilation model separated in phases:
1) read the source code (using the reader, i.e. "read") 2) expand macros and convert source code to an AST 3) transform AST (inlining, constant folding, etc) 4) compile AST to intermediate form, etc 5) execute code
As you see the "load" is executed in phase 5, which is after macros have been expanded in phase 2. The system thinks define-syntax is a function you are trying to call, and () is one of its arguments (which is an invalid expression in Scheme).
Replace the (load "~~/syntax-case") by (include "~~/syntax-case.scm") and your code should work (because "include" is handled in phase 2).
Marc
That makes sense. A small question arises from this. I am in the process of writing what, in time, will become a resonably large application. I take it that include is the way to make use of forms in another file. That said what happens when several files include a single other file and are then compiled to native code. Are the forms from that single file duplicated for every include? This has a bit of impact that I would be interested in being aware of. Also, by extension, is there any more or less accepted way to organize large projects?
On Tue, 15 Mar 2005 12:54:36 -0500, Marc Feeley feeley@iro.umontreal.ca wrote:
(load "~~/syntax-case")
;; alias so compiler can inline for speed (define-syntax INSTANCE-DISPATCHER (syntax-rules () ((instance-dispatcher inst) (cdr inst))))
invoke gsi and then enter (load "oop.scm") I get a "Ill-formed expression" error. I don't really understand why these two methods produce very different results. Obviously, I am missing something but I have yet to find out what. Any help is appreciated.
This doesn't work because the (load "~~/syntax-case") is executed **after** macro expansion. Gambit uses a "classic" compilation model separated in phases:
- read the source code (using the reader, i.e. "read")
- expand macros and convert source code to an AST
- transform AST (inlining, constant folding, etc)
- compile AST to intermediate form, etc
- execute code
As you see the "load" is executed in phase 5, which is after macros have been expanded in phase 2. The system thinks define-syntax is a function you are trying to call, and () is one of its arguments (which is an invalid expression in Scheme).
Replace the (load "~~/syntax-case") by (include "~~/syntax-case.scm") and your code should work (because "include" is handled in phase 2).
Marc
That makes sense. A small question arises from this. I am in the process of writing what, in time, will become a resonably large application. I take it that include is the way to make use of forms in another file. That said what happens when several files include a single other file and are then compiled to native code. Are the forms from that single file duplicated for every include?
Yes. This means that is is best to put syntax declarations in include files and function definitions in .scm files that are "load"ed or linked into an executable after being compiled. The current model is really very close to what is done in C/C++.
This has a bit of impact that I would be interested in being aware of. Also, by extension, is there any more or less accepted way to organize large projects?
The other important mechanism is namespaces. With namespaces you can automatically add a prefix to local names, which is useful to avoid name clashes.
But a complete solution will only come when R6RS modules are implemented...
Marc
Ben
Does gambit support namespaces? They aren't discussed in the docs, but grepping through the code I see '##namespace' calls. However, '##'-prefixed functions aren't public, right? Thanks.
Best regards,
Ben
On Tue, 15 Mar 2005 13:41:42 -0500, Marc Feeley feeley@iro.umontreal.ca wrote:
The other important mechanism is namespaces. With namespaces you can automatically add a prefix to local names, which is useful to avoid name clashes.
On Mar 15, 2005, at 1:41 PM, Marc Feeley wrote:
That makes sense. A small question arises from this. I am in the process of writing what, in time, will become a resonably large application. I take it that include is the way to make use of forms in another file. That said what happens when several files include a single other file and are then compiled to native code. Are the forms from that single file duplicated for every include?
Yes. This means that is is best to put syntax declarations in include files and function definitions in .scm files that are "load"ed or linked into an executable after being compiled. The current model is really very close to what is done in C/C++.
See also (declare (core)) and (declare (not core)).
Brad