lispのマクロ

onlisp読んで、ようやくlispのdefmacroがちょっとだけわかりました。
C言語のマクロと同じだと思ってたのですが、実際には、式を返す関数だってことでした。


で、自分が作ったのは単純にinline関数なので、ぜんぜんdefmacroではなかったです。orz
凄く恥ずかしい。


式を返す関数とインライン展開のどこが違うのかというと、
マクロを展開するときにプログラムを動かせるかどうかという点があります。

inlinemacro[add](a,b){(a+b)}

defmacro[add](a,b){return `('a+'b);}

と言う感じです。defmacroだとこのあと、

defmacro[add](a,b){if(a==1){ return `0; }[else]{return `('a+'b);}}

のように拡張していける点が違います。
lispからそのまま移植を考えるとこんな感じになるのかと思います。
問題は、`や'をつかっていいの?ってところです。クォートは"`'の3つあるのだけど、
2つも割り当てるのもったいなくね?ってことで。
えーと、ocamlとかほかのDSLはどうやってるかみてみればいいのか。


metaocaml .<>.で囲って、.~( .)で元に戻すとふむふむ。
template haskell は [||]で囲って、$()で元に戻す感じかぁ。
c++はご存知のテンプレートなのでテンプレートですわなぁ。
なるほど。ふむふむむ。前は、わけがわからなかったのだけど、なんとなくわかったような気がする。
ちょっとは成長したな俺。


template haskellの$はいいかもなぁ。
[||]もカッコであると定義してしまえばそれでもいいかなぁ。
単純に好みの話なのだけど、Haskellのがいいってことで、[||]と$aみたいにしよう。

defmacro[add](a,b){if(a==1){ return .<0>. }[else]{return .< ( .~(a) + .~(b) ) >.}}
defmacro[add](a,b){if(a==1){ return [|0|] }[else]{return [|($(a)+$(b))|]}}
defmacro[add](a,b){if(a==1){ return [|0|] }[else]{return [|($a+$b)|]}}

マクロの書き方はhaskellを継承します。なんてな。見た目だけ。カッコイイので真似してみました。あとは、このマクロのカッコの名前か、@macroとかにしておくか。この辺の命名もあとできちんとしないとなぁ。話が変わって[else]とかはプリプロセッサでelseを[else]に書き換えたりできるといいんじゃないかとか、悪いんじゃないかとか。迷走は続きます。

defmacro[add](a,b){if(a==1){ return <%0%> }[else]{return <%($a+$b)%>}}
defmacro[add](a,b){if(a==1){ return <|0|> }[else]{return <|($a+$b)|>}}
defmacro[add](a,b){if(a==1){ return (|0|) }[else]{return (|($a+$b)|)}}

とか、どれがいいんだろ?理由もないのに変える必要もないわなぁ。
とにかく、こういう方向性で修正していきましょー。