quasiquote and gensym?

Started by TedWalther, October 12, 2007, 01:46:30 AM

Previous topic - Next topic

TedWalther

Lutz, are you planning to add a CL style quasiquote and unquote?  I notice back in 2004 someone tried to define it as a macro, but using qq and uq instead of the ` and , characters.



Also, will you be adding a gensym function?



Ted
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

cormullion

#1
Hi there. I've seen posts regarding backquotes and gensym on the forum before. Not sure what they do, but I gather they're not too hard to replicate...

rickyboy

#2
I tried this too, but Lutz does not like the backquote: http://www.alh.net/newlisp/phpbb/viewtopic.php?t=1086">//http://www.alh.net/newlisp/phpbb/viewtopic.php?t=1086



A gensym-like facility (it doesn't have to be *exactly* gensym) would be nice, though, to "clean" up our macros a bit.
(λx. x x) (λx. x x)

TedWalther

#3
Thanks for the link, Ricky.  Because I started off by reading Paul Graham's books, , and ,@ seem natural to me, not wierd or cryptic.  If that syntax is slow, then I can understand Lutz reluctance to put it in.  Pity though.



Also, I could really use gensym for various applications, unrelated to macro-ology.



Ted
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

Lutz

#4
To make macros hygienic and avoid variable capture use the 'args' function to access macro or functions arguments:


(define-macro (setq1)
(set (args 0) (eval (args 1))))

(setq1 x 123)

x => 123


For templating use 'expand' and 'letex'. Here an example for using 'letex' together with a definition of a 'gensym':


(define (gensym:gensym)
(if gensym:count
(inc 'gensym:count)
(set 'gensym:count 1))
(sym (string "gs" gensym:count) MAIN))

(gensym) => gs1
(gensym) => gs2

(define setq2
(letex (s (gensym) v (gensym))
(lambda-macro (s v) (set s (eval v)))))

=> (lambda-macro (gs3 gs4) (set gs3 (eval gs4)))

(setq2 y 456)

y => 456


or for an even stronger 'gensym' you could employ 'uuid':
(define (gensym) (string "gs" (uuid)))

(gensym) => gs7F695830-92DE-4220-BE07-936DF365CE3D


The first generates more human readable symbols, while the second is nice for code only read by machines and 100% safe. 'uuid' by itself generates a universal unique string id, which comes handy for session ids in web programming etc.



For macros, what works best most of the time, is to just use 'args' as in the first example.



Lutz

TedWalther

#5
Thanks  Lutz. I can see that quasiquote and unquote are done quite differently in newLisp.  Your gensym function is very nice.
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

rickyboy

#6
Quote from: "TedWalther"Thanks for the link, Ricky.  Because I started off by reading Paul Graham's books, , and ,@ seem natural to me, not wierd or cryptic.  If that syntax is slow, then I can understand Lutz reluctance to put it in.  Pity though.

Sorry Ted,  Maybe I wasn't clear: I meant that my implementation in newlisp code of CL-like quasiquoting was slow, not that it could never be implemented in a fast way.  In fact, Lutz could code a CL-like quasiquoting syntax into newlisp under-the-hood which would be very fast, but he chooses not to, because he doesn't like that syntax.  And as you pointed out recently, Lutz is happy with the newlispy way of accomplishing that.  Sorry if I confused you in my old post.
(λx. x x) (λx. x x)