気晴らしにマクロ

とりあえず作ってみた。
schemeをarc風味にするためのマクロ。
実はあまりマクロ書いたことないから、いろいろ問題有りそう。

それに、いろんなひとがやってそう。

オプショナル変数の指定方法がarcだと結構いい感じ。
マクロで出来そうだけど、多少長くなりそ。

hygienic macro(だっけか?)つかえばオプショナルもかけそうだけどなぁ。
hygienic macroの欠点ってなんなのだろ。
あまり調べられていないのだけれど、変数捕捉をしないことが安全性を高めているのだとすれば、諸刃の剣の切れ味が鈍るということか。
変数捕捉することで実現できるマクロがかけない。

;;macro生成macroではgensymする必要なかった。。キャプチャしないし。
;;
;;(define-macro (sn lname sname) ;; for short name.                                                     
;;  (let ((arg (gensym)))                                                                   
;;    `(define-macro (,sname . ,arg)                                                        
;;       `(,',lname ,@,arg))))                                                              
                                                                                          
(define-macro (sn lname sname)
  `(define-macro (,sname . args)
    `(,',lname ,@args)))

(sn define-macro mac)                                                                     
(sn macroexpand macex)                                                                                                                                                        
(sn gensym uniq)                                                                          
(mac (w/uniq arg . body)                                                                  
     (let ((t (gensym)))                                                                  
       `(let ,(map (fn (t) (list t (uniq))) arg)                                          
          ,@body)))                                                                       
                                                                                                                                                                                                                                                                                                                                                                     
(sn define def)                                                                           
(sn lambda fn)                                                                            
                                                                                          
(sn call/cc ccc)                                                                          
(mac (point cc dummy . body)                                                              
     `(ccc (fn (cc) ,@body ,dummy)))    

(mac (aif pred tr fl)                                                                     
     `(let ( ( it ,pred ) )                                                                   
        (if it                                                                            
            ,tr                                                                           
            ,fl)))