trait Bar {
def bar(): Int
}
trait Twice extends Bar {
abstract override def bar(): Int = super.bar() * 2
}
class Foo {
def bar(): Int = 42
} with Twice
I'm not sure why this syntax isn't available in Scala currently, but is there any chance to get it included in Dotty?
--
You received this message because you are subscribed to the Google Groups "dotty-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dotty-interna...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Sorry, I thought that was obvious.
Because it would be nice to provide a class that already has the trait mixed-in, so you don’t have to do that every single time you do new
.
So let me ask the opposite question: Why would you be satisfied with having to manually apply a trait, when a solution could exist that had it mixed-in by default?
:)-0xe1a
I think you'd probably just want to use trait parameters for that:
trait Bar(bars: Int) {
def bar: Int = bar
}
trait Twice extends Bar {
override def bar: Int = super.bar *2
}
class Foo extends Twice with Bar(42)
So, are you saying that instead of having Bar
s methods be abstract, they should instead be implemented by delegating to trait parameter functions?
I guess that would work, but at the cost of a rather weird syntax. And also, the trait no longer works as an abstract override, so I probably have to define it twice (no pun intended).
Also, let’s make the example a little more realistic:
trait Bar(_calculate: (Double, Double, Double) => Double, _process: (Int, String) => Long) {
def calculate(x: Double, y: Double, z: Double): Double = _calculate(x, y, z)
def process(a: Int, b: String): Long = _process(a, b)
}
trait Twice {
def calculate(x: Double, y: Double, z: Double): Double = super.calculate(x*2, y*2, z*2)
def process(a: Int, b: String): Long = _process(a*2, b+b)
}
object Foo {
def calculate(x: Double, y: Double, z: Double): Double = {
// Complex calculation
}
def process(a: Int, b: String): Long = {
// Lengthy process
}
}
class Foo extends Twice with Bar(Foo.calculate, Foo.process)
So boilerplatey I almost long for Java.
So, is there any good reason why my first example, which is succinct, readable, and, I think, clearly understood, isn’t, or shouldn’t be, allowed syntax?
:):)-0xe1a
On Thursday, July 21, 2016 at 10:25:13 AM UTC+2, Nils Kilden-Pedersen wrote:I'm not sure why this syntax isn't available in Scala currently, but is there any chance to get it included in Dotty?trait Bar { def bar(): Int } trait Twice extends Bar { abstract override def bar(): Int = super.bar() * 2 } class Foo { def bar(): Int = 42 } with Twice
First of all, I think this example can be encoded as:trait FooT extends Bar {def bar(): Int = 42}class Foo extends FooT with TwiceThat encoding is much more faithful. Is there some example where it's not enough? (I might have a different one below).
Well, it’s sort of annoying having to make two declarations, when the syntax could be made available for that not to be necessary.
However, my example was probably poor, as I feel this is more an annoyance when dealing with anonymous classes that need some trait behavior applied.
So, e.g. this would be nice:
def newBar(b: Int): Bar = new Bar { def bar = b } with Twice
Instead, I have to do this:
def newBar(b: Int): Bar = {
class AnonBar extends Bar {
def bar = b
}
new AnonBar with Twice
}
Not the end of the world, but the syntax seems inconsistent, and it’s more noisy boiler-plate.
I also think I got where you're coming from. If we pretended thatclass Name extends SuperTraits { body }simply meanttype Name = SuperTraits with { body }Now, it also makes sense to have:type Name = { body } with SuperTraitsSo by analogy we could want:
class Name { body } with SuperTraitsHowever, the JVM translation gives a special place to { body }, since the JVM doesn't support mixins directly.* This example relies on abstract override, because otherwise
class Foo extends Twice {def bar(): Int = 42}would work (and I'm not sure it won't work here).* A related annoyance (which gets in the way when using the cake pattern) is that SuperTraits must be trait or class names, not names of types that immediately expand to (refined) traits. I've run into that limitation somewhat, and that should be fixable. Concretely, you can't do:type Blip = Bar with { type T = Baz }class Foo extends BlipYou can trytrait Blip extends Bar { type T = Baz }class Foo extends Blipbut then new Bar { type T = Baz } is not a subtype of Blip, and this gets in the way sometimes.
--
You received this message because you are subscribed to the Google Groups "dotty-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dotty-internals+unsubscribe@googlegroups.com.