Skip to content
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

Macro Hygiene #61

Open
VincentToups opened this issue Oct 31, 2020 · 2 comments
Open

Macro Hygiene #61

VincentToups opened this issue Oct 31, 2020 · 2 comments

Comments

@VincentToups
Copy link

The documentation says lisp-like hygienic macros are supported but there isn't much else by way of documentation. Can you elaborate? Most of the time (Common) Lisp style macros are not called hygienic.

@anko
Copy link
Owner

anko commented Nov 1, 2020

You're right, the documentation is imprecise. Worse; it's also incorrect.

I was going by the Wikipedia definition of hygienic macro: Redefining a macro that previously-defined macros are using shouldn't change how the outputs of those previously-defined macros are interpreted. As you say, Common Lisp's macro system does not have this property. (Scheme's does though.)

I recall that eslisp had that property at some point, but it seems I never added a test for it, and have since broken it without noticing:

(! x) ; -> !x;

(macro not (lambda (x) (return `(! ,x))))

(not x) ; -> !x;

(macro ! (lambda (x) (return `(notReally ,x))))

(! x) ; -> notReally(x);

(not x) ; -> notReally(x);
        ; Should still be !x;.  This is not hygienic!

I'll remove the word for now, and look into restoring the feature in the future.

Thanks for the heads-up.

anko added a commit that referenced this issue Nov 1, 2020
At least, it isn't anymore, since I broke that at some point.  Ref #61.
@VincentToups
Copy link
Author

Scheme syntax-transformations have a somewhat broader meaning for the word hygiene. I'm hardly an expert in hygienic macros (though I am very familiar with syntax-case) but the key feature in my mind is that symbols introduced during macro expansion are guaranteed to not clash with any other symbols which may be in scope for the code which is being transformed.

My hand-waving way of thinking of this is that symbol names in both the input code and those introduced by the transformer are abstracted away from the relations they represent: two symbols may both be named "x" but they never the less remain distinct symbols and their bindings are not necessarily the same. Another way to think of it is that in order to reference an x in some code added by a macro-expansion you must also enclose the code in a form which provides a binding for that x. Code expanded by the macro may refer to an x but such references remain distinct.

So once you have macro hygiene you almost always want to think about how to violate it. I like syntax-case as a model of how this ought to work but there are other methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants