Why instances cannot be instantiated from traits directly in Scala 3


Scala 3 allows traits to have parameters, which make traits to be more similliar to classes.
But why does Scala 3 not allow to instatiate instances from a trait directly? Now to create an instance for a trait, a class must be first derived from the trait explicitly or implicitly.



correct me if i’m wrong, but I believe its due to the underlying type of Trait vs Class

classes are types with implicit constructors, whose instances are scala objects

traits are abstract interfaces used to provide and require members to be implemented by other entities

I believe you are referring to this:

scala> class A
// defined class A

scala> trait B
// defined trait B

scala> new A
val res0: A = A@72512218

scala> new B
-- Error:
1 |new B
  |    ^
  |    B is a trait; it cannot be instantiated

scala> new B {}
val res1: B = anon$1@26905a3f

So in other words, you’ll have to add empty braces {} when instantiating a trait. Personally I find it odd and a bit of an annoyance.

That’s not at all strange as you’re creating an anonymous subclass of B
This is equivalent to JAVA:

jshell> public interface A{};
|  created interface A
jshell> new A(){}
$3 ==> $0@5b6f7412

Well, as per language definition all values are objects and all objects are instances of a class

Why is that? I would say it is either because it has always be like that or because it is simpler. There may be a foundational reason but I doubt.

Now, sincerely, since all you need is an empty body ({}) I don’t think it is a big deal.
Anyways, a trait with arguments but that is concrete is weird.

Note that this reflects the semantics of the JVM platform itself. A trait at the language level becomes an interface at the JVM bytecode level and the JVM doesn’t allow interfaces to be instantiated directly, only classes.

(Regardless, the compiler could treat new B as if it were new B {} or new AnyRef with B, and I don’t see any strong reason it shouldn’t. Except possibly a concern with the overall amount of syntactic sugar in the language?)

Just for the record, that is what I mean with simpler.

I personally don’t think the language has to care about runtime limitations, especially given it is technically multi-platform.
But, I do understand this “limitation” could simplify the language and compiler; or maybe not, and is just an oversight as you mention.

Is also traditional on all languages I know that interfaces are not directly instantiable.

For much that I dislike the excessive amount of sugar syntax in the language, I don’t think this one would be a big deal.

Maybe, I would be more worried about possible error messages, but I can’t think of a good example.

Anyways, I still think the demand for this should be small. A concrete trait is weird IMHO (but it may be just because I am not so fond of inheritance)