On Sat, May 30, 2015 at 10:30:38PM -0700, chi wrote: > On 05/30/2015 07:02 AM, Peter Bex wrote: > > As has been pointed out time and again, it is fundamentally broken. > > Generally when that is true, you can link to a prepared document explaining it > clearly and unambiguously.
It's all about hygiene, and gensym doesn't cover the full range of hygiene issues. Almost every classic paper about hygienic macros mentions the hygiene problem at some point: - Bawden & Rees's "Syntactic Closures" paper starts out with three examples of broken macros. - Hanson's "A Syntactic Closures Macro Facility" also shows an example of "a subtle bug" in a macro regarding "if". - Clinger & Rees's "Macros That Work" contains a description of four identifier capturing problems. - Clinger's "Hygienic Macros Through Explicit Renaming" also shows an example where "lambda" must be renamed. - In "Implementing Lexically Scoped Macros", Rees shows another example of a macro that breaks in two ways. I didn't bother to check more papers. The Scheme "community wiki" has a FAQ page about gensym vs hygiene which is pretty good: http://community.schemewiki.org/?hygiene-versus-gensym If you use a search engine you find many more examples. A quick grab: http://www.phyast.pitt.edu/~micheles/scheme/scheme28.html http://eli.thegreenplace.net/2007/09/16/common-lisp-vs-scheme-macros/ http://stackoverflow.com/questions/3893919/mechanics-of-variable-capture-with-define-macro-in-scheme Even our own wiki has a tutorial which touches on the issue, but it doesn't really go into detail: http://wiki.call-cc.org/explicit-renaming-macros Now, you're probably not going to read all those things I linked, and they're not all equally clear about the problem, so let's look at a simple example of a macro containing a bug which cannot be fixed at all with traditional define-macro: (define-macro (inc! var) `(set! ,var (+ ,var 1))) Here, set! and + are unhygienically referenced, and may be captured at the call site. Using Gambit: > (define x 1) > (inc! x) > x 2 > (let ((+ print)) (inc! x)) 21> x > (print x) #!void> (set! x 1) > (let ((set! print)) (inc! x)) 12> x 1 Again, note that this bug is unfixable, even with gensym. If we explicitly rename the identifiers, the problem disappears: (define-syntax inc! (er-macro-transformer (lambda (e r c) `(,(r 'set!) ,(cadr e) (,(r '+) ,(cadr e) 1))))) In CHICKEN: #;2> (define x 1) #;3> (inc! x) #;4> x 2 #;5> (let ((+ print)) (inc! x)) #;6> x 3 #;7> (let ((set! print)) (inc! x)) #;8> x 4 Now, I'll readily agree that this is less readable and somewhat more error-prone than define-macro because it doesn't check the argument count. However, for more complicated macros you need to do more than just checking the argument count, which defmacro doesn't help you with either. In Common Lisp, defmacro is equally broken, but CL has the mitigation of being a Lisp-2, which means gensym is usually enough to avoid accidental variable capture: functions live in a different namespace. This is expanded upon in the comments section of the Scheme community wiki page I mentioned earlier. > ...and I would like to state for the record that even defining hygenic syntax > is > a pretty ruinous idea. You have to be very careful of what you're doing, and > confident that it's a good idea, because it is literally impossible for > someone > to tell what your program means without first calculating all of the syntax > rules you have defined in their head. It's so easy to mess with syntax in > Scheme, and that can be a double edged sword, where the code you produce is > completely inscrutable because nobody can figure out what the final result of > syntax producing syntax producing syntax will be. Macros are not to be used lightly, but in some cases they can be a real life saver. That's why Lisp has them and why Scheme has made such a fuss about trying to have them, but *correctly*. Cheers, Peter
signature.asc
Description: Digital signature
_______________________________________________ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users