kotlin - automatic conversion of numeric types [duplicate] - type-conversion

This question already has answers here:
Why doesn't Kotlin perform automatic type-casting?
(3 answers)
Closed 5 years ago.
In java, we can assign int to double, for example double x = 123;
In kotlin, we got a compiled error.
Question: Can we enable automatic conversion feature in kotlin? Why kotlin don't have this feature by default?
var x: Double = 123; // ERROR
One more example:
fun foo(x: Double) { }
fun main(args: Array<String>) {
foo(123.0); // OK
foo(123); // ERROR
}
UPDATE:
the literal 123 can be automatically converted to Short or Long at compile time. But it will not be converted to Float or Double.
fun fooShort(x: Short) {}
fun fooInt(x: Int) {}
fun fooLong(x: Long) {}
fun main(args: Array<String>) {
fooShort(123) // OK
fooInt(123) // OK
fooLong(123) // OK
}

No. This isn't going to happen. As kotlin is strongly typed meaning types aren't coerced implicitly. You need an explicit type conversion. From the Kotlin reference for Explicit number conversions it is stated:
Due to different representations, smaller types are not subtypes of bigger ones.
[...]
As a consequence, smaller types are NOT implicitly converted to bigger types.
[...]
We can use explicit conversions to widen numbers.

Related

Scala Mock Syntax (class _).expects meaning? [duplicate]

This question already has answers here:
What is the eta expansion in Scala?
(2 answers)
Closed 4 years ago.
New to Scala, have searched far and wide for clarification on some ScalaMock syntax. As per this guide, I keep seeing the following general testing pattern:
(myClass.myMethod _).expects()
What exactly is happening here? What function does the class/method/space/underscore serve? How does the compiler treat this?
The appended _ forces the conversion of a method into a function.
To understand why this is necessary, let's try to re-build a tiny piece of Scalamock, namely the expects method. The expects method seems to be invoked on methods of mocked objects. But methods / functions do not have an expects method to begin with. Therefore, we have to use the "pimp my library"-pattern to attach the method expects to functions. We could do something like this:
implicit class ExpectsOp[A, B](f: A => B) {
def expects(a: A): Unit = println("it compiles, ship it...")
}
Now let's define a class Bar with method baz:
class Bar {
def baz(i: Int): Int = i * i
}
and also an instance of Bar:
val bar = new Bar
Let's see what happens if you try to invoke expects on bar.baz:
(bar.baz).expects(42)
error: missing argument list for method baz in class Bar
Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing baz _ or baz(_) instead of baz.
So, it doesn't work without explicit conversion into a function, and we have to enforce this conversion by appending an _:
(bar.baz _).expects(42) // prints: "it compiles, ship it..."

Why can I concatenate String and Int in Scala?

I'm trying out some things in Scala, coming from Python. Since Scala is a lot more strict about keeping types consistent, I was surprised to find out that I can do the following concatenation, which would blow up in Python:
def adder(one:Any, two:String) = {one+two}
adder("word", "suffix")
res13: String = wordsuffix
But also:
val x:Int = 1
adder(x, "suffix")
res12: String = 1suffix
So it just transforms an Int into a String w/out telling me. What is this called and what is the logic behind it?
And what is the benefit of this? I feel it can come back to bite me, e.g. when dealing with user input to a function.
I know this is not very specific and if this is too broad, I'll gladly retract the question.
There is an implicit class in scala.Predef that operates on objects of any type
implicit final class any2stringadd[A](private val self: A) extends AnyVal {
def +(other: String): String = String.valueOf(self) + other
}
That implements Any + String (as you have defined it in adder). As rogue-one mentioned, there is also a method for concatenating String + Any defined in StringOps. If you tried to do Any + Any it would fail because it's expecting a String as the argument.
So it just transforms an Int into a String w/out telling me
Scala is converting your Int into a String, but it's not a type conversion because Int cannot be coerced into a String. You can observe that by trying something like this:
def foo(str: String) = ???
foo(5) // Type mismatch: expected: String, actual: Int
That will fail to compile because Scala can't magically coerce an Int into a String.
what is the logic behind it?
See implicit classes
And what is the benefit of this? I feel it can come back to bite me, e.g. when dealing with user input to a function.
It's a convenience method that's very specific to String and concatenation. This feature is implemented in Java, so I believe it was implemented in Scala to maintain source compatibility. My example above shows that (except in this specific case), user input to a function will respect the types defined on the function.
It's called implicit conversion (or implicit typecasting)
The purpose - convenience so you don't have to do everything manually. Most high-level languages will do that with the most used generics like strings, ints, bools...
You can check scala.Predef to see all the methods used when implicitly converting types, and you can take control of it using scala.language.implicitConversions. Read more at Scala Documentation.
This String concatenation not only works for Int but for any data-type. For instance
scala> case class Elephant(value: String)
defined class Elephant
scala> "Hello" + Elephant("elephant")
res2: String = HelloElephant(elephant)
This is because of the method + defined in StringOps (via Predef) class that accepts argument of type Any. So it is a method that is made available to a String object via implicit conversion that takes an argument of type Any. so "Hello" + Elephant("elephant") is actually "Hello".+(Elephant("elephant"))

scala simple example of proper subtyping

I'm new to scala and trying to understand the right way to think about subtypes, so here's a simple example.
Let's say I want to make a function truncation() that takes a number and rounds it down to a few decimals places and returns the result. I might go about this as,
def truncation(number:Double, level:Int)={
math.floor(number * math.pow(10,level)) / math.pow(10,level)
}
truncation(1.2345, 2)
res0: Double = 1.23
But I probably also want this function to work with other numeric types besides Double, such as Float.
So how should I think about generalizing this function to work well with multiple types?
I'm thinking I should be using generic types such as
def truncation [A](number:A, level:Int):A={
math.floor(number * math.pow(10,level)) / math.pow(10,level)
}
but this doesn't compile.
In the case of just two types, I see that the Either type is a good option. But in the more general case,maybe I'll want to be able to handle Ints as well, and have different implementations that match on the type of the input object.
What's the best way to be thinking about this? Thanks for your help.
For a generic that you want to constrain to numeric types, you can use Numeric:
def truncation[T](number: T, level:Int)(implicit n: Numeric[T]) = {
import math._
val doubleValue = n.toDouble(number)
floor(doubleValue * pow(10,level)) / pow(10,level)
}
Or equivalently:
def truncation[T : Numeric](number: T, level:Int) = {
import math._
val doubleValue = implicitly[Numeric[T]].toDouble(number)
floor(doubleValue * pow(10,level)) / pow(10,level)
}
These will work for Ints, Doubles, Floats, and other numeric types.
The first example uses an implicit parameter, which you can read about here. The second version uses a context bound, which you can read about here together with the implicitly operator, which you can read about here. Finally, read the documentation of Numeric here to see all the available methods.
Note that the versions above both return Double. If you want them to return T (whatever the input type is), you can try:
def truncation[T : Numeric](number: T, level:Int): T = implicitly[Numeric[T]] match {
case n:Fractional[T] =>
val tenPow = n.fromInt(math.pow(10, level).toInt)
n.div(n.fromInt(n.toInt(n.times(number, tenPow))), tenPow)
case n:Integral[T] => number
}

Scala : Difference between two ways declare a function [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the rationale behind curried functions in Scala?
I have two difference ways to declare a function: 1) use currying. 2)use function as parameter.
Here is my code :
def transform(f: Double => Double)(input: Double) = {
f(input)
}
def transformVer2(f: Double => Double, input: Double) = {
f(input)
}
transform(x=>x*x)(10) //> res8: Double = 100.0
transformVer2(x=>x*x, 10) //> res9: Double = 100.0
I don't know what the real difference of two above declare of a function. Please tell me.
Thanks :)
The former employs currying, the latter is something you're probably more familiar with from languages like C, C++, etc.
Currying is something that is prominent in functional programming languages.. functional programming languages place the idea of functions and function chaining in high regard so something like
def transform(f: Double => Double)(input: Double)
Can be seen as something that takes as a single argument a function Double => Double and returns another function that takes as a single argument a Double and returns a Double.
As Programming in Scala discusses, function currying also let's us do some nifty things, two of which come to mind are
type inference
new control abstractions
For type inference, consider something like foldLeft.
val myVector = Vector(1, 2, 3, 4)
myVector.foldLeft(0.0)(_ + _)
foldLeft is curried, and us specifying 0.0 as the initial value let's the type inferencer know we want our final result to be a Double.
For new control abstractions, we can do something like
def doWithFileAndClose(file: File)(func: () => Unit): Unit =
try { func() } finally { file.close }
which would be used like
doWithFileAndClose("somefile.txt") {
/* do stuff */
}
This takes advantage that Scala will accept curly braces in place of parentheses, which makes the above look just like familiar control structures such as for and while loops.

How do I implement a generic mathematical function in Scala

I'm just getting started with Scala and something which I think should be easy is hard to figure out. I am trying to implement the following function:
def square(x:Int):Int = { x * x }
This works just fine, but if I want to try to make this function work for any kind of number I would like to be able to do the following:
def square[T <: Number](x : T):T = { x * x }
This complains and says: error: value * is not a member of type parameter T
Do I need to implement a trait for this?
That was one of my first questions in Stack Overflow or about Scala. The problem is that Scala maintains compatibility with Java, and that means its basic numeric types are equivalent to Java's primitives.
The problem arises in that Java primitives are not classes, and, therefore, do not have a class hierarchy which would allow a "numeric" supertype.
To put it more plainly, Java, and, therefore, Scala, does not see any common grounds between a Double's + and a an Int's +.
The way Scala finally got around this restriction was by using Numeric, and its subclasses Fractional and Integral, in the so-called typeclass pattern. Basically, you use it like this:
def square[T](x: T)(implicit num: Numeric[T]): T = {
import num._
x * x
}
Or, if you do not need any of the numeric operations but the methods you call do, you can use the context bound syntax for type declaration:
def numberAndSquare[T : Numeric](x: T) = x -> square(x)
For more information, see the answers in my own question.
You can define square as:
def square[T: Numeric](x: T): T = implicitly[Numeric[T]].times(x,x)
This approach has the advantage that it will work for any type T that has an implicit conversion to Numeric[T] (i.e. Int, Float, Double, Char, BigInt, ..., or any type for which you supply an implicit conversion).
Edit:
Unfortunately, you'll run into trouble if you try something like List(1,2,3).map(square) (specifically, you'll get a compile error like "could not find implicit value for evidence parameter of type Numeric[T]". To avoid this issue, you can overload square to return a function:
object MyMath {
def square[T: Numeric](x: T) = implicitly[Numeric[T]].times(x,x)
def square[T: Numeric]: T => T = square(_)
}
Hopefully someone with a better understanding of the type inferencer will explain why that is.
Alternatively, one can call List(1,2,3).map(square(_)), as Derek Williams pointed out in the scala-user mailing list thread.