Arc Forumnew | comments | leaders | submitlogin
2 points by elibarzilay 6173 days ago | link | parent

Off topic, but:

* The define-syntax...syntax-rules boilerplate is a very-easy-to-bypass thing.

* Small applications are not a good justification for unhygienic macros: they bite much more when there are several people involved, or when a project lives for a long time.

* Adding automatic gensyms is not enough to call the result hygienic.



1 point by icemaze 6173 days ago | link

1. I didn't know that, I never managed to get past that point. :P Are there macros like with-gensyms that make your life easier? Could you give a reference to show more precisely what you mean? That would be really nice.

2. What I mean is that variable capture is even more useful in big projects (because the DSL approach tends to be more powerful). It is true that they could cause nastier bugs if used incorrectly. But if you use them correctly (by forcing an order of evaluation and protecting the variables you use) there should be no problems. That's certainly true for a LISP-2, I'm not sure about Arc.

3. I don't care how you call it: if you use gensyms where needed the resulting macros won't screw you up! That's what matters, doesn't it?

-----

3 points by elibarzilay 6172 days ago | link

1. You complained about scheme having too much boilerplate code. This is easy to fix, for example, with this macro-defining-macros:

  (define-syntax defmac
    (syntax-rules ()
      ((defmac (name x ...) body)
       (define-syntax name
         (syntax-rules () ((name x ...) body))))))
you can write:

  (defmac (unless condition body ...)
    (when (not condition) body ...))
(See also item 4.)

2. Yes, DSLs are even more useful in big projects; obviously, the only source of all problems is using something incorrectly, the problem is how easy it is to write something incorrect; evaluation order has nothing to do with macros; protecting variables you use doesn't cover all problems; lisp-2 is "statistically better" because people shadow function names less frequently (see also next item).

3. They will bite -- even if you always use gensyms. A simple example:

  (def twice (func) [func (func _)])
  (mac with-duplicate (func . body)
    `(let ,func (twice ,func) ,@body))
This looks simple enough -- but `with-duplicates' happily inserts a `twice' symbol, regardless of what it happens to be bound to:

  (let twice [+ _ _] (with-duplicate cdr (cdr '(1 2 3 4))))
4. Extra point: doing simple captures in scheme with `define-syntax' is said to be difficult in the general case, but it is possible to make that easy too. For example, see the macro definition and examples in http://tmp.barzilay.org/defmac.ss -- the definition uses mzscheme's `syntax-case' etc, but this is not something that you should know about to use it. Just skip to the example to see how it works. (Cheat: there are subtle cases that this doesn't work.)

-----

1 point by icemaze 6172 days ago | link

1. Yes, that's much nicer, thanks.

2. "the problem is how easy it is to write something incorrect". Very true.

"evaluation order has nothing to do with macros" I'm sorry but that's incorrect. An example will show you why:

  (mac sum (x y) `(+ ,y ,x)) ; This is a toy, but some macros suffer from the same problem without being so trivial/stupid
  (= x 1)
  (+ x (++ x))   ; -> 3, the expected result
  (= x 1)
  (sum x (++ x)) ; -> 4, wrong result
Common Lisp macros usually solve this with a meta-macro called once-only that forces things to be evaluated in the right order and only once. Google it for more info.

"lisp-2 is statistically better". Well, not if people know that shadowing function can cause problems. Now a question arises: does shadowing functions solve problems in a way not possible with other methods? Does shadowing function make programs shorter? Or, equivalently, is shadowing functions really that useful? (Please provide examples if you answer this). If not, using a lisp-2 and being careful is enough. But yes, it's easy to overlook a symbol and make a mistake that can be costly. On that, I agree.

3. You are right and that's why I said "I'm not sure about [a lisp-1 like] Arc".

4. That seems really interesting, I'll look into it.

-----

1 point by elibarzilay 6172 days ago | link

You didn't understand me.

One of the things that you can do with macros is specify evaluation order, that's correct. You should also know when and how to evaluate your arguments, as done with the once-only utility (which is really just a thin wrapper around the obvious solution of binders).

But when I said "evaluation order has nothing to do with macros" I meant the kind of macro facility that you use (the original context of this thread was hygiene). No matter which kind of macros you have, the above issues are still the same.

-----