14 Aug 2012 01:19
Re: Towards Scala 3
Rex Kerr <ichoran <at> gmail.com>
2012-08-13 23:19:19 GMT
2012-08-13 23:19:19 GMT
On Mon, Aug 13, 2012 at 6:50 PM, Alexander Kuklev <akuklev <at> gmail.com> wrote:
I was just explaining what happened now, and why one might want something better.
I don't think you quite understood my proposal. My question is: what is the type of t in f[T](t: T) before the generic is made specific? Your answer is: a type in a custom trait. My answer is: sure, but you don't need a separate trait each time; you just need one marker/wrapper trait--let's call it G. Then
G[T] => R
is shorthand for
Function1[G[T],R] {
def apply[T](t: T) => R
}
where G[T] pushes genericity from the class level to the method level (which with erasure can be both rigorously and trivially done).
Mon, 2012-08-13 <at> 22:57:06 UTC+2, Rex Kerr:Also, it would be nice to be able to have functions that can take generic type parameters:
def f[T](t: T) = t
f _ // Tell me, do you honestly want Nothing => Nothing here?!
I missed this. In the proposal above, functions can have generic type parameters.The function you wrote would have the type {type T; val t: T} => T. (I omit annotations for brevity.)
I was just explaining what happened now, and why one might want something better.
But the more parsimonious solution to that is to have an appropriate type-level encoding (e.g. Generic[T]):
val g: Function1[Generic[T],Generic[T]] = f _
// g is instantiated to have def apply[T](t: T): T
I have considered type level encodings instead of annotations <at> Param and <at> Arg. Something like representing trait F[T] = {...} as trait F extends Generic1 = {private type T = super._1}, and trait ArgListOfF extends Tuple2 {val x: Int = super._1, val y: Int = super._2} for argument list of f(x: Int, y: Int). Unfortunately, there are two issues:a) we need renaming rather than copying, something like trait F extends Generic1 = {type super._1 as T} and {val super._1 as x: Int},b) it doesn't work really well with inheritance. Often we inherit from two different generic types trait F[A, B] extends X[A] with Y[B], if both X[_] and Y[_] now inherit from Generic1, how could we prevent the name conflict?
I don't think you quite understood my proposal. My question is: what is the type of t in f[T](t: T) before the generic is made specific? Your answer is: a type in a custom trait. My answer is: sure, but you don't need a separate trait each time; you just need one marker/wrapper trait--let's call it G. Then
G[T] => R
is shorthand for
Function1[G[T],R] {
def apply[T](t: T) => R
}
where G[T] pushes genericity from the class level to the method level (which with erasure can be both rigorously and trivially done).
I don't think we want named parameters on functions; type-matching seems like a much more useful generalization than argument-name matching.Could you elaborate on this? What type matching and argument-name matching do you mean?
I mean that duplicate: (Int, String) => String is plenty of information for an interface. You shouldn't need to know that Int was called n and String was called original--it clutters up the interface with dummy symbols. What is the class corresponding to the supertype of the functions corresponding to these two methods?
def f1(s: String): Int
def f2(name: String): Int
By encoding these names into the trait it seems like you are presuming that I couldn't want to abstract across these two functions.
But I do. Almost surely I do.
You've got the annotation backwards, I think:
trait ThreeArgs[T] extends (T,Int,Int) with FnArg {
<at> named("t") val _1: T
<at> named("a") val _2: Int
<at> named("b") val _3: Int = 0
}
This is pretty much just tuple/function-arg unification.
--Rex
RSS Feed