5 ms·
Why does lack of hygenic macros matter? You can go from basic macros to Clojure's syntax-quote (quasiquote with auto gensyms for certain reader-defined forms) i
by emidln 10y ago
Why does lack of hygenic macros matter? You can go from basic macros to Clojure's syntax-quote (quasiquote with auto gensyms for certain reader-defined forms) in 100 lines of code[1]. I've listed a few other implementations of the clojure-style of quasiquote plus auto-gensym, but there are a ton of them floating around the web for almost every lisp you can think of.
[1] As a clojure library - https://github.com/brandonbloom/backtick/blob/master/src/backtick.clj https://github.com/brandonbloom/backtick/blob/master/src/bac... (although you have to rewrite lines 51-56 to use explicit gensyms in a let instead of using the internal syntax-quote so that it bootstraps cleanly).
[2] Using the alternate Clojure reader - https://github.com/clojure/tools.reader/blob/master/src/main/clojure/clojure/tools/reader.clj https://github.com/clojure/tools.reader/blob/master/src/main...
[3] Using Hylang - https://github.com/hylang/hy/blob/master/hy/core/macros.hy#L200 https://github.com/hylang/hy/blob/master/hy/core/macros.hy#L...
- qwertyuiop924 10y agoThe problem isn't having to make sure that you've gensymed everything. I said I'd be okay with er-macro-transformer, from scheme, which has the same problems, albeit with proper hygene and with rename instead of gensym, which is nicer (and indeed, in CHICKEN we have ir-macro-transformer, which is like syntax-quote, but better, because it operates on the generated output instead of on the input). The problem is gensym itself. Most people think that the only axis macro systems rest on is hygenic vs non-hygenic: Hygenic |Non-hygenic syntax-rules|defmacro and gensym This actually isn't true. Macro systems rest on two axies: Hygenic vs Non-Hygenic, and Lowlevel vs Highlevel: Hygenic Lowlevel |Non-hygenic Lowlevel er-macro-transformer|defmacro and gensym ir-macro-transformer| sc-macro-transformer| --------------------+---------------------- Hygenic highlevel |Non-hygenic highlevel syntax-rules |??? Highlevel macros use declarative pattern-matching. Lowlevel macros are imperative. Hygenic macros guarantee that there will be no name-clashes in a rename. Depending on your language, gensym may or may not do this, but usually does. However, hygenic macros also guarantee that all renamed expressions take on the value they have at in the environment within which the expansion occurs. Gensym does not, and never will, do this. This is acceptable in a Lisp-2 with packages (barely), but in a Lisp-1 of any sort, there is an extreme risk of function shadowing, and other nasty bugs (see http://community.schemewiki.org/?hygiene-versus-gensym http://community.schemewiki.org/?hygiene-versus-gensym for details). Hopefully, this explains why I insist on hygenic macros, and why I think PG really screwed up by not adding hygenic lowlevel macros to arc.
- emidln 10y agoI think the examples I listed (2 of them anyway) actually would be considered hygienic by your standards. syntax-quote as implemented by clojure makes three guarantees: (a) symbols in the body that are postfixed by `#` will be uniformly replaced by a unique gensym in the expansion (b) unquoted things are left alone (c) any other symbol that is not the result of unquote or auto-gensyming, is fully namespace-qualified In so far as is possible with a mutable function namespace (and clojure has this, you can alter the contents of vars and add/remove vars from namespaces), the syntax-quote in Clojure provides the environment within the expansion occurs as well as guaranteeing no name clashes (unless you explicitly opt into them, e.g. unquoting a quoted symbol). If you wanted to do something similar to what the article mentions for common lisp, you end up at: (intern (ns-name 'clojure.core) 'symbol-you-want-to-replace (fn [x] alt-definition-here)) I guess someone technically could do that, but if they do, I would rather my language err towards giving me the power to make bad decisions than hamstring my ability to do useful things. In summary, as long as you have lexical scoping (which FemtoLisp claims to) or namespaces of any sort, you can solve all but the most contrived problems of something like syntax-rules without the additional complexity and restrictions. Again, this can just be added to the language by the user, if they really want it. This comes back to a larger question of, if everything about a language is interesting except its macro system, wouldn't you be well-served to just bolt on the macro system that you desire? (Not saying that FemtoLisp is for you.) Seems that a hygienic vs non-hygienic macro system is fairly trivial if you care enough about the other features.
- deleted 10y ago[deleted]
- qwertyuiop924 10y agoSyntax-quote still isn't actually hygenic by my standards, assuming you can do this (you can test). I don't have a computer in front of me, and I don't know clojure super well (like some of it, don't like some of it, HATE Java and the JVM): (fn a_func [x] (print x)) (defmacro a_macro [y] `(a_func ~y)) (let ((a_func (fn [x] (print "oh noes!")))) (a_macro "this is a string")) ;;;if I'm right, should print "oh noes!" If this does work properly, and no variant of it works, than congrats clojure, you have hygene, or close enough. >I guess someone technically could do that, but if they do, I would rather my language err towards giving me the power to make bad decisions than hamstring my ability to do useful things. Which is why I prefer low-level hygenic macros, like er/ir/sc-macro-transformers: I CAN break hygene whenever I want to, but I have hygene when I want it, and lack of hygene when I don't. Despite what Doug Hoyte may say, I don't have my hands behind my back. >In summary, as long as you have lexical scoping (which FemtoLisp claims to) or namespaces of any sort, you can solve all but the most contrived problems of something like syntax-rules without the additional complexity and restrictions. What additional complexity? With ir-macro-transformer (not mentioned in the article), my macros are as clean as syntax-quote, and it's not that hard to learn. Also, what additional restrictions? I don't see any. >This comes back to a larger question of, if everything about a language is interesting except its macro system, wouldn't you be well-served to just bolt on the macro system that you desire? (Not saying that FemtoLisp is for you.) Seems that a hygenic vs non-hygenic macro system is fairly trivial if you care enough about the other features. Well, femtolisp IS pretty cool, and if you hack together enough code, you can make a system that's almost hygenic, but I'm not sure if you can actually add hygene without the compiler's co-operation. Although gensym may be close enough as far as co-operation goes... I would need to look into this further.