Scala implicit type casting - scala

I'm just beginning Scala, coming from Java.
So I know that in Scala, all things are objects, and Scala matches the longest token (source: http://www.scala-lang.org/docu/files/ScalaTutorial.pdf), so if i understand correctly:
var b = 1.+(2)
then b is a Double, plus and Int, which in Java would be a Double.
But when I check its type via println(b.isInstanceOf[Int]) I see that it is an Int. Why is it not a Double like in Java?

According to the specification:
1. is not a valid floating point literal because the mandatory digit after the . is missing.
I believe it's done like that, exactly because expressions like 1.+(2) should be parsed as an integer 1, method call ., method name + and method argument (2).

The compiler would treat 1 and 2 as Ints by default. You could force either one of these to be a Double using 1.toDouble And the result (b) would be a double.
Btw - did you mean to write 1.0+2 - in which case b would be a double?

Related

What is the semantics of Long.toInt in Scala?

If long.isValidInt, then obviously, it evaluates to the corresponding Int value.
But what if it's not? Is it equivalent to simply dropping the leading bits?
Is it equivalent to simply dropping the leading bits?
Yes. To verify this you can either just try it or refer to the following section of the Scala specification:
Conversion methods toByte, toShort, toChar, toInt, toLong, toFloat, toDouble which convert the receiver object to the target type, using the rules of Java's numeric type cast operation. The conversion might truncate the numeric value (as when going from Long to Int or from Int to Byte) or it might lose precision (as when going from Double to Float or when converting between Long and Float).
And the corresponding section of the Java specification:
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.
Why this isn't just described in the ScalaDocs for the toInt method, I don't know.

How to coerce a value to a String in Pony?

I am trying to learn Pony, and for obvious reasons, one of the first things I want to do is print values.
However, it does not seem to work for most things, like:
env.out.print(2 + 2)
Gives the error:
Could not infer literal type, no valid types found
I also tried:
let four: U32 = 2 + 2
env.out.print(four)
But this gives an uglier error saying I need something that is a subtype of ByteSeq. Fine, but how do I get one of those?
You'll have to convert the integer into a String.
In Pony there is an interface called Stringable which declares the function string(fmt), and a lots of classes implements that interface. Integers do for instance.
So just call .string() to convert a value in something printable.

Working with opaque types (Char and Long)

I'm trying to export a Scala implementation of an algorithm for use in JavaScript. I'm using #JSExport. The algorithm works with Scala Char and Long values which are marked as opaque in the interoperability guide.
I'd like to know (a) what this means; and (b) what the recommendation is for dealing with this.
I presume it means I should avoid Char and Long and work with String plus a run-time check on length (or perhaps use a shapeless Sized collection) and Int instead.
But other ideas welcome.
More detail...
The kind of code I'm looking at is:
#JSExport("Foo")
class Foo(val x: Int) {
#JSExport("add")
def add(n: Int): Int = x+n
}
...which works just as expected: new Foo(1).add(2) produces 3.
Replacing the types with Long the same call reports:
java.lang.ClassCastException: 1 is not an instance of scala.scalajs.runtime.RuntimeLong (and something similar with methods that take and return Char).
Being opaque means that
There is no corresponding JavaScript type
There is no way to create a value of that type from JavaScript (except if there is an #JSExported constructor)
There is no way of manipulating a value of that type (other than calling #JSExported methods and fields)
It is still possible to receive a value of that type from Scala.js code, pass it around, and give it back to Scala.js code. It is also always possible to call .toString(), because java.lang.Object.toString() is #JSExported. Besides toString(), neither Char nor Long export anything, so you can't do anything else with them.
Hence, as you have experienced, a JavaScript 1 cannot be used as a Scala.js Long, because it's not of the right type. Neither is 'a' a valid Char (but it's a valid String).
Therefore, as you have inferred yourself, you must indeed avoid opaque types, and use other types instead if you need to create/manipulate them from JavaScript. The Scala.js side can convert back and forth using the standard tools in the language, such as someChar.toInt and someInt.toChar.
The choice of which type is best depends on your application. For Char, it could be Int or String. For Long, it could be String, a pair of Ints, or possibly even Double if the possible values never use more than 52 bits of precision.

Single-element parethesized expressions/tuples vs common use of parentheses

Sorry if this is trivial - I am so new to swift, actually I have only looked at the language guide+reference for a few minutes.
As far as I understand a parenthesized expression like (2,3) is used to construct a tuple, and (2) is a single-element tuple of type (Int).
But then what happens with common use of parentheses like (2+4) in expression (2+4)*5? Is this still a tuple of type (Int) multiplied by an Int?
From Types in the Swift book:
If there is only one element inside the parentheses, the type is
simply the type of that element. For example, the type of (Int) is
Int, not (Int).
So the type of (2) or (2+4) is simply Int, and the * in (2+4)*5 is
just integer multiplication.
+, * etc are infix operators, and they have a semantic meaning that's different from the comma ,, so the compiler treats it in a different way.

Adding spaces to the + operator in Scala gives different results?

Scala newbie here
Trying
(1).+(2) returns a Int value of 3, so far so good
but
1.+(2) returns a Double value of 3.0.
But if you do
1 . +(2) it returns a Int value of 3.
Note: The only difference between this and the above is the space after the "1"
Does Spaces matter in Scala? Im more curious as to how 1.+(2) returned a Double as it looks like it parsed 1. as a Double and then added "2" to it.
1.+(2) is calling the + method on the Double "1.". This is a carry-over from Java syntax, where "1." is equivalent to 1.0.