Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instantiation of a single trait vs a mixin

Tags:

scala

Any idea why I cannot create an instance of a single trait, without providing a class body:

trait MyTrait
val test1 = new MyTrait // Does not compile.
val test2 = new MyTrait {} // Compiles.

But if I add another one into the mix then I will be able to create an instance:

trait MyTrait
trait SecondTrait
val anotherTest = new SecondTrait with MyTrait  // Compiles successfully.

I would have expected the same behavior.

Side note: I already had read this question. But the presence of the trait body does not answer my problem, as the second example still does not have a body. Thus, why does the compiler consider the second example as an anonymous class?

like image 620
humbletrader Avatar asked Mar 20 '19 19:03

humbletrader


1 Answers

The specification for Instance Creation Expressions says:

A simple instance creation expression is of the form new c where c is a constructor invocation. Let T be the type of c. Then T must denote a (a type instance of) a non-abstract subclass of scala.AnyRef...

A general instance creation expression is of the form new t for some class template t. Such an expression is equivalent to the block { class a extends t; new a } where a is a fresh name of an anonymous class which is inaccessible to user programs.

In new MyTrait, MyTrait is syntactically a legal constructor invocation. So new MyTrait is a simple instance creation expression which fails to compile because MyTrait doesn't "denote a non-abstract subclass of scala.AnyRef".

But SecondTrait with MyTrait can't be a constructor invocation, so it's treated as a class template for a general instance creation expression, which creates an anonymous class. The same applies to MyTrait {}.

like image 82
Alexey Romanov Avatar answered Oct 25 '22 10:10

Alexey Romanov