2

Given:

abstract class A { def show: Unit }
trait T extends A {
  abstract override def show: Unit = {
    print(" T"); super.show; print(" xT")
  }
}
trait U extends A {
  abstract override def show: Unit = {
    print(" U"); super.show; print(" xU")
  }
}
class C extends A {
  def show: Unit = print(" C")
}

I can do:

new C with T with U show

But, it "feels" (given Scala's propensity for shortened syntaxes and anonymous stuff in general) like I might be able to instantiate my mixed in class from an anonymous form. Something on the lines of

// doesn't work like this at least:
val a = new { def show { print("Anon")}} with T with U
a show

But I have entirely failed to determine if I'm simply using the wrong syntax, or if this is simply not possible. Can someone tell me how this should be done, or if it definitely is not possible?

Toby Eggitt
  • 1,806
  • 19
  • 24
  • 1
    This seems somewhat relevant: http://www.scala-lang.org/old/node/3199 Back then, they came to the conclusion that it's easier to use simple composition in favor of trait mixins. – Andrey Tyukin Jan 21 '18 at 18:16
  • Interesting discussion, thanks! Yes, looks like they're saying the syntax isn't possible. It's also interesting that they seem to be questioning the merits of the goal, suggesting that a composition approach is probably preferable to a compile-time structure. I was wondering the same thing, though hadn't gotten far enough into my investigation to really be confident either way. – Toby Eggitt Jan 21 '18 at 18:46

2 Answers2

2

I don't think this is possible.

The following two proposals are as close as I can get.

Use Constructor with Mixins

The following solution requires an additional helper class D, but the end result looks almost as your fictional syntax, except that you need one additional character for D, and you have to use round parentheses instead of curly braces:

import scala.language.postfixOps

abstract class A { def show: Unit }
trait T extends A {
  abstract override def show: Unit = {
    print(" T"); super.show; print(" xT")
  }
}
trait U extends A {
  abstract override def show: Unit = {
    print(" U"); super.show; print(" xU")
  }
}
class C extends A {
  def show: Unit = print(" C")
}

new C with T with U show

class D(s: => Unit) extends A {
  def show = s
}

// that's pretty close, isn't it?
val a = new D(print("hurray!")) with T with U
a show

Just hide the class in a block

If you just don't want to litter the namespace with classes that you use only once, then just enclose the class in a block:

val a = {
  class D extends A {
    def show = println("NoPollution")
  }
  new D with T with U
}
a show

What you wanted is to "eliminate the useless variable D" in the above "class-valued compile-time-evaluated-expression", but I don't see how one could do that.

Andrey Tyukin
  • 43,673
  • 4
  • 57
  • 93
  • Well, it looks like nobody wants to suggest that this is possible, so I guess that makes your answer the accepted one. Thanks for the input! – Toby Eggitt Jan 24 '18 at 02:25
0

Isn't this what you want?

val a = new T with U {override def show { print("Anon")}}

Syntax is pretty much the same as with declaring a new class, first the extensions/mixins, then the body.

leyren
  • 524
  • 6
  • 20