objects allocation in java vs scala? [duplicate] - scala

What is the difference between val a=new String("Hello") and val a="Hello"
Example:
val a="Hello"
val b="Hello"
a eq b
res:Boolean=True
Similarly:
val a=new String("Hello")
val b=new string("Hello")
a eq b
res:Bolean=False

eq compares memory references.
String literals are put in a string constants pool, so in the first example they share the same memory reference. This is a behavior that comes from Java (scala.String is built on top of java.lang.String).
In the second example you're allocating two instances at runtime so when you compare them they're are at different memory locations.
This is exactly the same as Java, so you can refer to this answer for more information: What is the difference between "text" and new String("text")?
Now, if you want to compare their values (as opposed to their memory references), you can use == (or equals) in Scala.
Example:
val a = new String("Hello")
val b = new String("Hello")
a eq b // false
a == b // true
a equals b // true
This is different than Java, where == is an operator that behaves like eq in Scala.
Also note that == and equals are slightly different in the way the deal with null values (== is generally advised). More on the subject: Whats the difference between == and .equals in Scala?

First of all eq (and its opposite ne) are used for what is called reference equality.
The behavior you observed is the result of what's technically known as string interning and is the inherited behavior from Java. Scala makes use of java.util.String under the hood. You can observe this in the REPL:
scala> val s = "Hello World!"
s: String = Hello World!
scala> s.isInstanceOf[java.lang.String]
res1: Boolean = true
You can see a general explanation of eq, ne, and == here.
To learn about JVM string interning see this Wikipedia article.

Related

What does { val x = a; b.:::(x) } mean in Scala?

I am new to Scala and studying a book about it (Programming in Scala). I am really lost, what is the author trying to explain with the code below. Can anyone explain it in more detail ?
{ val x = a; b.:::(x) }
::: is a method that prepends list given as argument to the list it is called on
you could look at this as
val a = List(1, 2)
val b = List(3, 4)
val x = a
b.prependList(x)
but actually for single argument methods if it's not ambiguous scala allows to skip parenthesis and the dot and this is how this method is supposed to be used to not look ugly
x ::: b
it will just join these two lists, but there is some trick here
if method name ends with : it will be bound the other way
so typing x ::: b works as if this type of thing was done (x):::.b. You obviously can't type it like this in scala, won't compile, but this is what happens. Thanks to this x is on the left side of the operator and it's elements will be on the left side (beginning) of the list that is result of this call.
Oh well, now I found maybe some more explanation for you and also the very same piece of code you posted, in answer to this question: What good are right-associative methods in Scala?
Assuming a and b are lists: It assigns a to x, then returns the list b prepended with the list x.
For example, if val a = List(1,2,3) and val b = List(4,5,6) then it returns List(1,2,3,4,5,6).

Any concise way to define a constant function (mapping) in scala

I am a newbie in Scala. I have the following code to define a constant function that returns true for 1,2,3 and false for the other Integers.( actually the function defines a set {1,2,3} of integers):
val a= Node1 _
def Node1(x:Int):Boolean={
if (x==1 || x ==2 || x==3){true}
else{false}
}
Is there any way to define this function more concisely?
val a: Int => Boolean = Set(1, 2, 3).contains(_)
which is effectively same as
val a: Int => Boolean = Set(1, 2, 3)
This is because Set's apply method is same as its contains method.
On lookup performance, although as aforementioned Set.apply conveys the desired semantics, note that Set is a trait that may implement for instance ListSet, HashSet or TreeSet, each designed for specific uses.
For the aim here of looking up for an element, consider TreeSet (see Collections Performance Characteristics for details) outperforms other Set implementations. This proves relevant specially for large collections.

Why does Slick require using three equal signs (===) for comparison?

I was reading through coming from SQL to Slick and it states to use === instead of == for comparison.
For example,
people.filter(p => p.age >= 18 && p.name === "C. Vogt").run
What is the difference between == and ===, and why is the latter used here?
== is defined on Any in Scala. Slick can't overload it for Column[...] types like it can for other operators. That's why slick needs a custom operator for equality. We chose === just like several other libraries, such as scalatest, scalaz, etc.
a == b will lead to true or false. It's a client-side comparison. a === b will lead to an object of type Column[Boolean], with an instance of Library.Equals(a,b) behind it, which Slick will compile to a server-side comparison using the SQL "a = b" (where a and b are replaced by the expressions a and b stand for).
== calls for equals, === is a custom defined method in slick which is used for column comparison:
def === [P2, R](e: Column[P2])(implicit om: o#arg[B1, P2]#to[Boolean, R]) =
om.column(Library.==, n, e.toNode)
The problem of using == for objects is this (from this question):
Default implementation of equals() class provided by java.lang.Object compares memory location and only return true if two reference variable are pointing to same memory location i.e. essentially they are same object.
What this means is that two variables must point to the same object to be equal, example:
scala> class A
defined class A
scala> new A
res0: A = A#4e931efa
scala> new A
res1: A = A#465670b4
scala> res0 == res1
res2: Boolean = false
scala> val res2 = res0
res2: A = A#4e931efa
scala> res2 == res0
res4: Boolean = true
In the first case == returns false because res0 and res1 point to two different objects, in the second case res2 is equal to res0 because they point to the same object.
In Slick columns are abstracted in objects, so having column1 == column2 is not what you are looking for, you want to check equality for the value a column hold and not if they point to the same object. Slick then probably translates that === in a value equality in the AST (Library.== is a SqlOperator("="), n is the left hand side column and e the right hand side), but Christopher can explain that better than me.
'==' compare value only and result in Boolean 'True' & 'False
'===' compare completely (i.e. compare value with its data types) and result in column
example
1=='1' True
1==='1' False

Unique id for Scala object

In Python, id(x) gives the unique id of object x. What's the equivalence in Scala?
>>> id(True)
1166096
>>> id(False)
1166108
>>> x = id([1,2,3])
>>> id(x)
2058589988
>>> y = id([1,2,3])
>>> id(y)
2058589976
I could use x.hashCode for the id, but it will return the same value when the contents are the same. I'd like to know what makes a eq b == false in the following code. What values are compared in a eq b?
scala> val a = ArrayBuffer(1,2,3)
a: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3)
scala> val b = ArrayBuffer(1,2,3)
b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3)
scala> a.hashCode
res44: Int = 387518613
scala> b.hashCode
res45: Int = 387518613
scala> a eq b
res39: Boolean = false
It is not possible to do this. You need to generate and keep track of IDs yourself.
eq compares references, and is similar to == in Java.
There is System.identityHashCode (which is the default implementation of Any.hashCode) but it is not guaranteed to be unique.
You may be able to implement id using the JNI, although it might not be trivial due to the possibility of a compacting GC being in place. I don't know much about the JNI, though.
Even then, I don't see id as a useful function and I don't see any use for it. If you need a reference to an object, store a reference. If you need a weak reference, use a java.lang.ref.WeakReference[T].
I could use x.hashCode for the id, but it will return the same value
when the contents are the same.
First of all: no. As per the documentation: "The default hashing algorithm is platform dependent." So do not make any assumption on hashCode.
Second: eq compares references. As per the documentation: "Tests whether the argument (arg0) is a reference to the receiver object (this)."
Third: you can't get the equivalent of the python id in scala.

Declaring multiple variables in Scala

I'd like to use val to declare multiple variable like this:
val a = 1, b = 2, c = 3
But for whatever reason, it's a syntax error, so I ended up using either:
val a = 1
val b = 2
val c = 3
or
val a = 1; val b = 2; val c = 3;
I personally find both options overly verbose and kind of ugly.
Is there a better option?
Also, I know Scala is very well thought-out language, so why isn't the val a = 1, b = 2, c = 3 syntax allowed?
The trivial answer is to declare them as tuples:
val (a, b, c) = (1, 2, 3)
What might be interesting here is that this is based on pattern matching. What is actually happens is that you are constructing a tuple, and then, through pattern matching, assigning values to a, b and c.
Let's consider some other pattern matching examples to explore this a bit further:
val DatePattern = """(\d{4})-(\d\d)-(\d\d)""".r
val DatePattern(year, month, day) = "2009-12-30"
val List(rnd1, rnd2, rnd3) = List.fill(3)(scala.util.Random.nextInt(100))
val head :: tail = List.range(1, 10)
object ToInt {
def unapply(s: String) = try {
Some(s.toInt)
} catch {
case _ => None
}
}
val DatePattern(ToInt(year), ToInt(month), ToInt(day)) = "2010-01-01"
Just as a side note, the rnd example, in particular, may be written more simply, and without illustrating pattern matching, as shown below.
val rnd1, rnd2, rnd3 = scala.util.Random.nextInt(100)
Daniel's answer nicely sums up the correct way to do this, as well as why it works. Since he already covered that angle, I'll attempt to answer your broader question (regarding language design)...
Wherever possible, Scala strives to avoid adding language features in favor of handling things through existing mechanisms. For example, Scala doesn't include a break statement. However, it's almost trivial to roll one of your own as a library:
case object BreakException extends RuntimeException
def break = throw BreakException
def breakable(body: =>Unit) = try {
body
} catch {
case BreakException => ()
}
This can be used in the following way:
breakable {
while (true) {
if (atTheEnd) {
break
}
// do something normally
}
}
(note: this is included in the standard library for Scala 2.8)
Multiple assignment syntaxes such as are allowed by languages like Ruby (e.g. x = 1, y = 2, z = 3) fall into the category of "redundant syntax". When Scala already has a feature which enables a particular pattern, it avoids adding a new feature just to handle a special case of that pattern. In this case, Scala already has pattern matching (a general feature) which can be used to handle multiple assignment (by using the tuple trick outlined in other answers). There is no need for it to handle that particular special case in a separate way.
On a slightly different aside, it's worth noting that C's (and thus, Java's) multiple assignment syntax is also a special case of another, more general feature. Consider:
int x = y = z = 1;
This exploits the fact that assignment returns the value assigned in C-derivative languages (as well as the fact that assignment is right-associative). This is not the case in Scala. In Scala, assignment returns Unit. While this does have some annoying drawbacks, it is more theoretically valid as it emphasizes the side-effecting nature of assignment directly in its type.
I'll add one quirk here, because it hit myself and might help others.
When using pattern matching, s.a. in declaring multiple variables, don't use Capital names for the variables. They are treated as names of classes in pattern matching, and it applies here as well.
val (A,B)= (10,20) // won't work
println(A)
Error message does not really tell what's going on:
src/xxx.scala:6: error: not found: value A
val (A,B)= (10,20)
^
src/xxx.scala:6: error: not found: value B
val (A,B)= (10,20)
^
src/xxx.scala:7: error: not found: value A
println(A)
^
I thought `-ticking would solve the issue but for some reason does not seem to (not sure, why not):
val (`A`,`B`)= (10,20)
println(A)
Still the same errors even with that.
Please comment if you know how to use tuple-initialization pattern with capital variable names.
If all your variables are of the same type and take same initial value, you could do this.
val a, b, c: Int = 0;
It seems to work if you declare them in a tuple
scala> val (y, z, e) = (1, 2, 45)
y: Int = 1
z: Int = 2
e: Int = 45
scala> e
res1: Int = 45
Although I would probably go for individual statements. To me this looks clearer:
val y = 1
val z = 2
val e = 45
especially if the variables are meaningfully named.