Uninitialized abstract types

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

3 Likes

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

1 Like

I am sorry @SethTisue That wasn’t a questions, I thought that it is kind of bug and therefore decided to report it here.

Thanks

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.

1 Like

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 be used though. For instance as println(s"Bye $id!").

2 Likes

This is why we can’t have nice things.

2 Likes

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.

1 Like