0

Is it possible to parameterize one or more traits for mixing? My example below doesn't compile, but IntelliJ's intellisense does actually come up with the correct types.

class Student
class Students[A <: Student] {

  def create = new Student with A
}

trait Major extends Student
trait Dormitory extends Student
trait Fraternity extends Student

val onCampus = new Students[Major with Dormitory]
val fratBoys = new Students[Major with Fraternity]

onCampus.create // is a: Student with Major with Dormitory
fratBoys.create // is a: Student with Major with Fraternity
Richard Pianka
  • 3,317
  • 2
  • 28
  • 36
  • Your new class `Student with A` does not define default constructor. You can change function to `def create = new A` and it is more readable. Compiler does not know A class - and it can not create object for you. If A class? trait? function? – Andrzej Jozwik Nov 04 '13 at 08:25
  • 1
    It's a contrived example to illustrate the thing I'm asking about. – Richard Pianka Nov 05 '13 at 21:45

1 Answers1

1

It is impossible to mix traits dynamically because the Scala compiler generates a new anonymous class per mixin to support this functionality on the JVM:

scala> trait A
defined trait A

scala> trait B
defined trait B

scala> new A with B
res0: A with B = $anon$1@40f8335a

There are several similar questions to this one with detailed answers on why it's impossible dynamically and how it can be done (but really should not!) using macros.

Mixing in a trait dynamically

Dynamic mixin in Scala - is it possible?

How do I create an instance of a trait in a generic method in scala?

Community
  • 1
  • 1
tzbob
  • 131
  • 4
  • Maybe I'm misunderstanding something subtle, but I'm not looking for mixing at runtime. In my contrived example, I would expect the compiler to create four anonymous classes: a "`Student with Major with Dormitory`" class, a "`Student with Major with Fraternity`" class, a "`Students`" class that returns the former from `create`, and a "`Students`" class that returns the latter from `create`. – Richard Pianka Nov 05 '13 at 21:49
  • That is nog how type parameters work, after a valid type check of the program your A parameter is erased (Google type-erasure). The type-checker will not generate separate classes for your cases A=Major with Dormitory, etc. making it impossible to instantiate your class because the required information is lost. Long story short it's impossible to mix in traits dynamically because the information required is only available during type checking and it is not the type checker's job to create the anonymous classes. – tzbob Nov 06 '13 at 06:47
  • I edited my answer to mixing dynamically and not at runtime to avoid confusion. – tzbob Nov 06 '13 at 06:52
  • For what it's worth, Scala preserves metadata about parameterized types if you go digging with reflection -- though the JVM obviously won't so it's sort of a moot point. That said, it seems totally conceivable that the compiler could generate classes in the way I described; that it doesn't is a specification/implementation detail. In any case, thanks. – Richard Pianka Nov 09 '13 at 01:09