-
Notifications
You must be signed in to change notification settings - Fork 14
use FunctionalInterface
to indicate trait
cannot have a constructor, or violate other SAM type conditions
#197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Noting some overlap with universal traits, in which
|
ref #191 |
what's the proposal exactly? that the compiler automatically adds |
I take it to mean that if a trait is so annotated, we'll a) error if a constructor is required, b) error if any ancestor has a constructor and c) allow LMF to use it as a lambda target type. |
Maybe FI is the wrong annotation to mark this, though |
It seems unfortunate to me that the user is required add an annotation in order to get the LMF translation. |
Separate compilation and the generality of traits are the thorns in our side. We might be able to do better down the track with a You could even implement fields in the same manner. |
That sounds interesting! Maybe at some point having our own LMF will solve enough issues for us to consider it. But back to the proposal. Suppose I write |
Let's call the annotation
Traits are super fragile with separate compilation, but the current scheme allows you to add side effects to the constructor of a trait without recompiling subclasses. There is just the one special case that if a trait has no method bodies in its decls, the The closest thing we have to this today is |
For the record, Dotty uses |
With dotty, compile: trait T
trait U extends T { def apply(a: Any): Any }
object Test {
def main(args: Array[String]): Unit = {
val u: U = x => x
assert(u("") == "")
}
} Then, recompile trait T { throw new Exception("hello?") } Rerunning Dotty does seem to respect ancestors when computing whether to use trait T { ??? }
trait U extends T { def apply(a: Any): Any }
object Test {
def main(args: Array[String]): Unit = {
val u: U = x => x // new Test$$anonfun$2
assert(u("") == "")
}
}
|
This is conceptually the same as in Java: // run 1
interface I {}
class C implements I {} class I This would result in an |
to deal with no-op constructors gratuitously being added, ruining a trait's potential as a SAM
The text was updated successfully, but these errors were encountered: