trait User {
type Id
}
final class MyUser extends User {
def sayHi = println("Hi!")
def sayBye(id: Id) = println("Bye!")
}
(new MyUser).sayHi
I have an abstract type Id which is not initialized. When I try to run this code I have no messages telling me that ID is not initialized.
I have an error when try to invoke the method utilizing the type, which shows the error (new MyUser).sayBye
Is that expected behavior even class is final?
As for me it should fail on compilation by seeing that I am creating object but there is still some uninitialized abstract types. Say you write a library and forgot to initialize some types, only library users can catch that error and can’t fix that immediately as they use the code as dependency
Abstract types are always ‘initialized’, type Id is a valid type and is a syntax sugar for type Id >: Nothing <: Any. See What's in a type alias for details / previous discussion.
Is this in the context of some Scala contribution you’re working on? If it is, please make the context clear. If it isn’t, please use https://users.scala-lang.org for questions
I remember we went back and forth over this in the early days of Scala. In the end, there was no reason to demand that an abstract type should be resolved to an alias in a concrete class. Type-theoretically, we only have to require that the type could be instantiated, so there are no inconsistent bounds.
On the one hand, it could make for a good warning/lint on the method, something like “method sayBye can never be called because it requires a value of final abstract type Id” . The case where it’s defined in a final class is especially strong.
On the other, there already is a warning, id is unused. It can’t be used for exactly the same reasons it can’t be called. Sending the user on some puzzle track through unused to the source of the problem isn’t ideal, but this doesn’t strike me as a huge deal.
It could also be used in a more principled way if Id had an upper bound other than Any.
Such an Id type could also be a useful phantom type (where it would appear in parameters or tags of other types), where it’s on purpose that the type does not have a precise definition.
I think we’re on the same page here: a warning is only useful if the method is uncallable. In a phantom type, the type doesn’t appear as the parameter of a method.