Understanding Scala lazy val inheritance rules - scala

In this code, x is null during construction:
abstract class A {
val x: String
println(s"A: x is $x")
}
class B extends A {
val x: String = "foo"
println(s"B: x is $x")
}
new B()
A: x is null
B: x is foo
It can be fixed by adding lazy to the declaration of x in B:
abstract class A {
val x: String
println(s"A: x is $x")
}
class B extends A {
lazy val x: String = "foo"
println(s"B: x is $x")
}
new B()
A: x is foo
B: x is foo
I don't understand exactly why. It's counterintuitive that making a val lazy should cause it to be initialized earlier than the corresponding non-lazy val would have been.

An implementing val definition in a subclass is evaluated - only after- its superclass has been initialized. Since you require the evaluation of the val before the superclass has finished initialization, the JVM knowns it's not yet initialized so it gives you the default value for an uninitialized String, which is null.
This is one of the reasons why lazy vals were built into the language:
When you prefix a val definition with the lazy modifier, the initializing expression on the right-hand side will only be evaluated the first time the val is used. Since you require the val to be evaluated in the superclass, it triggers it's evaluation. That is why it becomes available in the superclass.

Related

What does treating a method as a function mean in Scala?

By assigning a variable (or value?) a method name with a space and an underscore, you tell scala to treat the method as a function, which apparently means doing more than simply taking the value generated by a call to the method and assigning to the variable. What else is/can go on through such an assignment?
Since Scala runs on the JVM, it's easier to understand in terms of simple Java-like classes without Scala's syntactic sugar.
Remember that Scala functions are essentially members of a class similar to the following (signature deliberately simplified):
class Function[X, Y] {
def apply(x: X): Y
}
Application of a function f to an argument x is desugared into a method application f.apply(x).
Now suppose that you have another class Foo with method bar:
class Foo {
def bar(x: Int): String
}
If you now have an instance foo of type Foo, then whenever its method bar is transformed into a function by writing:
val f = foo.bar(_)
a new instance of an anonymous subclass of Function is created:
val f = new Function[Int, String] {
def apply(x: Int) = foo.bar(x)
}
If you use this syntax inside a class, this is closed over instead of an instance foo.
This is what all those weirdly named classes Main$$anon$1$$anonfun$1 are: they are the anonymous classes that represent functions. The functions can appear quite implicitly (for example, as blocks passed to the for-loops).
That's all there is to it semantically. The rest is just syntactic sugar.
Here is a complete runnable example that demonstrates the conversion of an instance method into a function:
with sugar, from the outside (a)
with sugar, from the inside (b)
without sugar, from the outside (c)
without sugar, from the inside (d)
You can save it into a file and execute with scala <filename.scala>:
/** A simple greeter that prints 'hello name' multiple times */
case class Hey(name: String) { thisHeyInst =>
def hello(x: Int): String = ("hello " + name + " ") * x
def withSugarFromInside = hello(_)
def noSugarFromInside = new Function[Int, String] {
def apply(y: Int) = thisHeyInst.hello(y)
}
}
val heyAlice = Hey("Alice")
val heyBob = Hey("Bob")
val heyCharlie = Hey("Charlie")
val heyDonald = Hey("Donald")
val a = heyAlice.hello(_)
val b = heyBob.withSugarFromInside
val c = new Function[Int, String] { def apply(y: Int) = heyCharlie.hello(y) }
val d = heyDonald.noSugarFromInside
println(a(3))
println(b(3))
println(c(3))
println(d(3))
In all four cases, a greeting is printed three times.
What _ actually does is an eta-conversion. It takes compile-time construction called method and returns runtime construction called anonymous function, which is actually an instance of scala's Function. Exactly the class depends on arity, so it might be Function1, Function2, Function3 and so on. The point here is to make First-class citizen, which may act like a value.
OOP needs a little more than some new object. Before making the code that creates instance, compiler generates a new class (extending FunctionN) in compile-time, but theoretically it shouldn't be necessary a whole new class. For Java 8 it could be native Java-lambdas.
Btw, you may extend Function1 by yourself and even eta-abstract it again:
scala> object f extends (Int => Int) { def apply(a: Int) = a }
scala> f(1)
res0: Int = 1
scala> f.apply _
res1: Int => Int = <function1>
scala> res1(5)
res2: Int = 5
As a conclusion a little copy-paste from #Daniel C. Sobral's answer:
the former can be easily converted into the latter:
val f = m _
Scala will expand that, assuming m type is (List[Int])AnyRef
into (Scala 2.7):
val f = new AnyRef with Function1[List[Int], AnyRef] {
def apply(x$1: List[Int]) = this.m(x$1)
}
On Scala 2.8, it actually uses an AbstractFunction1 class to reduce
class sizes.
Or simply saying val f = m _ is same as val f = (x: List[Int]) => m(x)
To make this answer more modern and precise let's see what's happening using scalac 2.11.2 and javap:
$ echo "object Z{def f(a: Int) = a}" > Z.scala //no eta-abstraction here
$ scalac Z.scala
$ ls
Z$.class Z.class Z.scala
$ echo "object Z{def f(a: Int) = a; val k = f _}" > Z.scala
$ scalac Z.scala
$ ls
Z$$anonfun$1.class Z.class //new anonfun class added for lambda
Z$.class Z.scala
$ javap -c Z\$\$anonfun\$1.class
Compiled from "Z.scala" // I've simplified output a bit
public final class Z$$anonfun$1 extends scala.runtime.AbstractFunction1$mcII$sp implements scala.Serializable {
public final int apply(int);
Code:
calling apply$mcII$sp(int)
public int apply$mcII$sp(int); //that's it
Code:
0: getstatic #25 // reading Field Z$.MODULE$:LZ$;, which points to `object Z`
3: iload_1
4: invokevirtual #28 // calling Method Z$.f
7: ireturn
public final java.lang.Object apply(java.lang.Object); //just boxed version of `apply`
Code:
unboxToInt
calling apply(int) method
boxToInteger
public Z$$anonfun$1();
Code:
AbstractFunction1$mcII$sp."<init>":()V //initialize
}
So it still extends AbstractFunction1
I'll try to provide some examples how a function or method are assigned to values with underscore.
If it's need to reference a zero-argument function
scala> val uuid = java.util.UUID.randomUUID _
uuid: () => java.util.UUID = <function0>
scala> uuid()
res15: java.util.UUID = 3057ef51-8407-44c8-a09e-e2f4396f566e
scala> uuid()
uuid: java.util.UUID = c1e934e4-e722-4279-8a86-004fed8b9090
Check how it's different when one does
scala> val uuid = java.util.UUID.randomUUID
uuid: java.util.UUID = 292708cb-14dc-4ace-a56b-4ed80d7ccfc7
In first case one assigned a reference to a function. And then calling uuid() generates new UUID every time.
In second, function randomUUID has been called and value assigned to a val uuid.
There are some other cases why _ might be useful.
It's possible to use a function with two arguments and create a function with a single argument out of it.
scala> def multiply(n: Int)(m: Int) = n*m
multiply: (n: Int)(m: Int)Int
scala> val by2 = multiply(2) _
by2: Int => Int = <function1>
scala> by2(3)
res16: Int = 6
To be able to do, it's crucial to define function multiply as curried. It's called function currying.

In Scala Reflection, why do constructor params hide getters?

vars in a scala class automatically get getters & setters you can see through scala reflection via members
import scala.reflect.runtime.{universe => ru}
class A(var x: Int)
scala> ru.typeOf[A].members.filter{_.name.toString.contains("x")}
res22: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(variable x, method x_=, method x)
However, if you create a subclass, which re-uses the var name in the constructor, the getter is gone:
class B(x:Int, var y: Int) extends A(x)
scala> ru.typeOf[B].members.filter{_.name.toString.contains("x")}
res23: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(value x, method x_=)
scala> res23.head.asTerm.isVal
res25: Boolean = true
This seems a little misleading ... after all, B still does have a getter for x (and its not a val)
scala> val b = new B(5,6)
b: B = B#270288ed
scala> b.x
res26: Int = 5
scala> b.x = 7
b.x: Int = 7
scala> b.x
res27: Int = 7
If I try to pretend that the value x I got from members is a getter, I get an error:
scala> val xGetter = res23.head.asTerm
xGetter: reflect.runtime.universe.TermSymbol = value x
scala> val objMirror = ru.runtimeMirror(getClass.getClassLoader).reflect(b)
objMirror: reflect.runtime.universe.InstanceMirror = instance mirror for B#270288ed
scala> val getterMirror = objMirror.reflectField(xGetter)
scala.ScalaReflectionException: Scala field x isn't represented as a Java field, neither it has a Java accessor method
note that private parameters of class constructors don't get mapped onto fields and/or accessors,
unless they are used outside of their declaring constructors.
What is the right workaround here? Is it completely wrong to have a subclass name its constructor args the same as the names in the parent args? Or instead of calling members, do I need to work my up all super-classes to get all getters & setters?
Note that members gives me the inherited getter as long as the subclass doesn't create a constructor w/ the same name:
class Y(var x: Int)
class Z(q:Int, z: Int) extends Y(q)
scala> ru.typeOf[Z].members.filter{_.name.toString.contains("x")}
res28: Iterable[reflect.runtime.universe.Symbol] = SynchronizedOps(method x_=, method x)
EDIT
In case its unclear, I'm really asking:
1) is this a bug in scala reflection?
2) if not, should I:
(a) never have classes use names of constructor fields be the same as the name of fields in base classes? (if so, I'm probably defining all my classes wrong ...)
or
(b) to get all getters & setters, should I just go through the list of all parent classes and use declarations, rather than relying on members to do the right thing, since it doesn't work in this one case?
EDIT 2
in response to #som-snytt's answer, the visible methods of x are really on x in A, not the param in the constructor to B. Eg.:
class A(var x: Int){def showMeX {println(x)}}
class B(x:Int, var y: Int) extends A(x)
scala> val b = new B(5,10)
scala> b.showMeX
5
scala> b.x = 17
b.x: Int = 17
scala> b.showMeX
17
so I don't really think that the either the getter or setter for x has been shadowed, from the perspective of normal user code. Its only been shadowed for reflection code ... and it doesn't make sense to me that there would be two different versions of shadowing.
2) if not, should I: (a) never have classes use names of constructor fields be the same as the name of fields in base classes?
Since they wouldn't let me fix this, that's exactly what I do. I try to give all constructor parameters new names distinct from all inherited names. Here's a typical example within the compiler.
class PackageClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TypeName)
Yes, it's ridiculous.
https://groups.google.com/forum/#!topic/scala-language/9jLsT_RRQR0
https://issues.scala-lang.org/browse/SI-3194
https://issues.scala-lang.org/browse/SI-4762
https://issues.scala-lang.org/browse/SI-6880
Oh boy, don't keep pulling that thread...
https://issues.scala-lang.org/browse/SI-7475
https://issues.scala-lang.org/browse/SI-2568
https://issues.scala-lang.org/browse/SI-6794
It shouldn't be hard to see that the odds of any of it being addressed are nil. It's a perfect example of why I quit.
By the way, if you use -Xlint it warns you about this. That's mentioned in SI-4762.
% cat a.scala
class A(var x: Int)
class B(x:Int, var y: Int) extends A(x) {
def z = x
}
% scalac -Xlint a.scala
a.scala:3: warning: private[this] value x in class B shadows mutable x inherited from class A.
Changes to x will not be visible within class B - you may want to give them distinct names.
def z = x
^
one warning found
Well, in:
class B(x:Int, var y: Int) extends A(x)
The x in B is private (not a case class, no val or var specifier), the x in A is public (you specified var). I'm not too familiar with this reflection API, but does it show private members?
If you instead:
scala> class B(val x:Int, var y: Int) extends A(10)
<console>:9: error: overriding variable x in class A of type Int;
value x needs `override' modifier
class B(val x:Int, var y: Int) extends A(10)
^
The only public x is the one in A, which can be shown here:
scala> class B(x:Int, var y: Int) extends A(10)
defined class B
scala> new B(2,3).x
res4: Int = 10
If you want to override the parent member, use override, and change the parent to something that can be overriden.
I guess as long as the answer to my question is not (2a), then if anybody else runs into this, here is a workaround. Maybe it will be unnecessary in the future depending on the answer to (1).
(Some extra stuff here, but maybe useful also)
import scala.reflect.runtime.{universe => ru}
object ReflectionUtils {
def extractGetterSetterPairs(typ: ru.Type): Seq[GetterSetterPair] = {
typ.baseClasses.foldLeft(Seq[GetterSetterPair]()){case (acc, clsSymb) =>
extractGetterSetterPairs(clsSymb.asClass.toType, acc)
}
}
private def extractGetterSetterPairs(typ: ru.Type, acc: Seq[GetterSetterPair]): Seq[GetterSetterPair] = {
val terms = typ.declarations.collect{case x if x.isTerm => x.asTerm}
acc ++ terms.filter{x => x.isGetter}.map{x => x -> x.setter}.
filter{case(g,s) => s.isTerm}.map{case(g,s) =>
GetterSetterPair(g,s.asTerm)
}
}
def termName(t: ru.TermSymbol): String = {
t.name.toString.trim
}
}
case class GetterSetterPair(getter: ru.TermSymbol, setter: ru.TermSymbol) {
val name = ReflectionUtils.termName(getter)
val fieldType = {
//this is way more complicated than it should be. But
// 1) getters for some reason are not instances of ru.MethodType
// java.lang.ClassCastException: scala.reflect.internal.Types$NullaryMethodType cannot be cast to scala.reflect.api.Types$MethodTypeApi
// 2) its a headache to get the types out of setters
val m = setter.typeSignature.
asInstanceOf[ru.MethodType]
m.params.head.typeSignature
}
}

Scope of Scala's implicit class conversion

Scala seems to apply the implicit class conversion on the largest possible expression, as in the following example:
scala> class B { def b = { println("bb"); true } }
defined class B
scala> class A { def a = { println("aa"); new B } }
defined class A
scala> (new A).a.b
aa
bb
res16: Boolean = true
scala> class XXX(b: => Boolean) { def xxx = 42 }
defined class XXX
scala> implicit def toXXX(b: => Boolean) = new XXX(b)
toXXX: (b: => Boolean)XXX
scala> (new A).a.b.xxx
res18: Int = 42
I'm very happy about this fact, but my question is that which part of the SLS specifies this behavior? Why does it not evaluate (new A).a.b to true first for example, and just apply the conversion on that value?
The line containing the implicit conversion
(new A).a.b.xxx
gets converted by the compiler (ie, at compile-time) into
toXXX((new A).a.b).xxx
We can see this if you use the -Xprint:typer option when starting Scala.
private[this] val res3: Int = $line5.$read.$iw.$iw.toXXX(new $line2.$read.$iw.$iw.A().a.b).xxx;
Since this conversion happens at compile-time and not run-time, it would be impossible for Scala to evaluate (new A).a.b to true before applying the conversion. Thus, the behavior you get is exactly the same as if you has just written toXXX((new A).a.b).xxx in the first place.
As answered by Ryan Hendrickson on the mailing list:
[The definition] you're looking for is in Section 7.3, in the list of the three situations in which views are applied:
In a selection e.m with e of type T, if the selector does not denote a member
of T. In this case, a view v is searched which is applicable to e and whose result
contains a member named m. The search proceeds as in the case of implicit
parameters, where the implicit scope is the one of T. If such a view is found,
the selection e.m is converted to v(e).m.
So the compiler can only generate something that is semantically equivalent to v(e).m, and as you've demonstrated, when by-name parameters are involved
val x = e
v(x).m
is not semantically equivalent to v(e).m.

Scala lower type bounds and covariance

Im reading this page http://www.scala-lang.org/node/137, I understand what covariance is and lower bounds as well, but what it's not clear is this line:
Unfortunately, this program does not compile, because a covariance
annotation is only possible if the type variable is used only in
covariant positions. Since type variable T appears as a parameter type
of method prepend, this rule is broken.
why elem has to be an instance of a supertype of T, if ListNode is already covariant why elem cannot be prepended to the current list.
class Super {override def toString = "Super"}
class Sub extends Super {override def toString = "Sub"; def subMethod {} }
val sup = new Super
val sub = new Sub
Imagine the following were allowed:
// invalid code
class Foo[+T] {
def bar(x: T) = println(x)
}
Since Foo is covariant on T, this is valid (a simple upcast, since a Foo[Sub] is a Foo[Super]):
val foo : Foo[Super] = new Foo[Sub] {
override def bar(x: Sub) = x.subMethod
}
Now foo is, as far as we know, a Foo[Super] like any other, but its bar method won't work, because the bar implementation requires a Sub:
foo.bar(sup) // would cause error!

two type parameters with the same name

I am wondering why the two type parameters (named "A") with the same name ("A") is allowed as per the example below. I know this is a POOR naming of type parameters, don't do this.
(My guess is that they are on a on a different scope level, e.g. class level and function level, and the compiler is using some kind of name mangling)
class MyTest[A](){
type MyType = A
def checkString[A](value:A, x:MyType):A = {
value match {
case x:String => println("Value is a String")
case _ => println("Value is not a String")
}
x match {
case x:String => println("x is a String")
case _ => println("x is not a String")
}
value
}
}
Example output from 2.8.0
scala> val test = new MyTest[Int]
test: MyTest[Int] = MyTest#308ff65f
scala> test.checkString("String",1)
Value is a String
x is not a String
res7: java.lang.String = String
scala> test.checkString(1,1)
Value is not a String
x is not a String
res8: Int = 1
Nested scopes in Scala are free to shadow each others' symbol tables. Types are not the only things you can do this with. For example:
class X[A](a: A) {
def X[A](a: A) {
if (a==this.a) {
val X = Some(this.a)
X match {
case Some(a) => "Confused much yet?"
case _ => "Just because you can do this doesn't mean you should."
}
}
}
}
The principle is that a scope has control over its namespace. This has dangers, if you use it foolishly (e.g. I have used X and a for each of three different things, and A for two--in fact, you could replace every identifier with X except for the one in the Some which has to be lower case). But it also has benefits when writing functional code--you don't have to worry about having to rename some iterating variable or type or whatever just because you happen to place it in a different context.
def example = {
val a = Array(1,2,3,4,5)
val sumsq = a.map(i => i*i).sum
a.map(i => {
val a = Array.range(1,i)
val sumsq = a.map(i => i*i).sum // Cut and paste from above, and works!
sumsq + i
}).sum
}
So be aware that you have the power to confuse yourself, and wisely choose to use that power non-confusingly.
I'm not expert of Scala, but your code behave exactly what I would expected.
First, you need to know that the type parameter of method is not need bound to class.
For example, the following is valid Scala.
class Test1 {
def test[A] (x: A) = println(x)
}
And the following is also a valid Scala code, the only different is that this one does not use the type A at all.
class Test2[A] {
def test (x: Int) = println(x)
}
So I think it is clear now, first you created a instance of MyTest[Int], which is fine.
scala> val test = new MyTest[Int]
test: MyTest[Int] = MyTest#308ff65f
Then you called checkString[A, Int] without provide type parameter A, since it is a generic function, the compiler must inference what type is A.
scala> test.checkString("String",1)
Value is a String
x is not a String
res7: java.lang.String = String
Note:
In this time point, Scala already knows that x must be a Int and its type is fixed, since you provide it by MyTest[Int]. So the following code will yield compile error.
scala> val t = new MyTest[Int]
t: MyTest[Int] = MyTest#cb800f
scala> t.checkString ("A", "B")
<console>:8: error: type mismatch;
found : java.lang.String("B")
required: t.MyType
t.checkString ("A", "B")
Now the complier looks at the arguments you provided, and found its is
checkString ("String", 1)
which is corresponding to
checkString (value: A, x: Int)
So now compiler knows type A in checkString[A, Int] must be a string, and if you do all of this by hand, your code will look like this.
scala> val test = new MyTest[Int]
test: MyTest[Int] = MyTest#5bda13
scala> test.checkString[String]("String", 1)
Value is a String
x is not a String
res1: String = String
scala> test.checkString[Int] (3, 4)
Value is not a String
x is not a String
res4: Int = 3
scala> test.checkString[Int] ("String", 4)
<console>:8: error: type mismatch;
found : java.lang.String("String")
required: Int
test.checkString[Int] ("String", 4)
^
Well I belive at scala we use same rule as in Java basically we are looking for smallest available scope in Java:
class Foo<T>{
T instance;
void <T> T getInstance(){
return instance
}
}
Will produce a compilation error since type T declared in generic method getInstance is not the same as parameter type of class Foo.
In case of Scala I believe then you write
def checkString[A]
You telling compiler that function behavior will vary upon provided type but it has no connection with parameter class of outer class. Unfortunately I cannot find correct place is Scala spec right now.
Its not just related to scala. In most languages you can do that. Because as you said the variables are in different scope.
In c#
class test
{
int i;
void method(int i)
{
this.i = i;
}
}
this represents the self type. I am not sure about the this functionality in scala. But the reason for your question is scope level.