In fact, there is no need for language support for the lenses - although, of course, they can be more or less useful depending on the properties of the language, and the clarity of the syntax will depend on the features of the language.
As I mentioned above, there are good lens libraries for Scala, although the language itself does not (and probably should not) provide them. For example, suppose we have the following classes:
case class Email(user: String, domain: String) case class Contact(email: Email, web: String) case class Person(name: String, contact: Contact)
And instance:
val foo = Person( "Foo McBar", Contact(Email("foo", "mcbar.com"), "http://mcbar.com/foo") )
Using Shapeless , you can write the following (note that in the next version 2.0 you will not need an isolator template):
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 _)
And then:
val emailDomainLens = Lens[Contact] >> _1 >> _1
And now Foo McBar can easily change its email domain:
scala> println(emailHostLens.set(foo)("mcbar.org")) Person(Foo McBar,Contact(Email(foo,mcbar.com),mcbar.org))
This is all Scala vanilla - the current version of Shapeless (1.2.4) does not use macros or compiler plugins, etc., and will work on Scala 2.9. If we want to use Scala 2.10 macros, we get even more pleasant syntax and fewer templates:
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))
It uses Rillit , a proof-of-concept lens library developed by Aki Saarinen (and later adapted by me ).
All this could be done in Java, although the syntax is unlikely to be as clean. In fact, I'm sure Java lens libraries exist, although I have never seen or used them, and the relative lack of attention to immutable data types means that most Java developers will never need or need a lens.