overloading + and += operators for "Number Classes" - operator-overloading

I want to create extension functions for classes that encapsulate simple Numbers. For example DoubleProperty. I encountered the problem, that I can't overload the + and the += operator at the same time.
I wan't to create a behaviour, that passes following tests:
class DoublePropertyTest {
lateinit var doubleProperty: DoubleProperty
#Before
fun initialize() {
doubleProperty = SimpleDoubleProperty(0.1)
}
#Test
fun plus() {
val someProperty = doubleProperty + 1.5
assertEquals(someProperty.value, 1.6, 0.001)
}
#Test
fun plusAssign() {
val someProperty = doubleProperty
doubleProperty += 1.5 //error if + and += are overloaded
assert(someProperty === doubleProperty) //fails with only + overloaded
assertEquals(doubleProperty.value, 1.6, 0.001)
}
}
It could be implemented using these extension functions:
operator fun ObservableDoubleValue.plus(number: Number): DoubleProperty
= SimpleDoubleProperty(get() + number.toDouble())
operator fun WritableDoubleValue.plusAssign(number: Number)
= set(get() + number.toDouble())
The problem is, that if + is overlodaded the += can't be overloaded aswell:
Assignment operators ambiguity. All these functions match.
- public operator fun ObservableDoubleValue.plus(number: Number): DoubleProperty
- public operator fun WritableDoubleValue.plusAssign(number: Number): Unit
If I only overload the + operator, a new DoubleProperty object is returned on += operations instead of the initial one.
Is there a way to work around this limitation?

The strange += operator in Kotlin
you can both overloading the plus operator and plusAssign operator in kotlin, but you must following the rules of kotlin to solving the strange += conflicts.
introduce an immutable structure of the class for the plus operator which means any class outside the class can't edit its internal data.
introduce a mutable structure of the class for the plusAssign operator which means its internal data can be edited anywhere.
the kotlin has already done such things in the stdlib for the Collection & the Map classes, the Collection#plus and MutableCollection#plusAssign as below:
operator fun <T> Collection<T>.plus(elements: Iterable<T>): List<T>
// ^--- immutable structure
operator fun <T> MutableCollection<in T>.plusAssign(elements: Iterable<T>)
// ^--- mutable structure
But wait, how to solving the conflict when we using the += operator?
IF the list is an immutable Collection then you must define a mutable var variable, then the plus operator is used since its internal state can't be edited. for example:
// v--- define `list` with the immutable structure explicitly
var list: List<Int> = arrayListOf(1); //TODO: try change `var` to `val`
val addend = arrayListOf(2);
val snapshot = list;
list += addend;
// ^--- list = list.plus(addend);
// list = [1, 2], snapshot=[1], addend = [2]
IF the list is a mutable MutableCollection then you must define a immutable val variable, then the plusAssign operator is used since its internal state can be edited anywhere. for example:
// v--- `list` uses the mutable structure implicitly
val list = arrayListOf(1); //TODO: try change `val` to `var`
val addend = arrayListOf(2);
val snapshot = list;
list += addend;
// ^--- list.plusAssign(addend);
// list = [1, 2], snapshot=[1, 2], addend = [2]
On the other hand, you can overloads an operator with diff signatures, each signature for the different context, and kotlin also do it, e.g: Collection#plus. for example:
var list = listOf<Int>();
list += 1; //list = [1];
// ^--- list = list.plus(Integer);
list += [2,3]; //list = [1, 2, 3]
// ^--- list = list.plus(Iterable);

Your operator override implementation has two problems:
1. inconsistent type after plus
operator fun ObservableDoubleValue.plus(number: Number): DoubleProperty
= SimpleDoubleProperty(get() + number.toDouble())
Any ObservableDoubleValue instance plus a Number, got a DoubleProperty instance(or say a SimpleDoubleProperty instance). Let's say I have a type ComplexDoubleProperty implements ObservableDoubleValue, you will see:
var a = getComplexDoubleProperty()
a = a + 0.1 //compile error, WTF?
//or even
var b = SimpleDoubleProperty(0.1)
b = b + 0.1 //compile error, because b+0.1 is DoubleProperty
You can see this behavior makes no sense.
2. a=a+b and a+=b should be identical
If your implementation compiles, you will have
var a: DoubleProperty = SimpleDoubleProperty(0.1) //add DoubleProperty to make it compile
var b = a
a += 0.1
println(b == a)
prints true because += sets the value to the original instance. If you replace a+=0.1 with a=a+0.1 you will get false because a new instance is returned. Generally speaking, a=a+b and a+=b are not identical in this implementation.
To fix the two problems above, my suggestion is
operator fun SimpleDoubleProperty.plus(number: Number): SimpleDoubleProperty
= SimpleDoubleProperty(get() + number.toDouble())
so you don't need to override plusAssign. The solution is not as general as yours, but it's correct if you only have SimpleDoubleProperty calculations, and I believe you do, because in your implementation, plus always returns a SimpleDoubleProperty instance.

You cannot overload both + and +=. Overload one of the them.
When you write += in your code, theoretically both plus the plusAssign functions
can be called (see figure 7.2). If this is the case, and both functions are defined and
applicable, the compiler reports an error.
I copied/pasted from Kotlin in Action book!

If DoubleProperty is your class, you can make plus and plusAssign its methods, that should resolve any ambiguity.

Related

How can I combine this context with invokeFunction in Nashorn?

I am trying to call a function in Javascript from Java/Nashorn (in Scala, but that's not material to the question).
// JS
var foo = function(calculator){ // calculator is a Scala object
return this.num * calculator.calcMult();
}
The context on the Scala side is like this:
case class Thing(
num: Int,
stuff: String
)
case class Worker() { // Scala object to bind to calculator
def calMult() = { 3 } // presumably some complex computation here
}
I start by getting foo into the JS environment:
jsengine.eval("""var foo = function(calculator){return this.num * calculator.calcMult();}"""
To use this I need two things to be available: 1) 'this' context to be populated with my Thing object, and 2) the ability to pass a Java/Scala object to my JS function (to call calcMulti later). (If needed I can easily JSON-serialize Thing.)
How can I do both and successfully call foo() from Scala?
This may not be the only or cleanest solution, but it does work.
Turns out javascript has the ability to bind a given 'this' context to a function, which creates a "bound function" that has your 'this' visible within it. Then you use invoke() as you normally would on the bound function.
val inv = javascript.asInstanceOf[Invocable]
val myThis: String = // JSON serialized Map of stuff you want accessible in the js function
val bindFn = "bind_" + fnName
javascript.eval(bindFn + s" = $fnName.bind(" + myThis + ")")
inv.invokeFunction(bindFn, args: _*)
If you passed myThis into the binding to include {"x":"foo"} then when invoked, any access within your function to this.x will resolve to "foo" as you'd expect.

Scala: why do my case class instances have the same hashCode?

I am using Scala 2.11.
I have a case class Dimension and I created 3 instances of it. When I put them into a HashSet, I surprisingly found that only 1 was added properly. Then I tried to debug and found out they had the same hashCode.
I am new to Scala, but have a lot of experience in Java. I am wondering why all of them are having the same hashCode even if they have different fields and what is the default implementation of hashCode method in Scala's case class? And how does HashSet/HashMap work in Scala?
Here is my code example.
object Echo {
def main( args:Array[String] ):Unit = {
var d1 = new Dimension
d1.name = "d1"
d1.dimensionId = "1"
println("d1:" + d1.hashCode()) // d1, d2, d3 have the same hashCode
var d2 = new Dimension
d2.name = "d2"
d2.dimensionId = "2"
println("d2:" + d2.hashCode())
var d3 = new Dimension
d3.name = "d3"
d3.dimensionId = "3"
println("d3:" + d3.hashCode())
var l = List(d1, d2, d3)
val categories = mutable.HashSet.empty[Dimension]
l.foreach(md => {
categories += md
})
println(categories.size) // size is 1
}
}
case class Dimension() {
var dimensionId: String = _
var name: String = _
}
HashCode in scala only considers attributes in the constructor for case classes.
If you define your case class in a more functional and scalish way (assuring inmutabilitity for instance) the behaviour will be the expected:
DEFINING
case class Dimension(dimensionId: String, name: String)
val d1 = Dimension("1", "d1")
val d2 = Dimension("2", "d2")
RESULT
scala> println("d1:" + d1.hashCode())
d1:732406741
scala> println("d2:" + d2.hashCode())
d2:952021182
You can find the generated code for the hashcode method in this awesome answer here
Quoting the spec:
Every case class implicitly overrides some method definitions of class
scala.AnyRef unless a definition of the same method is already given
in the case class itself or a concrete definition of the same method
is given in some base class of the case class different from AnyRef.
In particular:
Method equals: (Any)Boolean is structural equality, where two
instances are equal if they both belong to the case class in question
and they have equal (with respect to equals) constructor arguments
(restricted to the class's elements, i.e., the first parameter
section).
Method hashCode: Int computes a hash-code. If the
hashCode methods of the data structure members map equal (with respect
to equals) values to equal hash-codes, then the case class hashCode
method does too.
Since the argument list of the constructor is empty, every Dimension vacuously equals any other Dimension, therefore their hashCode must also be the same.
Just don't mix case classes with those weird uninitialized vars, or at least do it more carefully.
As pointed out, hashCode uses primary constructor args to generate its result. You can still have a working version of your case class using vars though, like:
case class Dimension(var dimensionId: String = "", var name: String = "")

What is the purpose of final val in Scala? [duplicate]

What is the reason for vals not (?) being automatically final in singleton objects? E.g.
object NonFinal {
val a = 0
val b = 1
def test(i: Int) = (i: #annotation.switch) match {
case `a` => true
case `b` => false
}
}
results in:
<console>:12: error: could not emit switch for #switch annotated match
def test(i: Int) = (i: #annotation.switch) match {
^
Whereas
object Final {
final val a = 0
final val b = 1
def test(i: Int) = (i: #annotation.switch) match {
case `a` => true
case `b` => false
}
}
Compiles without warnings, so presumably generates the faster pattern matching table.
Having to add final seems pure annoying noise to me. Isn't an object final per se, and thus also its members?
This is addressed explicitly in the specification, and they are automatically final:
Members of final classes or objects are implicitly also final, so
the final modifier is generally redundant for them, too. Note, however, that
constant value definitions (§4.1) do require an explicit final modifier, even if
they are defined in a final class or object.
Your final-less example compiles without errors (or warnings) with 2.10-M7, so I'd assume that there's a problem with the #switch checking in earlier versions, and that the members are in fact final.
Update: Actually this is more curious than I expected—if we compile the following with either 2.9.2 or 2.10-M7:
object NonFinal {
val a = 0
}
object Final {
final val a = 0
}
javap does show a difference:
public final class NonFinal$ implements scala.ScalaObject {
public static final NonFinal$ MODULE$;
public static {};
public int a();
}
public final class Final$ implements scala.ScalaObject {
public static final Final$ MODULE$;
public static {};
public final int a();
}
You see the same thing even if the right-hand side of the value definitions isn't a constant expression.
So I'll leave my answer, but it's not conclusive.
You're not asking "why aren't they final", you're asking "why aren't they inlined." It just happens that final is how you cue the compiler that you want them inlined.
The reason they are not automatically inlined is separate compilation.
object A { final val x = 55 }
object B { def f = A.x }
When you compile this, B.f returns 55, literally:
public int f();
0: bipush 55
2: ireturn
That means if you recompile A, B will be oblivious to the change. If x is not marked final in A, B.f looks like this instead:
0: getstatic #19 // Field A$.MODULE$:LA$;
3: invokevirtual #22 // Method A$.x:()I
6: ireturn
Also, to correct one of the other answers, final does not mean immutable in scala.
To address the central question about final on an object, I think this clause from the spec is more relevant:
A constant value definition is of the form final val x = e
where e is a constant expression (§6.24). The final modifier must be present and no type annotation may be given. References to the constant value x are themselves treated as constant expressions; in the generated code they are replaced by the definition’s right-hand side e.
Of significance:
No type annotation may be given
The expression e is used in the generated code (by my reading, as the original unevaluated constant expression)
It sounds to me like the compiler is required by the spec to use these more like macro replacements rather than values that are evaluated in place at compile time, which could have impacts on how the resulting code runs.
I think it is particularly interesting that no type annotation may be given.
This, I think points to our ultimate answer, though I cannot come up with an example that shows the runtime difference for these requirements. In fact, in my 2.9.2 interpreter, I don't even get the enforcement of the first rule.

Scala.js native Javascript constructors

Scala.js facade for a native JS types can look like this (from Three.js facade):
#js.native
#JSName("THREE.Vector3")
class Vector3 extends Vector {
def this(x: Double = js.native, y: Double = js.native, z: Double = js.native) = this()
var x: Double = js.native
var y: Double = js.native
var z: Double = js.native
/* ... */
}
The corresponding Javascript definition of a function constructing Vector3 is:
function Vector3( x, y, z ) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
}
I have read docs about creating Scala.js facades, however constructors are only briefly mentioned there. The code from the facade works fine in real code, however I am unsure if the definition is correct and why and how it works.
the facade lets no argument constructor exist.
the constructor with arguments just calls a no argument constructor. Still the object seems to be constructed fine, with the member set to the values passed.
the constructor uses js.native as default value for all arguments. Should all facades define constructors this way?
Esp. the second point is confusing to me. How can this be working? In all three cases I would like to know what JS code is generated for the constructor and why.
One could also imagine a different way how to write the facade. Would that be more correct?
class Vector3(var x: Double = js.native, var y: Double = js.native, var z: Double = js.native) extends Vector {
/* ... */
}
The definition is correct. The rules of facades for JavaScript constructors are quite simply stated: when encountering a call such as
new C(arg1, ..., argN)
and C is a JavaScript class, this translates to
new Cconstr(arg1, ..., argN)
where Cconstr is the result of evaluating js.constructorOf[C]. For a native JavaScript class, js.constructorOf[C] looks up the name of C in the global scope (or applies #JSName or #JSImport rules). Concretely, in your example, a call such as
new Vector3(3, 4, 5)
translates to
new <global>.THREE.Vector3(3, 4, 5)
Note, in particular, that the body of the constructor definitions is completely irrelevant, since the call site directly calls JavaScript code in the Three.js library. Hence, the fact that the 3-arg constructor calls the 0-arg constructor and ignores its arguments is simply disregarded by the semantic rules. The call is necessary to comply with Scala's type checking rules, but is semantically irrelevant.
Similarly, the actual value of default parameter values are semantically irrelevant. Their presence makes the parameters optional, but their value is otherwise ignored by the compiler. A call such as
new Vector3(3)
translates in JavaScript to
new <global>.THREE.Vector3(3)
in which the y and z parameters are altogether not given, leaving to JavaScript to decide what to do with them.
Finally, your alternative definition:
class Vector3(var x: Double = js.native, var y: Double = js.native, var z: Double = js.native)
is just equally valid. It doesn't have an explicit 0-arg constructor, but it can also be "accessed" by giving 0 argument to the constructor, which has 3 optional parameters anyway. This definition is certainly more concise, though, and looks a bit more Scala-esque, so I would personally define it that way. But it is not any more correct than the initial one.

Scala class members and constructor parameters name clash

Consider the following class written in Java:
class NonNegativeDouble {
private final double value;
public NonNegativeDouble(double value) {
this.value = Math.abs(value);
}
public double getValue() { return value; }
}
It defines a final field called value that is initialized in the constructor, by taking its parameter called alike and applying a function to it.
I want to write something similar to it in Scala. At first, I tried:
class NonNegativeDouble(value: Double) {
def value = Math.abs(value)
}
But the compiler complains: error: overloaded method value needs result type
Obviously the compiler thinks that the expression value inside the expression Math.abs(value) refers to the method being defined. Therefore, the method being defined is recursive, so I need to state its return type. So, the code I wrote does not do what I expected it to do: I wanted value inside Math.abs(value) to refer to the constructor parameter value, and not to the method being defined. It is as if the compiler implicitly added a this. to Math.abs(this.value).
Adding val or var (or private ... variants) to the constructor parameter doesn't seem to help.
So, my question is: can I define a property with the same name as a constructor parameter, but maybe a different value? If so, how? If not, why?
Thanks!
No, you can't. In Scala, constructor parameters are properties, so it makes no sense to redefine them.
The solution, naturally, is to use another name:
class NonNegativeDouble(initValue: Double) {
val value = Math.abs(initValue)
}
Used like this, initValue won't be part of the instances created. However, if you use it in a def or a pattern matching declaration, then it becomes a part of every instance of the class.
#Daniel C. Sobral
class NonNegativeDouble(initValue: Double) {
val value = Math.abs(initValue)
}
your code is right, but "constructor parameters are properties",this is not true.
A post from the official site said,
A parameter such as class Foo(x : Int) is turned into a field if it is
referenced in one or more methods
And Martin's reply confirms its truth:
That's all true, but it should be treated as an implementation
technique. That's why the spec is silent about it.
So normally, we can still treat primary constructor parameters as normal method parameter, but when the parameters is referenced by any of the methods, the compiler will cleverly turn it into a private field.
If any formal parameter preceded by the val, the compiler generates an getter definition automatically.if var, generates a setter additionally. see the language speification section 5.3.
That's all about primary constructor parameters.
You can consider parametric field
class NonNegativeDouble(val value: Double, private val name: String ){
if (value < 0) throw new IllegalArgumentException("value cannot be negative")
override def toString =
"NonNegativeDouble(value = %s, name = %s)" format (value, name)
}
val tom = "Tom"
val k = -2.3
val a = new NonNegativeDouble(k.abs, tom)
a: NonNegativeDouble = NonNegativeDouble(value = 2.3, name = Tom)
a.value
res13: Double = 2.3
a.name
<console>:12: error: value name in class NonNegativeDouble cannot be accessed in NonNegativeDouble
a.name
val b = new NonNegativeDouble(k, tom)
java.lang.IllegalArgumentException: value cannot be negative
...
It's defines fields and parameters with the same names "value", "name".
You can add modifiers such as private ...
In the case of case classes it should be:
case class NonNegativeDouble(private val initValue: Double) {
val value = Math.abs(initValue)
def copy(value: Double = this.value) = NonNegativeDouble(value)
}
The implementation of copy is required to prevent the sintesized version of the compiler that will bind the initValue argument.
I expect that the compiler is smart enough to not retain the «extra space» for the initValue. I haven't verified this behaviour.