独学大学情報学部

ただのノート。主にプログラミング。

macro-compatを使ってmacroの互換性を簡単に管理する

この記事はadventar版Scalaアドベントカレンダーの17日目です。

21日のみ書く予定でしたが、17日空いてるのも寂しいので ズサーc⌒っ゚Д゚)っ しました。 あ、Monocle v1.2.0 がリリースされましたよ。めでたいですね!!

さて、本日はそんなMonocleでも使ってる(?)Scalaのマクロのお話です。個人的にはそもそもあんまりマクロ使わないですし、使ったとしても2.11系のみ対応だったりで、2.10系との互換性を意識したことがなかったんですが、Scala複数のメジャーバージョンを跨ぐライブラリともなると話は別なようです。

Monocle(執筆時 v1.2.0)ではLensやPrism、Isoなどを生成するようなマクロがあります。これまでは、2.10系と2.11系のマクロAPIの差はscala-2.10, scala-2.11ディレクトリ以下にそれぞれMacrosCompatibilityというtraitを作って、そこで吸収していました。

Monocle/MacrosCompatibility.scala at v1.2.0-M1 · julien-truffaut/Monocle · GitHub

Monocle/MacrosCompatibility.scala at v1.2.0-M1 · julien-truffaut/Monocle · GitHub

最近はsbt側で上記ディレクトリの管理もやってくれるようになりましたが、依然コードの方は自前で書かなければなりません。

そこで本日ご紹介するのが macro-compat という、Miles(@milessabin)さんが開発してるライブラリです。

github.com

使い方は簡単。2.11.xのAPIを使って普通にマクロを書いて、その実装を書いたclassに@bundleをつけると勝手に2.10.x系向けのコードも生成してくれます。

やってることは単純で、2.11.xのAPIに対応する2.10.x向け変換メソッドをimplicitとか使ってゴリゴリと定義してあるBundleトレイトをマクロアノテーションを使って、該当のクラスにmix-inしてるだけです。コード例書くのも面倒なので、ちょっと前にMonocleに入れた際のプルリクURL貼っておくので、許して><

Use macro-compat by aoiroaoino · Pull Request #276 · julien-truffaut/Monocle · GitHub

大変便利なmacro-compatですが、まだまだ開発途中の様子で、しばしば欲しい変換メソッドが定義されていなかったりします。 仮にもし定義されてなかった場合は、チャンスなので容赦なく(?)Pull Reqしましょう!

以上、とってもあっさりですがmacro-compatの紹介でした。
素敵なマクロライフを〜。