Hacker News new | past | comments | ask | show | jobs | submit login

Racket's hygienic macro system seems to be a heavier cognitive load as well (although it certainly has its own benefits, and some would say it's essential). I really like in Clojure and Arc how easy it is to pound out a macro when you need one.

I have less experience in CL and Racket. I would think that since CL's macros are unhygienic, they would be easy to write as they are in Clojure. It could be that I just haven't gotten the hang of Racket's macros yet, and that once you do they aren't any harder. Let me know if this is the case.




For purposes of writing macros, CL seems to be identical to Arc, other than the name for the macro-defining construct ("defmacro" instead of "mac"). Which, of course, can be fixed with a macro.

There are three "things" about Racket's macro system: hygiene, pattern-matching, and phases. The sort of built-for-you way to do things (define-syntax with syntax-rules or syntax-case) is both hygienic and pattern-matching-based. But you can also make something that is hygienic but not pattern-based, or pattern-based but not hygienic, or neither; this last one is done for you in the library "mzlib/defmacro".

However, what you can't do, at least not without doing something like creating a new file and inserting (require (for-meta 2 <new file>)), is define a macro that you use in a macro body. For example, if you wanted to define "w/uniq", so that you could write

  (define-macro (swap a b)
    (w/uniq tmp           ;instead of (let ((tmp (gensym)))
      `(let ((,tmp ,a))
          ...etc
Simply writing (define-macro (w/uniq var . body) ...) will not work; a macro must be defined at phase level 2 for it to be used by a macro that is defined at phase level 1 (which is when macros are normally defined). And I have not succeeded in finding any way to make this work other than, as I said, creating another file and requiring it. (And, of course, if you want to use anything that isn't base Racket when defining 'w/uniq or whatever, you'll have to require that somehow, or do without.) This might be a minor complaint, but it does annoy me.

See also: http://arclanguage.org/item?id=11529


First, you don't need `w/uniq' in Racket - hygenic macros do that for you automatically. Here's `swap' in Racket:

  (define-syntax-rule (swap a b)
    (let ([tmp a]) (set! a b) (set! b tmp)))
But if you wanted to implement it, here's an easy way to do it in the same module

  (define-syntax (swap stx)
    (define-syntax (w/uniq stx) ...)
    (syntax-parse stx
      [(swap a b) ...]))
That said, the fact that you can't define macros to be used in macros in the same file can be annoying, and is something that we plan to add to the language.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: