時代はリテラルレベルプログラミングだ!

リテラルレベルプログラミングという用語が存在するのかは知りませんが、べつに厳密に定義せずなんとなく使います。まぁこれ https://github.com/okomok/lity の説明が "Exploring literal-level metaprogramming" なので、そこから拝借という感じですかね。

さて、scalaでは、StringやIntのリテラルでfinal valで定義すると、型自体が特別扱いされる(?)という、知られざる仕様があります。まずは以下のgist御覧ください


finalを付けずに val a = "a" だと型は a: String = a なのに対して、final valにすると

b: String("b") = b

というよくわからない型になってますね。そして

def foo(c: b.type)

と定義すると、foo("bar")と渡すとコンパイルエラーになり、foo("b")とするとコンパイル成功するという、謎のメソッドが定義できます。
これ自体は、特殊な言語拡張でもマクロでもなく、Scala2.9(もっと以前?)くらいからある、標準の範囲内の言語仕様です。


以下の記事の解説がもう少し詳しいかもしれません

さて、こんなものをなにに使うのか?というと、あのshapelessでいくつか使われています。

https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0#extensible-records
https://github.com/milessabin/shapeless/blob/shapeless-2.0.0/examples/src/main/scala/shapeless/examples/records.scala

たとえば、recordというものです。shapelessのrecordは、とても大雑把にいえばある意味Mapのようなものなのですが、keyを "Stringのリテラル型" にすることにより、無名case classというか、HListならぬ、HMap的なものというのが実現されています。とにかくshapelessのwikiやサンプルコードみてヤバさを感じてください。あとsqltypedが、このshapelessのrecord使っていたはず https://github.com/jonifreeman/sqltyped


あとは、マクロで頑張りつつ、リテラルレベルプログラミングをやってるのが、最初にリンク貼ったやつです
lity作者からコメントもらったので読みましょう。

https://github.com/okomok/lity

lityの他にも、似たようなヤバい感じなsingとか作ってる人です

https://github.com/okomok/sing

さて、そんなリテラルレベルプログラミングですが、おそらく
「 "b".type というものが実質存在するのに、それを型として直接書けないのはおかしいよね!書けるようにしようぜ!」
という流れで

SIP-23 Literal-based singleton types」

http://docs.scala-lang.org/sips/pending/42.type.html

というのものが最近提案されています。これがもし入ったら面白いけど、初心者には意味不明なヤバイ方向に進化する可能性を秘めていて、ますますあれな感じですね、Scala



追記
自分もうまく説明できませんが、いわゆるsingleton typeとも違うものです、たぶん。たとえば以下のgistみてください

だれかこのあたりの違いをうまく説明してくれ・・・。


とりあえず、妄想含めたあやしい解説というか、自分の現状の知識をtweetしたので貼っておく。ツッコミ待ち