編集可能
2016年4月13日

Scalaのマクロにおける依存関係の工夫

結論としてはSchemeを勉強しよう!(ぇ
1
Kenji Yoshida @xuwei_k

Scalaのマクロで「Treeを受け取り変形して別のTree生成する部分」と「生成されたTreeが実行時に依存するクラス」のjarを分けて定義しておくことによって、実行時には前者必要なくて後者のみで良くなる、が、それを意識して分けてるライブラリがほぼ皆無(?)という問題について

2016-04-13 19:13:08
Kenji Yoshida @xuwei_k

というのを含めたいろいろをこのあたり github.com/scalikejdbc/sc… について考えてて思ったのだが、結局英語で説明する能力がなくてつらくて日本語で書きたくなってくる(というか今すでにtwitterで書いてる)パターン・・・

2016-04-13 19:21:41
Kenji Yoshida @xuwei_k

twitter.com/xuwei_k/status… Tree生成するマクロ側は、生成された結果が特定のクラスやライブラリに依存するとしても 「「Treeを生成するマクロ側」のコードそのもののビルド時」(マクロが実行されるタイミングとは別) には、それらのクラスが存在しなくてもよくて、

2016-04-13 19:25:00
Kenji Yoshida @xuwei_k

そういう関係な具体例としては自分のライブラリが github.com/xuwei-k/zeroap… github.com/xuwei-k/zeroap… core部分でScalaz関連のTreeを生成するが、生成するマクロコードのビルド側にはzの依存がなくてもよく、みたいなことになっており

2016-04-13 19:28:36
Kenji Yoshida @xuwei_k

なおかつ % "provided" にすることによって、コンパイル時のみの依存にできるのである github.com/msgpack4z/msgp… という工夫を、誰か英語でScala本体のマクロのドキュメントに書いて推奨して欲しい(他力本願)

2016-04-13 19:30:26
Kenji Yoshida @xuwei_k

別の例で例えると、Scalaの限定継続は kmizu.hatenablog.com/entry/2014/04/… pluginとlibraryの2種類のjarがあるわけだが、コンパイラプラグイン書く場合はそれらを明示的に分けることになるが、マクロだと良くも悪くもそれを1つのjarにできてしまうという

2016-04-13 19:38:48
でこれき @dico_leque

Implicit phasing for library dependencies dl.acm.org/citation.cfm?i… の言葉で言うと phasing dependency problem を explicit phasing で解決する話かなあ

2016-04-13 19:40:27
Kenji Yoshida @xuwei_k

世の中の大半のScalaのマクロのライブラリ使うと、何も考えないと実行時にscala-reflectのjarの依存くっついて来るけど、工夫すれば基本scala-reflectのjarの依存は実行時には必要ないはず、とか

2016-04-13 19:40:48
がくぞ @gakuzzzz

@xuwei_k あれに関してはTree生成するコード自体にも特に310必要ないのでもっと簡単に行けますね。

2016-04-13 19:41:03
(び) @bizenn

これ、Clojureにも似た話がありそうだけど、そう言えば意識してなかった。

2016-04-13 19:41:47
Kenji Yoshida @xuwei_k

なるほど?(clojureはまぁたぶんわかるとして、でこれきさんの全く聞いたことなくてアレ) twitter.com/bizenn/status/… twitter.com/dico_leque/sta…

2016-04-13 19:44:47
Kenji Yoshida @xuwei_k

@gakuzzzz で、結局scalikjdbcのアレに関しては、たぶん大体の互換性(この場合の互換性の意味・・・となるが)とリフレクション避けるのを、型クラス化(とマクロ導入)したことにより偶然両立可能になるのでは?という立場です(問題があってもコンパイル時に判明するはず)

2016-04-13 19:47:13
がくぞ @gakuzzzz

@xuwei_k はいscalikejdbc-jsr310 じゃなくてマクロのanyの中でやればいけるかな、と。jsr310に入れちゃうとユーザが依存に追加しないと互換性保てなくなるかと思います。coreがコンパイル時だけjsr310に依存するとかもできそうだけど必要ないかなーと

2016-04-13 19:50:59
でこれき @dico_leque

@xuwei_k R6RS Schemeでも、マクロ展開時とか特定のphaseだけ他のライブラリに依存したりすると同じような問題が起きます。で、その論文の著者はあるライブラリがどのphaseで必要になるかユーザーが自分で指定する方法をexplicit phasingと呼んでいます

2016-04-13 19:54:48
Kenji Yoshida @xuwei_k

@gakuzzzz マクロ呼ばれなければ影響ないはず?なので、そんなことない気がした、けど「java8のやつ使う人は必ずscalikejdbc-jsr310依存に入れてる」という前提が成り立つなら大丈夫だけど、あれ入れなくても使えなくもない(そんな人少なそうだけど)からダメか(?

2016-04-13 19:55:01
がくぞ @gakuzzzz

@xuwei_k 現状の挙動がjsr310の依存入れてなくてもinsertとか動いちゃいますからねー。いちおうそこはキープした方がいいのかな、と

2016-04-13 19:56:33
でこれき @dico_leque

@xuwei_k (explicit phasing にはいくつかアプローチがあるけど、やっぱり大変だし、R6RSの仕様だとユーザーが自分でphaseを指定しなくてもimplicitにプログラムから依存性を推論できるよね? というのがこの著者の主張だったりします)

2016-04-13 20:01:41
Kenji Yoshida @xuwei_k

@gakuzzzz んーでもやっぱりversionアップ時のコンパイル時には気がつける?なら、べつに移動させちゃっていい気もしますけど、大したコード量でもないからマクロで毎回丸ごと生成でもどっちでもいいか、任せます (個人的にはjsr301のモジュールに移動でいい気がしますが)

2016-04-13 20:07:06

コメント

コメントがまだありません。感想を最初に伝えてみませんか?