I’ve been drawn toward a style of Scala where:
- ≈all parameters and functions are implicit
- semantic info that normally lives in variables’ names is put into their types
- variable-names are basically redundant / unused, because the types now hold that info
This can cut down on three kinds of boilerplate:
- composing things into product types (and projecting fields back out of those products)
- explicitly passing variables to functions that take eponymous arguments
- storing intermediate values with names that are a camel-cased version of their type
I’m interested in pointers to any tooling that supports this, prior art where it worked well or poorly, or relevant terms (what is this pattern called?).
I’m also aware of the general aversion to implicit conversions in particular, and to “too much implicit magic” in general, but nevertheless feel that there is something interesting in this direction that I want to explore. I’ve gone pretty far with it on a few projects and not regretted it.
Example
Given:
case class Foo(a: String, b: Int, c: Seq[String])
We can convert it to:
case class A(value: String )
case class B(value: Int )
case class C(value: Seq[String])
case class Foo(A:A, B:B, C:C)
it gets interesting when we add a variety of “common sense” implicits:
object Foo {
implicit def derive(implicit A:A, B:B, C:C) = Foo(A, B, C)
// this needs to be mixed-in or explicitly wildcard-imported in order for these to be in scope
trait extras {
implicit def unwrapA(Foo: Foo) = Foo.A; implicit def deriveA(implicit Foo: Foo) = Foo.A
implicit def unwrapB(Foo: Foo) = Foo.B; implicit def deriveB(implicit Foo: Foo) = Foo.B
implicit def unwrapC(Foo: Foo) = Foo.C; implicit def deriveC(implicit Foo: Foo) = Foo.C
}
object extras extends extras
}
import Foo.extras._
// now implicit resolution can do a variety of common-sense things, e.g. (A, B, C) ⇒ Foo, Foo ⇒ A, Foo ⇒ B, Foo ⇒ C
In particular, the derive*
functions let the implicit resolver “chase arrows” recursively; here’s a fiddle that takes it a step further.
Is there a name for this pattern? Are there existing macros that can help?
Thanks in advance for any suggestions!