Arc Forumnew | comments | leaders | submitlogin
2 points by Johnny_65701 6061 days ago | link | parent

I also took it one step farther; hygenic macros. I wrote a macro called hyg that expands into a defmacro that uses let and gensym to avoid capture of all the symbols that are supposed to be hygienic. (Basically it automatically implements the solution in On Lisp for you). the syntax is

(hyg name (x) `(a b c) `(do-something-with ,x a b c)) where name is the name of the macro, x is the argument to the macro, a,b,c are the hygienic symbols, and the rest is the body of the macro. If anybody wants to play with it, I'll post it.



1 point by stefano 6061 days ago | link

Could you push it on Anarki?

-----

2 points by Johnny_65701 6060 days ago | link

It's for Common Lisp, not Arc, but if you want to play with it, send me an e-mail: jjuniman at ll dot mit dot edu. I tried to post it but the formatting got all mangled up and it became unreadable. It's not a lot of code, only a dozen lines or so.

-----

2 points by absz 6060 days ago | link

To post code that looks like code, surround it by blank lines and indent each line with two spaces—that should allow the code to display in a sane manner.

  (When you do that,
   it comes out like this.)

-----

2 points by Johnny_65701 6060 days ago | link

I did that and the ends of the lines got all mutilated. Dunno why, I'm copying & pasting from emacs, I'm not doing anything exotic.

-----

2 points by absz 6060 days ago | link

Are you on Windows/editing files created there? If so, is it possible that Windows's "\r\n" line endings are being pasted in literally?

-----

3 points by Johnny_65701 6059 days ago | link

Nope, Linux. But let me try again, since I have a different macro now that's considerably simpler, so the loss of newlines isn't as bad.

The original one I wrote wasn't working quite right. Then I found something in On Lisp, a macro called with-gensyms that I renamed with-hygeine due to a symbol conflict with something in Clisp:

  (defmacro with-hygiene (syms &body body)
   `(let ,(mapcar #'(lambda (s)
                    `(,s (gensym)))
                syms)
    ,@body))
You're supposed to use it like this:

  (defmacro my-stupid-macro (x y z)
    (with-hygeine (a b c)
      `(do-something-with ,x ,y ,z ,a ,b ,c)))
This gets me most of the way there, but what I really want is this:

  (hyg my-stupid-macro (x y z) (a b c)
    `(do-something-with ,x ,y ,z ,a ,b ,c))
We can achieve that like this:

  (defmacro hyg (name args syms &body body)
    `(defmacro ,name ,args
       (with-hygiene ,syms ,@body)))
Now I can do this:

  (hyg swap (a b) (temp) 
    `(progn 
      (setf ,temp ,a) 
      (setf ,a ,b) 
      (setf ,b ,temp)))
Which expands to:

  (DEFMACRO SWAP (A B) 
    (WITH-HYGIENE (TEMP) 
     `(PROGN 
        (SETF ,TEMP ,A) 
        (SETF ,A ,B) 
        (SETF ,B ,TEMP))))
which expands to:

  (PROGN 
    (SETF #:G3089 A) 
     (SETF A B) 
     (SETF B #:G3089))
PS: I'm a Lisp noob, so apologies in advance if something about this is a little naive, or contains a major oversight.

-----

2 points by absz 6059 days ago | link

Are you sure that you're indenting the lines with two extra spaces each (even the first)? That might fix the formatting.

-----

2 points by Johnny_65701 6059 days ago | link

Ooops, you are correct, sir. I indented all the lines except the first. Indenting the first line fixed the formatting (I went back & edited it)

-----