-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
syntax rules implementation issues #55
Comments
Perhaps, when fixing this, it would be nice to consider using the new macro-related SRFis by Marc Nieper-Wißkirchen? |
Hi @jpellegrini. It is clear that the macro system must be rewritten, but hygienic macros are far above my head. This is why the implementation of macro is so poor in STklos 😞 . About this bug, I have found that there is already a kludge in the source that I have added for this problem ( it was added in 2002 from the comment, and I don't remember all the story). By using a So (define-syntax f
(syntax-rules (k)
((f) #f)
((f k) 'K)
((f k x ...) (%%a a %%a (f x ...)))))
stklos> (macro-expand '(f k k k))
(G200 a G200 (f k k)) I know that this is far form ideal, but in the meantime you could perhaps use this turnaround. |
Thanks @egallesio ! :) |
Anyway - where is the macro code of STklos located? |
The code for non hygienic macro is in the compiler and the code for hygienic macro is in |
Ok, I understand how it works now... I am reviewing the macro system options and SRFIs, articles, etc, related to them. It may take a while, but if you don't mind @egallesio , I'd like to try to come up with a new implementation for STklos. |
This would be really great!!! |
It seemsthat Marc is planning to work on a general, portable implementation of a macro system, which would be updated when new macro features arise (in new SRFIs for example). If that is the case, then it would be better to wait and incorporate it, no? |
Marc Nieper-Wißkirchen, I meant. Sorry, was in a hurry! |
While we don't get a better system, would it be OK to use alexpander? |
SUMMARYI am studying the STklos compiler in order to propose a new hygienic macro implementation.
About (1)
About (2):
should expand to About (3):
And for this code:
STklos answers I have an idea of how to implement this, and will be working more on it in the next days. Remark: STklos' |
I'm a bit slow these days - health and personal problems together. That, and I have also been studying ways to get a nice hygienic macro system. I'll be back soon! |
Very sad to read that you're not well. Hope that things will go better for you very soon. |
The idea for handling free variables in macros is this: Include two primitives, case I: the free reference is bound to a local var where the macro is created. When compiling, this:
would create an expander for f like
and later, the macro would be compiled as if, in the macro call, a reference was made to the deep case II: the free variable refers to a global in the current module -- either bound or yet undefined.
This would create an expander for f as
so that, when the compiler finds the |
Then, it would be simple to do the renaming part. That can be done outside the compiler, and is no big deal |
Take care! Hope things will turn out for the better. Your dedication to Scheme is very admirable. |
Oh.
|
The problem is that This local reference issue is also related to SRFI-154 (First class dynamic extent) A new VM instruction that saves the current frame and module list could be used to implement both SRFI-154 and hygienic macros. Or, we could try to implement |
Actually, it seems easy to change it in the compiler, no changes to the VM! Working on it... |
|
Now the rest could be done by integrating the matching part of alexpander or eiod, using |
For full compliance with the standards, it would also be necessary to have a similar %syntax-alias.
If I remember correctly, the standard does not forbid that. Some Schemes allow redefinition of lambda, let, etc (Chibi does); others do not. But even if not allowing to redefine those, the same scoping rules would need to work for hygienic macros -- all the issues with variables arise with syntax too, but the solution then is very similar. Working on it. |
One more thing: the correct implementation would probably need to include macro names in the same stack as variable names, since the standard treats symbol binding scope the same way, regardless of their being boud to a value or to a macro transformer:
STklos does the right thing here:
but
(full-syntax was already loaded) If you're ok with this, I can try to put informaion about macros in the |
@egallesio can you confirm this?
But the macros are visible anyway (?) Even if defined with
Not complaining, just asking. I'm trying to understand all macro-expansion code in order to propose a good |
Hi @jpellegrini,
To answer your questions:
Yep!
Because I'm not very proud of it 🙄 and I think that more (really more) work If you look at the compiled version of a file (define-macro (add-macro x y)
`(+ ,x ,y))
(export-syntax add-macro)
(provide "foo") You will see that it contains ; A -*- Scheme -*- generated file *DO NOT EDIT**
STklos (:version "1.50" :globals () :expanders ((add-macro lambda (x y) `(+ ,x ,y))))
#(+ x y apply add-macro "foo" provide)
32
... bytecode ... The Consider the following file (require "foo")
(print (add-macro 1 3)) If this file is compiled to a file, when building the binary, the compiler needs to know that
Yes since they are global 😞 Allowing, clean local macros is probably the first job to do (as well as enter them in the symbol table and don't use anymore a global table of macros).
Didn't take it as a complaint at all. Any help, on hygienic macros is warmly welcome. Do you think that your |
Not sure that my explanation is clear. Tell me if it is not the case. |
Thanks @egallesio I understand it now! Due to personal problems I'll be a bit slow not, but I'll be working on it! FIrst local
Yes, a wrapper over |
Thanks to you Geronimo, I will be slow too since I have a lot of courses in this period. But if your |
That would be greata! I was willing to study the define-macro implementation and work on local macros, but that would be a lot of work. If you can get define-macro to behave lexically scoped, that would be wonderful. The hygiene part with renaming etc I can do easily later. Meanwhile I can concentrate on Debian packaging! (There are some PRs related to that, by the way) |
I suppose it would work like this - It would be cool if syntax symbols were more like vars -- for example, they could have docstrings... And there could be a special form |
I had an idea, which would not be too invasive to the compiler. I'll work on it more later. |
Hi @egallesio ! |
That would be great, I have tried a solution some time ago, but failed miserably. Waiting for the PR 😉 |
I am overworked at the moment, and although the solution I have partially implemented is simple, it may take some more time to come up with the PR... |
Don't worry @jpellegrini; after all, it is more than 20 years that STklos has such macros 😉 |
An update: I think I got most of the basics done. Implemented macros with lexical scope, which works the same way as other identifiers in STklos; but the renaming/hygiene part is not yet done (however it should be fairly easy after this).
No more glitches! It seems to be working fine. |
Ok so I have written tests, and found that everything works perfectly in the REPL,
@egallesio if you want I may send the PR or put it in a branch in my Github fork so you can see what I'm doing. Anyway, here's a description of what I've done (it's not very organized yet but should be clear enough). Short summary:
Extended summaryGLOBAL MACROSA global macro needs to be Scheme implementation usually do not allow When the compiler finds a global macro being used,
then it will call LOCAL MACROSA local macro needs to have its identifier inserted in the same
The local macro name is kept on the environment stack by the compiler When the compiler finds a reference to an identifier,
ENVIRONMENTS: HOW EXPANDERS ARE COMPILEDA macro expander should use the environment in which it was defined.
When References to other local macros are dealt with when expanding: the LOCAL MACROS USING GLOBAL MACROSIf a global macro has been defined, then it is available as the value Caveat: it is possible to change the content of the global macro WE DO NOT KEEP TRACK OF GLOBAL/LOCAL DISTINCTIONIt's not necessary. NAME REWRITING, HYGIENE ETCWe DO NOT yet deal with those issues here. They can be dealt with |
Hi @jpellegrini, That is really great news. 🙌 |
Hi @egallesio !
Right! And I've made the new macros be variables in modules, and... If the file being compiled creates a module, there is some extra difficulty added. Anyway, there will be some solution for that. :) |
Hi @egallesio ! I've been working on this. I think we could use the current (define-module a
(define-macro (one) -1)
(export-syntax one)
)
(define-module b
(define-macro (one) +1)
(export-syntax one)
)
(provide "one") Since the proposal for new macros would be to have them represented as
The "old style" macros would be the ones we have today. The "new style" macros would be the new ones, with lexical scope (on top of which we'll have
Also, do you think we can somehow add a version number to the What do you think? One further idea: there could be two procedures used to write/read the macro struct from/to bytecode, that could also read/write arbitrary Scheme objects, |
Better yet, don't change the format of |
That is really really cool. Using a special tag such as #expanders is definitively the way to go. When everything is OK with your implementation, we can drop the old one and replace it by yours!!! Just a thing, if you take the position of the start and end of the definition of the macro: are you able to find the values of the constants used by the macro and don't you'll have to patch it? |
Ok @egallesio ! I'll be slowly working on it (I got some work issues to deal with).
The macro has an expander, which is just a closure. The code for serializing closures would do two things:
I'll first create the serializing code, make a separate PR for it, then use it in the macro PR. |
STklos introduces identical symbols in different phases of macro expansion using syntax rules:
Here's the STklos expansion:
some other implementations will return
I rewrote some macros for SRFI-156 and SRFI-41 using
define-macro
, but it feels like the wrong way to go... As far as I could see, SRFI-86 would also need some macro rewriting (and its implementation is quite large).The text was updated successfully, but these errors were encountered: