Scala の Macro について

2.10.0-M2 になって Scala に Macro が(まだコンパイルオプションが必要で、試験段階といった感じだが)入って、ここ数日、自分のまわりでなんとなく流行っていたので。 自分の発言とか特に、単に試してみただけであまり正確ではないだろうし、最終的にリリースされるころには色々と仕様変更される可能性(そもそも現状ちゃんとした仕様あるのか?)あるので注意してください
10
Kenji Yoshida @xuwei_k

まぁそんな簡単にいくわけないですね(´・ω・`)

2012-02-27 21:22:03
Naoki Takezoe @takezoen

ところでScalaでマクロ使えるようになったらIDEはどうするんだろう…。

2012-02-28 00:55:19
Kenji Yoshida @xuwei_k

.@takezoen マクロはソースコード上も実装上も、(いくつか暗黙的な引数があるが)結局は「ScalaのオブジェクトであるTreeを渡して、Treeを返す」だけで、それほど文法自体の拡張はないようなので、そこまでIDEでサポートするのに労力はかからないんじゃないですかね?

2012-02-28 01:37:15
Kenji Yoshida @xuwei_k

例えば(Scala2.10.0-M2の時点では)これ https://t.co/QeQW8AXI を逆コンパイルするとこんな感じで Context,Trees.Tree,Trees.Tree という3つの引数をとるメソッドになるっぽい http://t.co/MLPiXj6l

2012-02-28 01:40:38
拡大
Kenji Yoshida @xuwei_k

マクロはソースコード上は①_contextというreflect.macro.Context型のものが必ず渡る②macro内でのみいくつかの名前が自動でimportされる(よくわかってないがreflect.apiとかそのあたり?)だけであとは普通のメソッドとして実装する感じ

2012-02-28 01:58:46
Kenji Yoshida @xuwei_k

いやしかし quasi-quote が入ったら、その部分に関してはIDE作る側は結構めんどくさいか

2012-02-28 02:01:10
Naoki Takezoe @takezoen

@xuwei_k Webサイトのサンプルを少し眺めただけなのでScalaのマクロをちゃんと理解できてるか自信ないのですが、(マクロを書くときの)文法という意味だとそんなに対応は大変ではないと思うのですが、マクロの評価後の型情報をどうやって取るのだろう…という部分が気になります。

2012-02-28 02:56:09
Kenji Yoshida @xuwei_k

@takezoen 自分も詳しいことわかってないですが、現時点で色々いじってみた限りは def macro hoge(a:A):B と戻り値の型を明示して書いておけば、Bの型が返ってくるはずと仮定して補完などはやれるんじゃないのかなーとなんとなく思いますが

2012-02-28 03:03:39
Naoki Takezoe @takezoen

@xuwei_k macro typeがやばそうな気がするんですよね。あと、実際動かしてないのでどういう感じでコンパイラに組み込まれるのかわかっていませんが、インクリメンタルビルドで勝手にマクロの評価が走りまくったら困ることもあるだろうなぁ、とか…。

2012-02-28 03:09:18
Kenji Yoshida @xuwei_k

@takezoen たしかに副作用起こそうと思えば、IOでもなんでもできるので、インクリメンタルビルドの場合大変でしょうね。まぁ副作用起こすようなmacroを定義するほうが悪いでしょうが・・・

2012-02-28 03:16:23
Naoki Takezoe @takezoen

@xuwei_k TypeProviderの例みたいなものだとDBから型を生成するなど実行可能な環境が必要だったり、それなりに重い処理もあり得ると思います。ツールを作る側からするとサポートするとしてもどんな感じでサポートされるのか興味深いところです。

2012-02-28 03:25:48
Kenji Yoshida @xuwei_k

type macro A = TypeDef(Modifiers(),newTypeName("B"),Nil,TypeTree(definitions.IntClass.asTypeConstructor))

2012-02-28 04:08:00
Kenji Yoshida @xuwei_k

type macro って打ったらREPLでコンパイル通ったけれど使い方よくわからんし、そもそもこれある程度の実装完了されてて使える状態なのかさえわからない・・・(・ω・`)

2012-02-28 04:09:33
kmizu @kmizu

@takezoen @xuwei_k マクロ評価後の型情報は、マクロ定義時に返り値(式ツリー)の型が明示されていれば、それに沿って情報取得できるんじゃないですかね?Scalaのマクロは(現時点で)「型付けされたマクロ」ですし。

2012-02-28 06:15:30
kmizu @kmizu

@takezoen @xuwei_k それよりも、自分は、型チェックとマクロ展開の順番がどのようになっているのかがちょっと気になります。特に、マクロ呼び出しがネストした場合とか。

2012-02-28 06:16:37
kmizu @kmizu

BTW, 現状のScalaMacrosの実装だと、式木を分解するのがややめんどくさくて、式木を返すのも(qusi-quotationが無いせいで)めんどくさいので、その辺りが整備されないと、お気軽に有用なマクロを実装する、というわけにはいかなそうなんだよな。

2012-02-28 06:23:20
Kenji Yoshida @xuwei_k

@kmizu 現状"同じコンパイル単位で呼び出せない(利用される側のマクロが先にコンパイルされてる必要がある)" https://t.co/r67xMLRp のでネストした場合は問題にならないんじゃないですかね?この制限があるので、この前の例もわざわざプロジェクト2つ作りましたし

2012-02-28 09:43:10
kmizu @kmizu

@xuwei_k 定義ではなくて、macro1(....(macro2(...))...) みたいなのがあったとき、どうするんだろ、という話です。今のScalaMacrosはマクロ定義の引数と返り値型自体に型が付いてるから、呼び出し側ではその型にあってないとはねればいい話ですが。

2012-02-28 09:50:58
kmizu @kmizu

@xuwei_k ちなみに、同じコンパイル単位内で定義された別のマクロ呼び出せない、という制限はたぶん分割コンパイルを意識したものだと思います。Nemerleのマクロでもほとんど同じ制限がありました。

2012-02-28 09:51:57
Naoki Takezoe @takezoen

@kmizu @xuwei_k macro typeの型情報はTypeProviderのような使い方してるのを見ると静的解析では取れないんじゃないかなと思うのですが…。

2012-02-28 10:39:58
Kenji Yoshida @xuwei_k

「 D言語 に負けじと、最近 #Scala にも macro が入ってコンパイル時計算できるようになりました!」とこの流れにのって Scala を宣伝するメソッド

2012-02-28 18:50:29
akihiro @akihiro4chawon

IDTs 系はコンパイル時に全て確定してしまうので、scala では trait や、あるいは今後実装される macro で組むのが自然なんでしょうね。

2012-02-28 21:40:31
akihiro @akihiro4chawon

Groovy の技法 AST変換は比較的カジュアルに使えるけれど、リーダマクロ相当がないんだよね。惜しいな〜とおもう。

2012-02-28 21:48:51
akihiro @akihiro4chawon

Haskell 版の macro である TemplateHaskell だと同じ翻訳単位内に書ける場合もあることを考えると、scalaの macro はあまりカジュアルには使えなさげ。いや、濫用よくないのでそれでいいんだけど。

2012-02-28 21:49:49
kmizu @kmizu

@akihiro4chawon カジュアルに使えるか、というより、マクロを独立した「コンパイル済みの」モジュールとして再利用しやすいか、という問題かと。同じ翻訳単位に書いた場合、ソース単位はともかく、コンパイル済みライブラリとして再利用できないですし。

2012-02-28 22:15:57