overriding vars

54 views
Skip to first unread message

Paul Phillips

unread,
Mar 20, 2012, 2:16:01 PM3/20/12
to martin odersky, scala-l...@googlegroups.com
It was an interesting revelation that the inability to override vars
is not in the spec and is in question.

class A {
var x = 1
def y = this.x
}

class B extends A {
override def x = 2
def z = super.x
}

That one doesn't compile unless I also disable another check of unknown origin:

if (sym.isValue && !sym.isMethod || sym.hasAccessorFlag) {
unit.error(tree.pos, "super may be not be used on "+ sym.accessedOrSelf)
}

Then it does, and B and A have the clever arrangement where A can
never see what x has been set to, only B can by way of super.x. This
felt strange initially but I suppose it's the same for overridden
methods.

I am sure things break down somewhere with nontrivial examples
(possibly the sufficiently early visibility of the getter/setter) but
as it made it this far with no effort, I'm bringing it up. Hey
scala-language, what are the arguments for/against allowing the
overriding of vars?

This also works on first blush:

class C { var w = 1 }
class D extends C { override var w = 2 }

leading to the expected

class C extends scala.AnyRef {
private[this] var w: Int = 1;
<accessor> def w: Int = C.this.w;
<accessor> def w_=(x$1: Int): Unit = C.this.w = x$1
};
class D extends C {
private[this] var w: Int = 2;
override <accessor> def w: Int = D.this.w;
override <accessor> def w_=(x$1: Int): Unit = D.this.w = x$1
}

martin odersky

unread,
Mar 20, 2012, 6:55:17 PM3/20/12
to Paul Phillips, scala-l...@googlegroups.com
Yes, I think all this will require a bit of archeology to get at the
real reasons. Either way would be OK with me. We can disallow
overriding of vars in the spec, or allow them in the compiler. But the
fact that this is currently disallowed in the compiler indicates that
there probably were some problems with it.

Cheers

- Martin

--
Martin Odersky
Prof., EPFL and Chairman, Typesafe
PSED, 1015 Lausanne, Switzerland
Tel. EPFL: +41 21 693 6863
Tel. Typesafe: +41 21 691 4967

Daniel Sobral

unread,
Mar 20, 2012, 7:00:14 PM3/20/12
to scala-l...@googlegroups.com, martin odersky

Arguments for: it makes the language seem more regular/predictable. I
have no idea what it would entail specification-wise, but, from a S.O.
point of view, it goes like this:

* Scala's vals are really a field plus a getter, with the guarantee
that it will always return the same value.
* Scala's vars are really a field plus a getter and a setter.
* This is done this way because of uniform access principle. One can
latter change a var/val with a def and not have any client code
changed, not even recompiled.

"So I can override a var with a getter and a setter?"

* No, you can't.

"Why?"

* Err...

Likewise, I personally dislike not being able to override a val with a
def, but at least I have some reason to explain it away.

--
Daniel C. Sobral

I travel to the future all the time.

Kevin Wright

unread,
Mar 20, 2012, 9:01:00 PM3/20/12
to scala-l...@googlegroups.com, martin odersky
I can imagine all sorts of difficulty if you override a var with defs and then pass the resulting object to some framework that accesses the underlying field through reflection.  Hibernate and co would be examples of this kind of trickery.

To be fair though, you also get into the same problem overriding a var with a var.  Perhaps the right approach would be to outright forbid the overriding of any non-abstract var by any mechanism whatsoever.

Taking due care, of course, to ensure that such a restriction doesn't harm Java interop - especially our ability to inherit from existing Java classes.
--
Kevin Wright
mail: kevin....@scalatechnology.com
gtalk / msn : kev.lee...@gmail.com
vibe / skype: kev.lee.wright
steam: kev_lee_wright

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra

Daniel Sobral

unread,
Mar 20, 2012, 9:17:26 PM3/20/12
to scala-l...@googlegroups.com, martin odersky
On Tue, Mar 20, 2012 at 22:01, Kevin Wright <kev.lee...@gmail.com> wrote:
> I can imagine all sorts of difficulty if you override a var with defs and
> then pass the resulting object to some framework that accesses the
> underlying field through reflection.  Hibernate and co would be examples of
> this kind of trickery.

I can imagine all sort of difficulty if you use a framework that
accesses fields through reflection. I see no reason why *I* should
suffer for that.

Reply all
Reply to author
Forward
0 new messages