レンズの言語レベルのサポートは実際には必要ありません。もちろん、言語のプロパティに応じて多かれ少なかれ有用である可能性があり、構文の明快さは言語機能に依存します。
上記のコメントで述べたように、Scala には優れたレンズ ライブラリがありますが、言語自体は提供していません (おそらく提供すべきではありません)。たとえば、次のクラスがあるとします。
case class Email(user: String, domain: String)
case class Contact(email: Email, web: String)
case class Person(name: String, contact: Contact)
そしてインスタンス:
val foo = Person(
"Foo McBar",
Contact(Email("foo", "mcbar.com"), "http://mcbar.com/foo")
)
Shapelessを使用すると、次のように記述できます (今後のバージョン 2.0 では、同形定型文は不要になることに注意してください)。
import shapeless._, Nat._
implicit val emailIso = Iso.hlist(Email.apply _, Email.unapply _)
implicit val contactIso = Iso.hlist(Contact.apply _, Contact.unapply _)
implicit val personIso = Iso.hlist(Person.apply _, Person.unapply _)
その後:
val emailDomainLens = Lens[Contact] >> _1 >> _1
そして今、Foo McBar は自分の電子メール ドメインを簡単に変更できます。
scala> println(emailHostLens.set(foo)("mcbar.org"))
Person(Foo McBar,Contact(Email(foo,mcbar.com),mcbar.org))
これはすべてバニラの Scala です。Shapeless (1.2.4) の現在のバージョンは、マクロやコンパイラ プラグインなどを使用せず、Scala 2.9 で動作します。Scala 2.10 のマクロを使用したい場合は、より優れた構文を使用してボイラープレートを減らすことができます。
scala> import rillit._
import rillit._
scala> println(Lenser[Person].contact.email.domain.set(foo)("mcbar.org"))
Person(Foo McBar,Contact(Email(foo,mcbar.org),http://mcbar.com/foo))
これは、 Aki Saarinenによって開発された概念実証レンズ ライブラリであるRillitを使用します(後に私によって適応されました)。
構文はそれほどきれいではありませんが、これらすべては Java で実行できたはずです。実際、私は見たことも使用したこともありませんが、Java 用のレンズ ライブラリが存在することは確かです。また、不変データ型が比較的重視されていないということは、ほとんどの Java 開発者がレンズを必要としない、または必要としないことを意味します。