Overriding java public members in scala - scala

When inheriting from a Java class with public members, using scala's override modifier raises compilation error like so:
Error:(67, 22) overriding variable userId in class Logon of type String;
value userId has incompatible type
override val userId = s.user
^
The java class looks something along the following lines:
public class Logon {
public String userId = "";
}
and the scala code:
class MyLogon extends Logon {
override val userId : String = "abc"
}
Removing the modifier results in:
Error:(72, 7) overriding variable userId in class Logon of type String;
value userId needs `override' modifier
val userId: String = s.user
^
Why is this? Is it a bug? There are related questions e.g. 16607517 but these seem to be changing the visibility of the fields; that's not the case here - they're all public.
Believe this is with scalac-2.10.4.

It is impossible to override public fields defined in Java because of how it is implemented in Scala:
A public field (val user: String) is represented internally as a combination of private field (say, private val user$1: String) and public accessor method (def user: String = user$1). It is not allowed to override a field with a method, thus the compile error.
There is currently no way to omit the public accessor method generation in Scala, so you'll have to find other ways to implement what you want - either by defining a common trait or interface, or by using another field name, or by wrapping the Java Logon into a Scala Logon with proper superclass constructs.
Scala interoperates extremely well with Java, but the interop is not perfect, unfortunately.

You cannot override member variables.
This should not be confused with how scala allows to override val & var which works because scala compiler generates getter and setter methods for them.

Related

Scala compile error: member of method parameter not visible to class method

I am getting a compile error of:
value txn is not a member of Charge
new Charge(this.txn + that.txn)
^
with the following Scala class definition:
class Charge(txn: Double = 0){
def combine(that:Charge): Charge =
new Charge(this.txn + that.txn)
}
Explicitly declaring txn as a val allows it to work:
class Charge(val txn: Double = 0){
def combine(that:Charge): Charge =
new Charge(this.txn + that.txn)
}
I thought val was assumed? Can somebody explain this? Is it a problem with my understanding of the default constructor or the scope of the method?
In scala, you can define classes in two forms, for ex.
class Charge(txn: Double) -> In this case scala compiler compiles it to java like below
public class Charge {
....
public Charge combine(Charge);
....
public Charge(double);
....
}
As you can notice in compiled java code, there is no public accessor for txn
Let's look at another variation of Charge class,
If you define like this class Charge(val txn: String), it gets compiled to below
public class Charge {
...
public double txn();
...
public Charge combine(Charge);
...
public Charge(double);
...
}
As you can see, in this case compiler generates public accessor for txn hence you are able to access that.txn when you mark it as val
case class Charge(txn: Double): This is data class for which scala generates getters, equals and toString for you.
You can compile this class
scalac Charge.scala
javap -c Charge.class
And then see what it generates
What you pass to constructor is essentially constructor parameters whose scope is limited to the constructor. If you want to make them visible from the outside, you have to declare them as vals or reassign to some other vals in the constructor body.

Scala reflection: Why does getMethods return private vals defined in superclass?

Code below defines a trait T with a private val someVal and an anonymous class extending T. If we call getMethods from the instance of the anonymous class, someVal is listed as a public method:
scala> trait T { private val someVal = 3 }
defined trait T
scala> new T {}.getClass.getMethods.apply(0)
res2: java.lang.reflect.Method = public int $anon$1.$line6$$read$T$$someVal()
Of course someVal isn't accessible in this subclass, but why is it even in the return of getMethods, as public?
traits compile to interfaces, because they need multiple-inheritance. But interfaces can have neither fields nor non-public members. Therefore, a field becomes a pair of public accessors, mangled by the trait's name, and the compiler is tasked with placing the field into all subclasses and implementing the accessors. Any methods on T trying to access someVal go through the getter, and the static $init$ function, which contains the constructor code, uses the setter to set it to 3. If your val were declared public, then the name of the getter would be demangled to just someVal, and external code would use that, and if it were also var, the setter would demangle to someVal_=, which subsequently mangles to someVal_$eq. The horribly long mangled names are pretty much enough to keep anyone from using them, anyway, and it's only relevant when doing Java interop.

Scala mutator naming conventions and requirements

I am having some trouble understand the naming in Scala with respect to mutators. Here is the part that I am having trouble understanding:
class Company {
private val _name: String = _
def name = _name
def name_=(name: String) {
_name = name
}
}
So I understand that the _name is the private String, and the first def name is the getter/accessor while the second is the setter/mutator. Essentially, I understand what the code means and does, but I am not sure what is personal preference vs code standards/the required way to do it. Will all mutators have the _ suffix and is it standard to prefix private attributes with an underscore or is that personal preference?
Or can I just define the mutator as the following?
def name=(name: String) {
_name = name
}
Similarly, do I have the prefix the private val with the underscore or could I just change it to:
def name=(name: String) {
name = name
}
I got the above code from Scala Naming Conventions and Daniel Spewak's Accessors/Mutators
These are all good questions. Some of them are covered by the article from the Scala documentation you've liked, specifically in the part about Accessors/Mutators.
Naming of mutator methods
In a nutshell, the name_= form is not special syntax but rather a naming convention enforced by the specification.
Let's look at what scalac produces at the JVM bytecode level when you declare a plain old var. Understanding the bytecode produced by scalac is by no means necessary to understand the higher-level workings of the language, but many people learning Scala have some experience with Java and, though that, some intuition of what is possible in the JVM and what isn't. I think this is the closest we can get to as the why of some of the decisions that were made in the specification of Scala.
Here I have a source file called Var.scala:
trait Var {
var name: String
}
I compile the source to a class file and decompile it using javap:
$ scalac Var.scala
$ javap Var.class
Compiled from "Var.scala"
public interface Var {
public abstract java.lang.String name();
public abstract void name_$eq(java.lang.String);
}
As we can see, a var in a trait declares two JVM methods, a getter, and a setter. The getter takes the name of the var, while the setter has a bit of a weird name. Here, $eq is just how an = in a Scala identifier is encoded by scalac in the class file it produces. This is part of the Scala specification and is required for binary compatibility between different compilation units.
So the name of the setter as seen from Scala is simply name_=. This is also part of the Scala specification. When we write a statement that sets the value of a var, a call to a method with a name of that form is generated. When we write a statement that just reads the var, a call to the first method is generated.
Instead of declaring a var, we could just as well declare those two methods directly:
trait ValAndDef {
val name: String
def name_=(newName: String): Unit
}
Compiling and decompiling this will show the exact same methods as before. There is also nothing preventing you from declaring only one of those methods, which would create a member which can only be read but not written, or vice versa.
Naming of the private packing field
Until now, I've only talked about declaring a field. Implementing the field means also adding storage to the var or implementing the methods when declared directly. Declaring a var in a class instead of a trait will automatically add a field for storing the value of the var:
class VarClass {
var name: String = _
}
$ javap -private VarClass.class
Compiled from "VarClass.scala"
public class VarClass {
private java.lang.String name;
public java.lang.String name();
public void name_$eq(java.lang.String);
public VarClass();
}
If you decide to implement the field using a pair of methods, you will have to declare such a private field yourself. The Scala specification does not say anything about how that field should be named in that case (it is private and thus not part of any interoperability concern).
The only thing "official" I can find is a paragraph in the article I linked at the top, which advocates the _name naming pattern for the backing field, while also stating:
While Hungarian notation is terribly ugly, it does have the advantage of disambiguating the _name variable without cluttering the identifier.
So it is up to you whether you want to follow that guidance or not. ¯\_(ツ)_/¯

Why can't I have a private var / val with the same name as a getter / setter? or how to desugar implicit getters / setters

I'm sure it's a duplicate, but I couldn't find it.
Consider this class
class Test1(var param: Int)
Scala generates a getter and a setter, and makes the param private.
It can be shown using javap for example:
public class Test1 {
private int param;
public int param();
public void param_$eq(int);
public Test(int);
}
I was trying to write the desugared version of it with explicit getters / setters but couldn't do so 100% the same way as the private var had a naming collision with the getter.
class Test2(private[this] var param:Int) {
def param:Int = this.param
def param_= (param:Int) {this.param = param}
}
This is the error:
ambiguous reference to overloaded definition,
both method param in class Test2 of type => Int
and variable param in class Test2 of type Int
match expected type Int
def param:Int = param
^
This of course works (renaming private member to _param)
class Test3(private[this] var _param:Int) {
def param:Int = this._param
def param_= (param:Int) {this._param = param}
}
But generates this slightly different bytecode of course (since we had to rename param to _param):
public class Test3 {
private int _param;
public int param();
public void param_$eq(int);
public Test3(int);
}
Is there any way to reach the same bytecode as the example in Test1 while using explicit getter / setters as in Test2?
In Scala methods and fields share the same name space. This is a little confusing for converts coming from Java or other languages which have separate name space for each.
But it follows the Uniform Access Principle i.e. the user of a class can't tell if he is actually calling a def or a val (or a var) when used without parenthesis. This also means you can switch implementations between val an def without clients being affected. (I'm not sure if they'd have to get recompiled, but the source code can stay as it is.
Actually, you can!
Here is an answer that does exactly that to good effect.
There you will find a private var and an accessor with the same name.
private[this] var state
private final def state()
Note the parens on the definition of the accessor, which are not needed at the use site.
Under the covers, the local field has that LOCAL_SUFFIX_STRING, which is an evil space. See the Test3 members, below, which strips away the covers to bare all.
On the getter side, you can add parens. That breaks the saccharin setter, apparently. Can you live without sugary assignment syntax?
When you reference x.param, the compiler will supply parens, see #alexiv 's comment elsewhere on uniform access or the SO answer mentioned above.
import reflect.runtime.currentMirror
import reflect.runtime.universe._
class Test2(private[this] var param: Int) {
def param(): Int = param
def param_=(param: Int) { this.param = param }
}
val x = new Test2(1)
Console println x.param
x.param_=(2)
Console println x.param
class Test3(var param: Int)
val ps = typeOf[Test3].members filter (m => m.name.toString.startsWith("param")) map (m => s"'${m.name.toString}'")
Console println ps
Console println (typeOf[Test3].members filter (_.name.toString.endsWith(nme.LOCAL_SUFFIX_STRING)))
Note that the other answers suggest that Scala only distinguishes terms and types, neglecting to mention that symbols (obviously) can be overloaded.
You may have read that overloading is evil! That may be so, but whatever you do in the privacy of your own private members is entirely your own affair.
(Updated to suggest that even if the question is somewhat duplicated somewhere, this is still a fun and informative answer.)
I think variable and method are treated the same, the variable param is like a method without parameters, and the method param is the same, so just like the error indicates: ambiguous reference to overloaded definition.

Is there any advantage to definining a val over a def in a trait?

In Scala, a val can override a def, but a def cannot override a val.
So, is there an advantage to declaring a trait e.g. like this:
trait Resource {
val id: String
}
rather than this?
trait Resource {
def id: String
}
The follow-up question is: how does the compiler treat calling vals and defs differently in practice and what kind of optimizations does it actually do with vals? The compiler insists on the fact that vals are stable — what does in mean in practice for the compiler? Suppose the subclass is actually implementing id with a val. Is there a penalty for having it specified as a def in the trait?
If my code itself does not require stability of the id member, can it be considered good practice to always use defs in these cases and to switch to vals only when a performance bottleneck has been identified here — however unlikely this may be?
Short answer:
As far as I can tell, the values are always accessed through the accessor method. Using def defines a simple method, which returns the value. Using val defines a private [*] final field, with an accessor method. So in terms of access, there is very little difference between the two. The difference is conceptual, def gets reevaluated each time, and val is only evaluated once. This can obviously have an impact on performance.
[*] Java private
Long answer:
Let's take the following example:
trait ResourceDef {
def id: String = "5"
}
trait ResourceVal {
val id: String = "5"
}
The ResourceDef & ResourceVal produce the same code, ignoring initializers:
public interface ResourceVal extends ScalaObject {
volatile void foo$ResourceVal$_setter_$id_$eq(String s);
String id();
}
public interface ResourceDef extends ScalaObject {
String id();
}
For the subsidiary classes produced (which contain the implementation of the methods), the ResourceDef produces is as you would expect, noting that the method is static:
public abstract class ResourceDef$class {
public static String id(ResourceDef $this) {
return "5";
}
public static void $init$(ResourceDef resourcedef) {}
}
and for the val, we simply call the initialiser in the containing class
public abstract class ResourceVal$class {
public static void $init$(ResourceVal $this) {
$this.foo$ResourceVal$_setter_$id_$eq("5");
}
}
When we start extending:
class ResourceDefClass extends ResourceDef {
override def id: String = "6"
}
class ResourceValClass extends ResourceVal {
override val id: String = "6"
def foobar() = id
}
class ResourceNoneClass extends ResourceDef
Where we override, we get a method in the class which just does what you expect. The def is simple method:
public class ResourceDefClass implements ResourceDef, ScalaObject {
public String id() {
return "6";
}
}
and the val defines a private field and accessor method:
public class ResourceValClass implements ResourceVal, ScalaObject {
public String id() {
return id;
}
private final String id = "6";
public String foobar() {
return id();
}
}
Note that even foobar() doesn't use the field id, but uses the accessor method.
And finally, if we don't override, then we get a method which calls the static method in the trait auxiliary class:
public class ResourceNoneClass implements ResourceDef, ScalaObject {
public volatile String id() {
return ResourceDef$class.id(this);
}
}
I've cut out the constructors in these examples.
So, the accessor method is always used. I assume this is to avoid complications when extending multiple traits which could implement the same methods. It gets complicated really quickly.
Even longer answer:
Josh Suereth did a very interesting talk on Binary Resilience at Scala Days 2012, which covers the background to this question. The abstract for this is:
This talk focuses on binary compatibility on the JVM and what it means
to be binary compatible. An outline of the machinations of binary
incompatibility in Scala are described in depth, followed by a set of rules and guidelines that will help developers ensure their own
library releases are both binary compatible and binary resilient.
In particular, this talk looks at:
Traits and binary compatibility
Java Serialization and anonymous classes
The hidden creations of lazy vals
Developing code that is binary resilient
The difference is mainly that you can implement/override a def with a val but not the other way around. Moreover val are evaluated only once and def are evaluated every time they are used, using def in the abstract definition will give the code who mixes the trait more freedom about how to handle and/or optimize the implementation. So my point is use defs whenever there isn't a clear good reason to force a val.
A val expression is evaluated once on variable declaration, it is strict and immutable.
A def is re-evaluated each time you call it
def is evaluated by name and val by value. This means more or less that val must always return an actual value, while def is more like a promess that you can get a value when evaluating it. For example, if you have a function
def trace(s: => String ) { if (level == "trace") println s } // note the => in parameter definition
that logs an event only if the log level is set to trace and you want to log an objects toString. If you have overriden toString with a value, then you need to pass that value to the trace function. If toString however is a def, it will only be evaluated once it's sure that the log level is trace, which could save you some overhead.
def gives you more flexibility, while val is potentially faster
Compilerwise, traits are compiled to java interfaces so when defining a member on a trait, it makes no difference if its a var or def. The difference in performance would depend on how you choose to implement it.