Arc Forumnew | comments | leaders | submitlogin
Are Arc macros hygienic after all?
3 points by andreuri2000 6109 days ago | 6 comments
...at least partially? I find

  (withs (do 1 re 2 mi 3) (+ do re mi))  ==> 6
whereas according to the definition

  (mac withs (parms . body)
    (if (no parms)
        `(do ,@body)
        `(let ,(car parms) ,(cadr parms)
           (withs ,(cddr parms) ,@body))))
the above should be equivalent to

  (let do 1
     (let re 2
       (let mi 3
         (do 
           (+ do re mi)))))
which should fail, shouldn't it? At least defmacro would fail, wouldn't it? What is going on?


6 points by almkglor 6109 days ago | link

macros override functions everywhere. Try doing something like this:

  (let obj (table)
      (obj 1))
Since obj is a newly-initialized table, we expect (obj 1) to return nil - except (obj ...) is a macro, which overrides the intended definition.

Basically, your greatest risk is that someone will define a new macro in Arc, which happens to shadow a variable (regardless of locality) you are already using in existing code. If that variable is a variable for a collection, you are s.c.r.e.w.e.d.

Maybe we should require that macro names have some defining feature?

-----

4 points by andreuri2000 6109 days ago | link

Hmm, so one gets:

   (let f  1 f)              ==> 1
   (let do 1 do)             ==> 1
   (let f  (fn () 1) f)      ==> #<procedure:f>
   (let do (fn () 1) do)     ==> #<procedure:do>
   (let f   (fn () 1) (f))   ==> 1
   (let do  (fn () 1) (do))  ==> nil    
Seems pretty screwed up to me...

-----

4 points by almkglor 6109 days ago | link

Yes. It might be a good idea to separate macro namespaces from normal namespaces.

-----

2 points by fallintothis 6108 days ago | link

Doesn't look like anything should fail to me. Looks like the do inside of the withs call is being expanded:

  arc> (macex1 '(withs nil something))
  (do something)
  arc> (macex '(do something))
  ((fn () something))
  arc> (macex '(withs nil something))
  ((fn () something))

-----

2 points by stefano 6109 days ago | link

Maybe the symbol do is interpreted as a macro only if it is found in the first position, elsewhere it is interpreted as a variable (or function) name.

-----

2 points by almkglor 6108 days ago | link

It is. Unfortunately this means, as I mentioned, that if you happen to do something like:

  (let obj (table)
       (= (obj 1) 1)
       (obj 1))
... it will fail, miserably.

-----