C#の「nameof」をScalaで実装してみる

C# vNext に、nameofという演算子が追加されています。

blog.xin9le.net

どういうものかというと、指定したメンバー名を string 型で受け取ることができるというとてもイケてる演算子です。

// こんなクラスがあって
class Person {
  public string Name { get; set; }
  public int Age { get; set; }
}

// こんなことができる
var p = new Person();

Console.WriteLine(nameof(p.Name));  // => "Name"

Console.WriteLine(nameof(p.Age));   // => "Age"

参照先の記事にあるように、文字列を指定してリフレクションをしていたコードが安全に記述できるようになります。

「これって Scala のマクロ使えば似たようなことができるんじゃ?」と思ったので、実験してみました。

目標

インスタンスのメンバー名を取れるよりは、型を指定してそのメンバーを取れる方がいいなと思ったので、以下のコードでメンバー名を取得できることを目標にしました。

// こんなクラスがあって
case class Person(name: String, age: Int)


// こんな定義で
def nameOf[A](f: A => Any): String = macro...


// こんなことができる
nameOf[Person](_.name)  // => "name"

コード

注)Scala のマクロを書くのはほぼ初めてです。実験ですのでエラーハンドリング等はちゃんとやってません。

あまり説明もできませんので、コードを張って終わりにしたいと思います・・・。

nameOf macro

まとめ

マクロの勉強不足なのでうまくかけていないところもありますが、とりあえず取得できるということが分かりました。 実用的に使えるようにしたいところです。