4 ms·
Hygienic macros and a strict phase separation are not distinctive to scheme, many languages have this now, most importantly Rust. And just like Rust macros sche
by patrec 3y ago
Hygienic macros and a strict phase separation are not distinctive to scheme, many languages have this now, most importantly Rust. And just like Rust macros scheme macros are not really an organic part of the language but some extra edifice bolted on top. Scheme definitely deserves credit for pioneering work here, but the only aspect that's of enduring distinctiveness that I'm aware of is Racket's #lang, which basically gives you a less messy and more powerful version of what you could do in Common Lisp with macros and read-tables.
My impression is that hygiene itself (which the scheme community tended to obsess over) is of minor practical benefit, but the fact that you get good error locations (because not using plain lists and symbols makes it easy to carry sufficient contextual information around[^1]) is a major upside.
Out of curiosity, are there additional important practical benefits you see, macro-wise, over Common Lisp (that would make up for the gimped repl)? I.e. in addition to better error messages?
[^1] I seem to remember being told Allegro Common Lisp does a good job here, but I assume identity still imposes some major limitations.
- justinpombrio 3y agoRust macros are not hygienic. The biggest issue with this, I suspect, is the visibility limitation: due to lack of hygiene a macro can only refer to a public value. Thus some crates will publicly expose a value with a doc string saying "this is supposed to be private please don't abuse it our you'll clobber the invariants this crate otherwise upholds". https://doc.rust-lang.org/reference/macros-by-example.html#hygiene https://doc.rust-lang.org/reference/macros-by-example.html#h...
- DonaldPShimoda 3y ago> Hygienic macros and a strict phase separation are not distinctive to scheme, many languages have this now, most importantly Rust. My understanding is that Rust's macros are only partially hygienic. They fall short of Racket's. To the best of my knowledge, Racket has the most hygienic and expressive macro system of any language today. The people behind it have put a lot of work into it over the past couple of decades, producing more than a few significant papers in the realm of PL research. > My impression is that hygiene itself (which the scheme community tended to obsess over) is of minor practical benefit I assume you've not written many macros that generate identifiers before. I assure you, hygiene is quite important for safely reasoning about your syntax! > are there additional important practical benefits you see, macro-wise, over Common Lisp Racket sports a focus on what they call "language-oriented programming". The gist of this community philosophy is that all significant software really is an API (or a layer of multiple APIs), and by treating these APIs as "languages" we can make them more ergonomic. Expressive macros enable a style of programming where you can make your API look however you want while still implementing it within whatever other language you're using. Pretty much all of my Racket projects end up with at least a few macros, though it's worth pointing out that the community also stresses that things that can be functions should be functions rather than macros.
- ReleaseCandidat 3y ago> Hygienic macros and a strict phase separation are not distinctive to scheme, many languages have this now Somebody has already written that Rust doesn't. And I wouldn't say 'many', I know of Elixir which does have them.
- patrec 3y agoRust macros are partially hygienic, but even scheme's macros turned out to have unintended hygiene violations (https://okmij.org/ftp/Scheme/Dirty-Macros.pdf https://okmij.org/ftp/Scheme/Dirty-Macros.pdf). > And I wouldn't say 'many', I know of Elixir Rust, Julia and Elixir are three fairly mainstream languages with hygienic macros, and there are many more obscure languages (Dylan, and I believe Perl6 aka Raku) to outright esoteric ones (PLOT), as well as hygenic macro add-ons like sweet.js.
- bjoli 3y agoI think hygiene vs. defmacro is pretty simple: syntax-case is explicit non-hygiene where defmacro is explicit hygiene. I prefer the former, even though syntax case doesn't go far enough. As it is in r6rs bindings are introduced unhygienically within the extent of a macro transformer, which stinks for complex enough macros. Sadly srfi 72 never caught on. The benefit of the thing giving us the gimped repl is that the runtime can know what something is at compile time. Modules can be compiled with something akin to blocks in SBCL, speeding up procedure calls in ways you can't really achieve with inline caches. Chez spends capararively very little time worrying about things like that, yet manages to have cheaper procedure calls than SBCL almost always.
- pjmlp 3y agoRust macros still fail short, hence why so many crates need to drag syn for the ride, making even more of a mess of compile times.