Why in Scala this statement is not a NullPointerException? null.asInstanceOf[Double] - scala

I am coming from Java, and trying to understand the following Scala syntax
null.asInstanceOf[Double]
Why is this not a NullPointerException?
I was trying to do something like:
var d : Double = 0
if(d == null)
// do something
However, I got following error message:
comparing values of types Double and Null using `==' will always yield false
This got fixed when I changed null to null.asInstanceOf[Double] as per this answer, but this is a weird statement for me, how on earth this is working?

Scala's scala.Double does not correspond to Java's java.lang.Double. Scala's double inherits from AnyVal, the parent of all value types. It most closely corresponds to the primitive type double in Java, which can't be null. When you do null.asInstanceOf[Double], you're actually getting the double value 0.0, not a null double.
From the Scala language specification section 6.3
[the null value] implements methods in scala.AnyRef as follows
...
asInstanceOf[T] returns the default value of type T
And the default value of Double is zero.
So, in short, your value can't possibly be null because it's like a Java primitive. So you don't need to do a null check in this case.

Related

Mypy fails to find a type error in simple one line function [duplicate]

Why does "mypy" consider "int" as a subtype of "float"? A subtype shall support all methods of its supertype, but "float" has methods, which "int" does not support:
test.py:
def f(x : float) -> bool:
return x.is_integer()
print(f(123.0))
print(f(123))
The static type checker accepts passing an "int" argument for a "float" parameter:
(3.8.1) myhost% mypy test.py
Success: no issues found in 1 source file
But this does not guarantee, that there are no errors at runtime:
(3.8.1) myhost% python test.py
True
Traceback (most recent call last):
File "test.py", line 5, in <module>
print(f(123))
File "test.py", line 2, in f
return x.is_integer()
AttributeError: 'int' object has no attribute 'is_integer'
because "float" has additional methods, which "int" does not have.
'Why does "mypy" consider "int" as a subtype of "float"?'
Because practicality has so far been considered to beat purity here. This is not to say that one could not propose that typing define a Scalar type that would include ints and floats but only be valid for arithmetic operations.
Note that int / int was changed in 3.0 so that float(int / int) == float(int) / float(int), to make int and float arithmetic consistent for equal int and float values.
Note also that a type-check passing does not mean no runtime errors: division by zero and overflow are still possible, as well as many others.
As #juanpa.arrivillaga pointed out, the explanation is on https://mypy.readthedocs.io/en/latest/duck_type_compatibility.html.
A subtype shall support all methods of its supertype, but "float" has methods, which "int" does not support
int is not a subtype of float, so it doesn't have to support methods of float.
The mechanism is good because passing integer values shouldn't cause errors, unless you really want them as in your example. You explicitly tried to use a method which doesn't exist. In common situations, we only make arithmetic operations on numbers, so a problem rarely exists and you can always avoid it by adding .0 as you wrote.
It is a common behavior in most languages to assume that int is a special case of float, consider for example C++ int to float implicit conversion.

Big Int in scala

I'm new to Scala. I'm trying to create a test case for a simple factorial function.
I couldn't assign the result value in the assert statement. I'm getting
Integer number is out of range even for type Long error in IntelliJ.
test("Factorial.factorial6") {
assert(Factorial.factorial(25) == 15511210043330985984000000L)
}
I also tried to assign the value to val, using the 'L' literal, again it shows the same
message.
val b: BigInt = 15511210043330985984000000L
I'm clearly missing some basic stuff about Scala, I would appreciate your help, to solve this
The value you are giving is indeed larger than can be held in a Long, and that is the maximum size for a literal value in Scala. However you can initialise a BigInt using a String containing the value:
val b = BigInt("15511210043330985984000000")
and therefore
assert(Factorial.factorial(25) == BigInt("15511210043330985984000000"))

The result null.asInstanceOf[Int] is 0

When I run null.asInstanceOf[Int], I am surprised to find that the result is 0, I would ask why it is 0, I thought it should be null
I thought it should be null
It can't be null because Int doesn't have a null value. You can see it if you try null: Int (type ascription instead of a cast), though the error message is ugly.
why it is 0
Because it's defined this way in http://scala-lang.org/files/archive/spec/2.12/06-expressions.html#the-null-value:
asInstanceOf[T] [on null] returns the default value of type T.
Interestingly, it used to be defined to throw NullPointerException instead, but actually implemented in the current way, so the specification was changed: https://issues.scala-lang.org/browse/SI-5236

Swift float multiplication error

This code fails:
let element: Float = self.getElement(row: 1, column: j)
let multiplier = powf(-1, j+2)*element
with this error:
Playground execution failed: :140:51: error: cannot invoke '*' with an argument list of type '(Float, Float)'
let multiplier = powf(-1, j+2)*element
Bear in mind that this occurs in this block:
for j in 0...self.columnCount {
where columnCount is a Float. Also, the first line does execute and so the getElement method indeed returns a Float.
I am completely puzzled by this as I see no reason why it shouldn't work.
There is no implicit numeric conversion in swift, so you have to do explicit conversion when dealing with different types and/or when the expected type is different than the result of the expression.
In your case, j is an Int whereas powf expects a Float, so it must be converted as follows:
let multiplier = powf(-1, Float(j)+2)*element
Note that the 2 literal, although usually considered an integer, is automatically inferred a Float type by the compiler, so in that case an explicit conversion is not required.
I ended up solving this by using Float(j) instead of j when calling powf(). Evidently, j cannot be implicitly converted to a Float.

Why is "Hello".foldLeft(1)(_.toLong * _.toLong) an error?

I'm new to Scala and a bit perplexed. While going through "Scala for the Impatient," and doing the exercises, I tried one where the result is the product of all the numeric values of the string "Hello". My first thought was to do the following:
"Hello".foldLeft(1)(_.toLong * _.toLong)
However, the expression (_.toLong * _.toLong) results in a type mismatch between the operator and the operand, an Int was expected, but it received a Long.
The following works, though:
"Hello".map(_.toLong).reduce(_ * _)
Why does the operator '*' expect an Int instead of a Long when using foldLeft? Is it because of the list's contents? Are the characters implicitly converted to Ints?
Thanks!
(Promoting my comment to an answer so the question can be closed.)
This is because your initial argument, 1, has type Int. You can resolve this by changing it to 1L.