I'm going to take one last swing at this and then wash my hands of it
forever. If I'm the only guy who thinks this is wrong, well it won't
be the first time that's happened. Your silence will tell me all I
need. But if anybody ELSE thinks this is wrong, then maybe you'd like
to take the ball a while because I just washed my hands and that ball
is grimy.
class A(var bippy: Int) { def f1 = "A.bippy = " + bippy }
class B(bippy: Int) extends A(bippy) { def f2 = "B.bippy = " + bippy }
class C(dingus: Int) extends B(dingus) { def f3 = "C.bippy = " + bippy }
val c = new C(10)
List(c.f1, c.f2, c.f3) foreach println
c.bippy = 123123
List(c.f1, c.f2, c.f3) foreach println
Do you know what this prints? Is there any question in your mind? Here
is what it prints.
A.bippy = 10
B.bippy = 10
C.bippy = 10
A.bippy = 123123
B.bippy = 10
C.bippy = 123123
That's it, I'm done. The ticket is
https://issues.scala-lang.org/browse/SI-4762 if anyone wants a piece
of it.
[scalacfork] Compiling 46 files to /scratch/trunk1/build/quick/classes/library
[scalacfork] /scratch/trunk1/src/actors/scala/actors/ActorTask.scala:35:
warning: private[this] value msg in class ActorTask shadows mutable
msg inherited from class ReactorTask. Changes to msg will not be
visible within class ActorTask - you may want to give them distinct
names.
[scalacfork] if (msg != null)
Some(msg) else None,
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/actors/scala/actors/ActorTask.scala:35:
warning: private[this] value msg in class ActorTask shadows mutable
msg inherited from class ReactorTask. Changes to msg will not be
visible within class ActorTask - you may want to give them distinct
names.
[scalacfork] if (msg != null)
Some(msg) else None,
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/actors/scala/actors/ReplyReactorTask.scala:26:
warning: private[this] value reactor in class ReplyReactorTask shadows
mutable reactor inherited from class ReactorTask. Changes to reactor
will not be visible within class ReplyReactorTask - you may want to
give them distinct names.
[scalacfork] Actor.tl set reactor
[scalacfork] ^
[scalacfork] three warnings found
[scalacfork] /scratch/trunk1/src/compiler/scala/reflect/internal/pickling/UnPickler.scala:116:
warning: private[this] value bytes in class Scan shadows mutable bytes
inherited from class PickleBuffer. Changes to bytes will not be
visible within class Scan - you may want to give them distinct names.
[scalacfork] val tag = bytes(index(i)).toInt
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/reflect/internal/pickling/UnPickler.scala:123:
warning: private[this] value bytes in class Scan shadows mutable bytes
inherited from class PickleBuffer. Changes to bytes will not be
visible within class Scan - you may want to give them distinct names.
[scalacfork] val tag = bytes(index(i))
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/reflect/internal/pickling/UnPickler.scala:129:
warning: private[this] value bytes in class Scan shadows mutable bytes
inherited from class PickleBuffer. Changes to bytes will not be
visible within class Scan - you may want to give them distinct names.
[scalacfork] val tag = bytes(index(i)).toInt
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/reflect/internal/pickling/UnPickler.scala:135:
warning: private[this] value bytes in class Scan shadows mutable bytes
inherited from class PickleBuffer. Changes to bytes will not be
visible within class Scan - you may want to give them distinct names.
[scalacfork] val tag = bytes(index(i)).toInt
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/reflect/internal/pickling/UnPickler.scala:141:
warning: private[this] value bytes in class Scan shadows mutable bytes
inherited from class PickleBuffer. Changes to bytes will not be
visible within class Scan - you may want to give them distinct names.
[scalacfork] val tag = bytes(index(i)).toInt
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/reflect/internal/pickling/UnPickler.scala:182:
warning: private[this] value bytes in class Scan shadows mutable bytes
inherited from class PickleBuffer. Changes to bytes will not be
visible within class Scan - you may want to give them distinct names.
[scalacfork] case TERMname => newTermName(bytes, readIndex, len)
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/reflect/internal/pickling/UnPickler.scala:183:
warning: private[this] value bytes in class Scan shadows mutable bytes
inherited from class PickleBuffer. Changes to bytes will not be
visible within class Scan - you may want to give them distinct names.
[scalacfork] case TYPEname => newTypeName(bytes, readIndex, len)
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/reflect/internal/pickling/UnPickler.scala:440:
warning: private[this] value bytes in class Scan shadows mutable bytes
inherited from class PickleBuffer. Changes to bytes will not be
visible within class Scan - you may want to give them distinct names.
[scalacfork] protected def readAnnotArg(i: Int): Tree =
bytes(index(i)) match {
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/reflect/internal/pickling/UnPickler.scala:454:
warning: private[this] value bytes in class Scan shadows mutable bytes
inherited from class PickleBuffer. Changes to bytes will not be
visible within class Scan - you may want to give them distinct names.
[scalacfork] protected def readClassfileAnnotArg(i: Int):
ClassfileAnnotArg = bytes(index(i)) match {
[scalacfork]
^
[scalacfork] /scratch/trunk1/src/compiler/scala/tools/nsc/interactive/Global.scala:444:
warning: private[this] value reporter in class Global shadows mutable
reporter inherited from class Global. Changes to reporter will not be
visible within class Global - you may want to give them distinct
names.
[scalacfork] reporter.reset()
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/tools/nsc/interactive/Global.scala:493:
warning: private[this] value reporter in class Global shadows mutable
reporter inherited from class Global. Changes to reporter will not be
visible within class Global - you may want to give them distinct
names.
[scalacfork] reporter.error(unit.body.pos, "Presentation
compiler crashed while type checking this file:
%s".format(ex.toString()))
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/tools/nsc/interactive/Global.scala:543:
warning: private[this] value reporter in class Global shadows mutable
reporter inherited from class Global. Changes to reporter will not be
visible within class Global - you may want to give them distinct
names.
[scalacfork] if (debugIDE && !reporter.hasErrors)
validatePositions(unit.body)
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/tools/nsc/transform/Erasure.scala:603:
warning: private[this] value context in class Eraser shadows mutable
context inherited from class Typer. Changes to context will not be
visible within class Eraser - you may want to give them distinct
names.
[scalacfork] Console.println(er.msg + " in file " +
context.owner.sourceFile)
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala:82:
warning: private[this] value context in class BodyDuplicator shadows
mutable context inherited from class Typer. Changes to context will
not be visible within class BodyDuplicator - you may want to give them
distinct names.
[scalacfork] val sym1 = context.scope.lookup(sym.name)
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala:147:
warning: private[this] value context in class BodyDuplicator shadows
mutable context inherited from class Typer. Changes to context will
not be visible within class BodyDuplicator - you may want to give them
distinct names.
[scalacfork] val newsym = ldef.symbol.cloneSymbol(context.owner)
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala:155:
warning: private[this] value context in class BodyDuplicator shadows
mutable context inherited from class Typer. Changes to context will
not be visible within class BodyDuplicator - you may want to give them
distinct names.
[scalacfork] val newsym = vdef.symbol.cloneSymbol(context.owner)
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala:184:
warning: private[this] value context in class BodyDuplicator shadows
mutable context inherited from class Typer. Changes to context will
not be visible within class BodyDuplicator - you may want to give them
distinct names.
[scalacfork] enterSym(context, ddef)
[scalacfork] ^
Same thing. I knew the answer, but this is one of the most common
complains I heard. Some workaround suggestions are:
class B(bippy0: Int) extends A(bippy0) { def f2 = "B.bippy = " + bippy }
class B(_bippy: Int) extends A(_bippy) { def f2 = "B.bippy = " + bippy }
Honestly, the lameness of the workaround is in itself a strong
indicator of how awful this particular interaction of features is. Not
that I have any suggestions on how to handle it, besides a warning.
--
Daniel C. Sobral
I travel to the future all the time.
Honestly, the lameness of the workaround is in itself a strongindicator of how awful this particular interaction of features is. Not
that I have any suggestions on how to handle it, besides a warning.
Same thing. I knew the answer, but this is one of the most common
complains I heard. Some workaround suggestions are:
class B(bippy0: Int) extends A(bippy0) { def f2 = "B.bippy = " + bippy }
class B(_bippy: Int) extends A(_bippy) { def f2 = "B.bippy = " + bippy }
Honestly, the lameness of the workaround is in itself a strong
indicator of how awful this particular interaction of features is. Not
that I have any suggestions on how to handle it, besides a warning.
Because A could have more than one one-argument constructor.
Auxiliaries are second-class enough without syntactically excluding
them from consideration. Still, something in the spirit of this idea
would sure be nice. I hate having to mkae up names for batons I'm
passing between relay racers. They're batons! They're all just
batons! Stop trying to humanize them!
On Wed, Dec 7, 2011 at 11:32 AM, Rex Kerr <ich...@gmail.com> wrote:Because A could have more than one one-argument constructor.
> I don't know why I should have to bother repeating the type information if
> all I want to do is forward parameters to A's constructor.
class A(x: Int) {
def this(x: String) = this(5)
def this(x: List[Int]) = this(x.head)
}
class B(_) extends A(_)
What's that?
class B(_: String) extends A(_)
I did anticipate that answer, which is why I wrote "Auxiliaries are
second-class enough without syntactically excluding them from
consideration" to start. But it's not so bad, maybe we bumbled our
way toward a good idea.
-- Martin
LOL!
Actually, I'm much more comfortable with this one than with these:
f[A[_] <: B[_]]
import p.{x => _, _}
f(_, _ + 1)
But I'll grant that there's some ambiguity here:
class B(_) extends A(_)
x match { B(_) => ... }
f(_)
They do look too much alike. I do wish the repeated constructor
parameters problem was solved, though, and the proposed syntax does
have a certain elegance. And, for better or worse, Scala does use
underscore as the wildcard syntax for not creating new keywords. I
invite anyone who thinks I'm exaggerating to look at the second table
here: http://docs.scala-lang.org/tutorials/FAQ/finding-symbols.html#keywordsreserved_symbols.
Or just ponder the meaning of each underscore in the three examples I
gave.
By the way, I've come to the conclusion that hiding keywords behind
underscore is a lie. The keyword count might be decreased, but at the
cost of people needing to disambiguate underscore on their minds.
class A(n: Int)
class B(n: Int) extends A(n+1)
def a(n: Int) = 0
def b(n: Int) = a(n+1)
By analogy, we can construct from this:
def b = a _
// or `a(_)`
that:
class B extends A _
This however lead me to the bold thought that `extends` could be dropped
completely, such that we could write the following:
class B = A _ {
// ...
}
IMHO, allowing `_` in class definitions would even increase consistency
in the language.
class A(var bippy: Int) { def f1 = "A.bippy = " + bippy }
class B(super bippy: Int) extends A { def f2 = "B.bippy = " + bippy }
class C(super dingus: Int) extends B { def f3 = "C.bippy = " + bippy }
or
class A(var bippy: Int) { def f1 = "A.bippy = " + bippy }
class B(super(bippy: Int)) extends A { def f2 = "B.bippy = " + bippy }
class C(super(dingus: Int)) extends B { def f3 = "C.bippy = " +
bippy }
With the second variation you can use the one super keyword for more
parameters
Or allow both styles
I think it is conciser and more clear what happens.
To be honest, nothing of that appeals to me. The former syntax makes
somewhat sense, although `super` is not really a "modifier" for the
parameter (as `implicit` would be). The latter however looks artificial
as it required completely new syntax.