Hello,
In the context of my master semester project, I’m implementing Clause Interweaving, I would like to have your feedback!
What it is:
It allows methods to have more than one type parameter clause, and for them to be arbitrarily interwoven with other clauses, basically a generalization of type currying:
//from
def foo[T,U](x: T)(y: U): Z
//to:
def bar[T](x: T)[U](y: U): Z
Note that at the use site, this behave very similarly to something already valid, but inelegant like:
def bar[T](x: T): { def apply[U](y: U): Z }
The only difference being overloading resolution, where the new system allows access to U
and y
where the old one doesn’t.
The full technical details can be found it this PR to the scala 2 doc (as there is no scala 3 doc yet):
Upsides:
Dependent methods:
The new syntax allows a clean way to have type parameters depend on values like this:
trait Key { type Value }
trait DB {
def getOrElse(k: Key)[V >: k.Value](default: V): V
}
Omitting obvious types:
It allows us to separate types parameters the compiler can infer from the ones it can’t, for example:
trait Function[Arity <: Int & Singleton, Return]
def constant[A <: Int & Singleton][R](x: R): Function[A,R] = ???
In constant
, A
is impossible to infer if there is no expected type, so we have to specify it, however, the R
can always be inferred, since we curried them, we can specify only A
like so:
val oneInputToZero = constant[1](0) // A = 1, inferred: R = Int
// Type: Function[1, Int]
Restricions
Classes and types must still have at most one type parameter clause, and it has to be the first one, this might be confusing to users.
The behaviour at constructor-call-site can still be emulated for classes through a constructor proxy:
class MyClass[T,U](x: T, y: U){...}
object MyClass{
def apply[T](x: T)[U](y: U) = new MyClass(x, y)
}
Conclusion
I hope you find this feature useful, and am happy to answer any questions !
I believe this feature represents a somewhat dramatic change, and as such I expect people will have strong opinions about it, if you have any thoughts or feelings about this change, please share them here.
This will help getting a feel for how the community at large would react !