Hacker News new | ask | show | jobs
by Johnny_Brahms 3186 days ago
I don't get the obsession with defmacro vs syntax case. Defmacro can be implemented in syntax case in about 10 lines, whereas the power of syntax-case is very much non-trivial to implement in CL.
1 comments

I understand that R7RS got rid of syntax-case and standard Scheme is back to syntax-rules only (which is another thing I like about Common Lisp: the standard has been in existence for 23 years).

I'm reminded of this article (https://fare.livejournal.com/189741.html), where this Common Lisp macro:

    (defmacro nest (&rest r) (reduce (lambda (o i) `(,@o ,i)) r :from-end t))
Has to turn into this in Racket (which isn't quite Scheme):

    (define-syntax (nest stx)
      (syntax-case stx ()
        ((nest outer ... inner)
         (foldr (lambda (o i)
                  (with-syntax (((outer ...) o)
                                (inner i))
                    #'(outer ... inner)))
                #'inner (syntax->list #'(outer ...))))))
And was incredibly difficult to reason about. And that author likes Racket.
The Scheme community obsessed over macro hygiene since the 1970's. Yet as of 1997, Scheme still had no error handling mechanism. The R5RS spec spoke about situations which perpetrate an "error", without defining what an error is, how an error can be caught, how an error can be programmatically generated at will, or even whether the image can continue running when an error occurs. (Yeah, macro hygiene will somehow save your project that is confounded by hacks to work around the lack of error handling!)

I'm not going to sit here re-evaluating Scheme, year by year, to see whether it's up to snuff yet.

Someone drop me an e-mail when Scheme gets a well-defined, left-to-right evaluation order, and when its imperative forms all return a stable value like #f or whatever.

    (define-syntax nest
      (syntax-rules ()
        ((nest x) x)
        ((nest x ... (y ...) z) (nest x ... (y ... z)))))
That one is quadratic according to the author, but for 1050 expands of a nest with 6 levels it is less than 10% slower. Whereas in chez scheme, the difference is even less (for more than 2000 expansions)

Edit: Decided to stress test the chez scheme macro expader. for 30000 expansions, it was under 1s using the syntax-case version. I'd say that is very much good enough.

R7rs small is a language in the spirit of r5rs. R5rs large will have a specified low level macro facility, probably syntax-case in one form or the other.

The smaller standard does not specify a low level macro facility. That doesn't mean that an implementation won't have one. No scheme has syntax-rules only.

I agree that the defmacro is simpler, but nobody said otherwise. The nest macro is more or less perfect for defmacro since it doesn't need hygiene.

If defmacro is so Important, there are several schemes with it out there, and if you really need it it is trivially implemented using low level hygienic macro facilities.

How do you describe the semantics of `nest` without showing the implementation?