- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Trait and use of super
Wed, 2010-10-13, 19:13
All,
I am trying the following:
scala> class Foo {
| def doStuff() {}
| }
defined class Foo
scala> trait Bar {
| this: Foo =>
|
| override def doStuff() {
| super.doStuff()
| }
| }
:10: error: value doStuff is not a member of java.lang.Object
with ScalaObject
super.doStuff()
^
Since my trait Bar is guaranteed to augment a Foo which defines
doStuff(), I thought I would be able to access super.doStuff().
Is this by design? Any simple workaround except having Bar extends
Foo, which I don't want?
-Erik
Wed, 2010-10-13, 20:17
#2
Re: Trait and use of super
trait DoStuff { def doStuff(): Unit }
class Foo {
def doStuff() = { println("foo") }
}
trait Bar extends DoStuff {
this: Foo =>
abstract override def doStuff() = {
super.doStuff()
println("bar")
}
}
scala> (new Foo with Bar).doStuff
foo
bar
scala> (new Foo).doStuff
foo
On 10/13/2010 11:06 AM, Erik Bruchez wrote:
> All,
>
> I am trying the following:
>
> scala> class Foo {
> | def doStuff() {}
> | }
> defined class Foo
>
> scala> trait Bar {
> | this: Foo =>
> |
> | override def doStuff() {
> | super.doStuff()
> | }
> | }
> :10: error: value doStuff is not a member of java.lang.Object
> with ScalaObject
> super.doStuff()
> ^
>
> Since my trait Bar is guaranteed to augment a Foo which defines
> doStuff(), I thought I would be able to access super.doStuff().
>
> Is this by design? Any simple workaround except having Bar extends
> Foo, which I don't want?
>
> -Erik
>
> .
>
Thu, 2010-10-14, 02:57
#3
Re: Trait and use of super
On Wed, Oct 13, 2010 at 12:00 PM, Paul Phillips wrote:
> On Wed, Oct 13, 2010 at 11:06:49AM -0700, Erik Bruchez wrote:
>> scala> trait Bar {
>> | this: Foo =>
>> |
>> | override def doStuff() {
>> | super.doStuff()
>> | }
>> | }
>> :10: error: value doStuff is not a member of java.lang.Object
>> with ScalaObject
>> super.doStuff()
>> ^
>>
>> Since my trait Bar is guaranteed to augment a Foo which defines
>> doStuff(), I thought I would be able to access super.doStuff().
>
> It's a recent change that you can override methods in the self type at
> all. (And I'm not at all sure it was a good change, for reasons brought
> up by ingo a couple months ago.) You shouldn't expect self types to act
> like a substitute for inheritance - since they won't.
Thanks. I need to get my head around that a bit more.
>> Is this by design? Any simple workaround except having Bar extends
>> Foo, which I don't want?
>
> Why not? Maybe you have a good reason, but there are more fallacious
> reasons to avoid that than good ones.
Here Foo contains a lot of stuff. Now if I inherit from Foo, my Bar
trait will inherit all of that. Hence my "I don't want".
But with another trait as suggested by Aaron I should be able to get somewhere.
-Erik
Thu, 2010-10-14, 06:07
#4
Re: Trait and use of super
On Wed, Oct 13, 2010 at 06:46:52PM -0700, Erik Bruchez wrote:
> >> Is this by design? Any simple workaround except having Bar extends
> >> Foo, which I don't want?
> >
> > Why not? Maybe you have a good reason, but there are more fallacious
> > reasons to avoid that than good ones.
>
> Here Foo contains a lot of stuff. Now if I inherit from Foo, my Bar
> trait will inherit all of that. Hence my "I don't want".
This is in the fallacious category to which I referred. Paraphrasing
your email, you wanted trait T2 below as an alternative to T1 because
you don't want to "inherit all of that", is that right?
class A {
def stuff = 5
def moreStuff = 10
def helloStuff = 15
}
trait T1 extends A {
def f = 5
override def helloStuff = 30
}
trait T2 {
self: A =>
def f = 5
override def helloStuff = 30
}
Let's take a look at what comes out the other end:
% javap T1\$class
Compiled from "A.scala"
public abstract class T1$class extends java.lang.Object{
public static int f(T1);
public static int helloStuff(T1);
public static void $init$(T1);
}
% javap T2\$class
Compiled from "A.scala"
public abstract class T2$class extends java.lang.Object{
public static int f(A);
public static int helloStuff(A);
public static void $init$(A);
}
% javap T1
Compiled from "A.scala"
public interface T1 extends scala.ScalaObject{
public abstract int f();
public abstract int helloStuff();
}
% javap T2
Compiled from "A.scala"
public interface T2 extends scala.ScalaObject{
public abstract int f();
public abstract int helloStuff();
}
Do you have some observable distinction in mind when you speak of this
unwanted inheritance?
Thu, 2010-10-14, 13:57
#5
Lazy val and implicit
Hi all,
I would like to define a lazy val
lazy val a = ...XXX: time consuming...
but XXX needs that some type X is ordered, so it seems that is should be
def a(implicit o: Ordering[X]) = ...XXX...
But now it will consume time everytime I'm asking for 'a'.
Is there a construct to have it equivalent to
lazy val a(implicit o: Ordering[X]) = ...XXX...
?
Thanks in advance,
Volker.
Thu, 2010-10-14, 14:07
#6
Re: Lazy val and implicit
lazy val a = {
val o = Ordering[X]; // or = implicitly[Ordering[X]]
...
}
On Thu, Oct 14, 2010 at 2:53 PM, Bardenhorst, Volker Dr.
wrote:
> Hi all,
>
> I would like to define a lazy val
>
> lazy val a = ...XXX: time consuming...
>
> but XXX needs that some type X is ordered, so it seems that is should be
>
> def a(implicit o: Ordering[X]) = ...XXX...
>
> But now it will consume time everytime I'm asking for 'a'.
>
> Is there a construct to have it equivalent to
>
> lazy val a(implicit o: Ordering[X]) = ...XXX...
>
> ?
>
> Thanks in advance,
> Volker.
Thu, 2010-10-14, 14:27
#7
RE: Lazy val and implicit
Hm,
I tried and got
scala> class A[X](x: X, y: X) {
| lazy val a = {
| val o = implicitly[Ordering[X]]
| o.max(x, y)
| }
| }
:7: error: could not find implicit value for parameter e: Ordering[X]
val o = implicitly[Ordering[X]]
Did I miss something?
Cheers,
Volker.
-----Original Message-----
From: Jason Zaugg [mailto:jzaugg [at] gmail [dot] com]
Sent: 14 October 2010 14:56
To: Bardenhorst, Volker Dr.
Cc: scala-user [at] listes [dot] epfl [dot] ch
Subject: Re: [scala-user] Lazy val and implicit
lazy val a = {
val o = Ordering[X]; // or = implicitly[Ordering[X]]
...
}
On Thu, Oct 14, 2010 at 2:53 PM, Bardenhorst, Volker Dr.
wrote:
> Hi all,
>
> I would like to define a lazy val
>
> lazy val a = ...XXX: time consuming...
>
> but XXX needs that some type X is ordered, so it seems that is should
> be
>
> def a(implicit o: Ordering[X]) = ...XXX...
>
> But now it will consume time everytime I'm asking for 'a'.
>
> Is there a construct to have it equivalent to
>
> lazy val a(implicit o: Ordering[X]) = ...XXX...
>
> ?
>
> Thanks in advance,
> Volker.
Thu, 2010-10-14, 14:37
#8
Re: Lazy val and implicit
Am 14.10.2010 um 15:20 schrieb Bardenhorst, Volker Dr.:
> Hm,
>
> I tried and got
>
> scala> class A[X](x: X, y: X) {
> | lazy val a = {
> | val o = implicitly[Ordering[X]]
> | o.max(x, y)
> | }
> | }
> :7: error: could not find implicit value for parameter e: Ordering[X]
> val o = implicitly[Ordering[X]]
>
> Did I miss something?
Your class definition would have to look like
class A[X : Ordering](x: X, y: X) {...}
as otherwise you cannot make sure that such an implicit value exists.
You already need that parameter at instance construction time.
You can of course also write it like this:
class A[X](x: X, y: X)(implicit o: Ordering[X]) {
lazy val a = o.max(x, y)
}
as you always need the Ordering[X] parameter.
Regards,
Moritz
Thu, 2010-10-14, 14:57
#9
RE: Lazy val and implicit
I would like to attach this to the method and val and for the former one I did like this
class A[X](val x: X, val y: X) {
...
bunch of other methods not relying on Ordering[X]
...
def f(that: A[X])(implicit o: Ordering[X]) = o.max(this.x, that.x)
}
And now wonder whether I could have
class A[X](val x: X, val y: X) {
...
bunch of other methods not relying on Ordering[X]
...
def f(that: A[X])(implicit o: Ordering[X]) = o.max(this.x, that.x)
"lazy val a(implicit o: Ordering[X]) = ..."
}
But maybe I'm expecting to much and I just have to use def instead of lazy val
-----Original Message-----
From: Moritz Uhlig [mailto:moritz [dot] uhlig [at] jsolution [dot] de]
Sent: 14 October 2010 15:27
To: Bardenhorst, Volker Dr.
Cc: Jason Zaugg; scala-user [at] listes [dot] epfl [dot] ch
Subject: Re: [scala-user] Lazy val and implicit
Am 14.10.2010 um 15:20 schrieb Bardenhorst, Volker Dr.:
> Hm,
>
> I tried and got
>
> scala> class A[X](x: X, y: X) {
> | lazy val a = {
> | val o = implicitly[Ordering[X]]
> | o.max(x, y)
> | }
> | }
> :7: error: could not find implicit value for parameter e: Ordering[X]
> val o = implicitly[Ordering[X]]
>
> Did I miss something?
Your class definition would have to look like
class A[X : Ordering](x: X, y: X) {...}
as otherwise you cannot make sure that such an implicit value exists.
You already need that parameter at instance construction time.
You can of course also write it like this:
class A[X](x: X, y: X)(implicit o: Ordering[X]) {
lazy val a = o.max(x, y)
}
as you always need the Ordering[X] parameter.
Regards,
Moritz
Thu, 2010-10-14, 15:37
#10
Re: Lazy val and implicit
Possibly a little off but for stuff that takes time I think a Future
is better, so
... {
Private[this] Val f = ... // makes a future
Lazy val a = f.get // or whatever gets you the future value...
...
}
That does wonders for responsiveness, eh?
Cheers,
Razie
On 10/14/10, Bardenhorst, Volker Dr. wrote:
> Hi all,
>
> I would like to define a lazy val
>
> lazy val a = ...XXX: time consuming...
>
> but XXX needs that some type X is ordered, so it seems that is should be
>
> def a(implicit o: Ordering[X]) = ...XXX...
>
> But now it will consume time everytime I'm asking for 'a'.
>
> Is there a construct to have it equivalent to
>
> lazy val a(implicit o: Ordering[X]) = ...XXX...
>
> ?
>
> Thanks in advance,
> Volker.
Thu, 2010-10-14, 16:07
#11
RE: Lazy val and implicit
Dr. Volker Bardenhorst wrote:
> But maybe I'm expecting to much and I just have to use def instead of
> lazy val
If you'd use a def, you could still cache the computed value, e.g.:
class A[X](val x: X, val y: X) {
private[this] var fResult: Option[X] = None
def f(that: A[X])(implicit o: Ordering[X]) = synchronized {
fResult getOrElse {
val n = o.max(this.x, that.x)
fResult = Some(n)
n
}
}
}
That's not really pretty though.
-
Andreas
Thu, 2010-10-14, 16:27
#12
RE: Lazy val and implicit
Yes, not really pretty but also not really ugly, thanks a lot
-----Original Message-----
From: Andreas Flierl [mailto:andreas [at] flierl [dot] eu]
Sent: 14 October 2010 16:53
To: Bardenhorst, Volker Dr.
Cc: scala-user [at] listes [dot] epfl [dot] ch
Subject: RE: [scala-user] Lazy val and implicit
Dr. Volker Bardenhorst wrote:
> But maybe I'm expecting to much and I just have to use def instead of
> lazy val
If you'd use a def, you could still cache the computed value, e.g.:
class A[X](val x: X, val y: X) {
private[this] var fResult: Option[X] = None
def f(that: A[X])(implicit o: Ordering[X]) = synchronized {
fResult getOrElse {
val n = o.max(this.x, that.x)
fResult = Some(n)
n
}
}
}
That's not really pretty though.
-
Andreas
Thu, 2010-10-14, 17:47
#13
Re: Lazy val and implicit
On Thu, Oct 14, 2010 at 7:53 AM, Bardenhorst, Volker Dr. <Volker [dot] Bardenhorst [at] eon [dot] com> wrote:
If your value is parameter dependent, it can't be a single value. What if it was called a second time with a different Ordering? This would be idempotent: def a[X](implicit: o: Ordering[X]) = map.getOrElseUpdate(o, new XXX(o)) // or whatever construction
Is there a construct to have it equivalent to
lazy val a(implicit o: Ordering[X]) = ...XXX...
If your value is parameter dependent, it can't be a single value. What if it was called a second time with a different Ordering? This would be idempotent: def a[X](implicit: o: Ordering[X]) = map.getOrElseUpdate(o, new XXX(o)) // or whatever construction
Thu, 2010-10-14, 18:07
#14
RE: Lazy val and implicit
good point,
does it mean that my class A orginal intendend to be
immutabel is broken here to mutable?
using Andreas' solution:
From: Nils Kilden-Pedersen [mailto:nilskp [at] gmail [dot] com]
Sent: 14 October 2010 18:37
To: Bardenhorst, Volker Dr.
Cc: scala-user [at] listes [dot] epfl [dot] ch
Subject: Re: [scala-user] Lazy val and implicit
On Thu, Oct 14, 2010 at 7:53 AM, Bardenhorst, Volker Dr. <Volker [dot] Bardenhorst [at] eon [dot] com> wrote:
If your value is parameter dependent, it can't be a single value. What if it was called a second time with a different Ordering? This would be idempotent: def a[X](implicit: o: Ordering[X]) = map.getOrElseUpdate(o, new XXX(o)) // or whatever construction
class A[X](val x: X, val y: X) {
private[this] var fResult: Option[X] = None
def f(that: A[X])(implicit o: Ordering[X]) = synchronized {
fResult getOrElse {
val n = o.max(this.x, that.x)
fResult = Some(n)
n
}
}
}
seems to imply "first ordering serves first". Is that then slightly immutable? When it is possible to fix the Ordering of some type (what is suitable for my purposes) is it then immutable again?
probably I have to think about my construction
cheers
From: Nils Kilden-Pedersen [mailto:nilskp [at] gmail [dot] com]
Sent: 14 October 2010 18:37
To: Bardenhorst, Volker Dr.
Cc: scala-user [at] listes [dot] epfl [dot] ch
Subject: Re: [scala-user] Lazy val and implicit
On Thu, Oct 14, 2010 at 7:53 AM, Bardenhorst, Volker Dr. <Volker [dot] Bardenhorst [at] eon [dot] com> wrote:
Is there a construct to have it equivalent to
lazy val a(implicit o: Ordering[X]) = ...XXX...
If your value is parameter dependent, it can't be a single value. What if it was called a second time with a different Ordering? This would be idempotent: def a[X](implicit: o: Ordering[X]) = map.getOrElseUpdate(o, new XXX(o)) // or whatever construction
Mon, 2010-10-18, 01:17
#15
Re: Trait and use of super
> This is in the fallacious category to which I referred. Paraphrasing
> your email, you wanted trait T2 below as an alternative to T1 because
> you don't want to "inherit all of that", is that right?
[snip]
> Let's take a look at what comes out the other end:
Looks pretty similar! I think my root issue was understanding what it
meant for a trait to "extend" a class. Seems like you covered this
here:
http://www.scala-lang.org/node/3112#comment-11558
So both "extends" and self types set a limitation on where a trait can
be instantiated.
Next step: understanding the difference(s) between the two.
-Erik
Mon, 2010-10-18, 01:57
#16
Re: Trait and use of super
On Sun, Oct 17, 2010 at 05:09:08PM -0700, Erik Bruchez wrote:
> So both "extends" and self types set a limitation on where a trait can
> be instantiated.
>
> Next step: understanding the difference(s) between the two.
Some are:
1) Self-types let you form cycles which you can't do via inheritance.
scala> trait T1 { self: T2 => } ; trait T2 { self: T1 => }
defined trait T1
defined trait T2
2) Self-types require all inheriting traits to have a compatible
self-type: traits extending classes impose no similar requirement.
scala> class Q ; trait T1 extends Q ; trait T2 extends T1
defined class Q
defined trait T1
defined trait T2
scala> class Q ; trait T1 { self: Q => } ; trait T2 extends T1
:8: error: illegal inheritance;
self-type T2 does not conform to T1's selftype T1 with Q
class Q ; trait T1 { self: Q => } ; trait T2 extends T1
^
3) Self-types can express constraints which cannot be expressed via
inheritance.
scala> type Bippy = { def bippy(): Int }
defined type alias Bippy
scala> trait T1 { self: Bippy => }
defined trait T1
scala> class A extends T1
:7: error: illegal inheritance;
self-type A does not conform to T1's selftype T1 with Bippy
class A extends T1
^
scala> class A extends T1 { def bippy(): Int = "5" }
:7: error: type mismatch;
found : java.lang.String("5")
required: Int
class A extends T1 { def bippy(): Int = "5" }
^
scala> class A extends T1 { def bippy(): Int = 5 }
defined class A
Mon, 2010-10-18, 18:37
#17
Re: Trait and use of super
>> Next step: understanding the difference(s) between the two.
>
> Some are:
>
> 1) Self-types let you form cycles which you can't do via inheritance.
>
> scala> trait T1 { self: T2 => } ; trait T2 { self: T1 => }
> defined trait T1
> defined trait T2
>
> 2) Self-types require all inheriting traits to have a compatible
> self-type: traits extending classes impose no similar requirement.
>
> scala> class Q ; trait T1 extends Q ; trait T2 extends T1
> defined class Q
> defined trait T1
> defined trait T2
>
> scala> class Q ; trait T1 { self: Q => } ; trait T2 extends T1
> :8: error: illegal inheritance;
> self-type T2 does not conform to T1's selftype T1 with Q
> class Q ; trait T1 { self: Q => } ; trait T2 extends T1
> ^
>
> 3) Self-types can express constraints which cannot be expressed via
> inheritance.
>
> scala> type Bippy = { def bippy(): Int }
> defined type alias Bippy
>
> scala> trait T1 { self: Bippy => }
> defined trait T1
>
> scala> class A extends T1
> :7: error: illegal inheritance;
> self-type A does not conform to T1's selftype T1 with Bippy
> class A extends T1
> ^
>
> scala> class A extends T1 { def bippy(): Int = "5" }
> :7: error: type mismatch;
> found : java.lang.String("5")
> required: Int
> class A extends T1 { def bippy(): Int = "5" }
> ^
>
> scala> class A extends T1 { def bippy(): Int = 5 }
> defined class A
Thanks, that helps!
-Erik
On Wed, Oct 13, 2010 at 11:06:49AM -0700, Erik Bruchez wrote:
> scala> trait Bar {
> | this: Foo =>
> |
> | override def doStuff() {
> | super.doStuff()
> | }
> | }
> :10: error: value doStuff is not a member of java.lang.Object
> with ScalaObject
> super.doStuff()
> ^
>
> Since my trait Bar is guaranteed to augment a Foo which defines
> doStuff(), I thought I would be able to access super.doStuff().
It's a recent change that you can override methods in the self type at
all. (And I'm not at all sure it was a good change, for reasons brought
up by ingo a couple months ago.) You shouldn't expect self types to act
like a substitute for inheritance - since they won't.
> Is this by design? Any simple workaround except having Bar extends
> Foo, which I don't want?
Why not? Maybe you have a good reason, but there are more fallacious
reasons to avoid that than good ones.