I'm a former Java developer, and I recently watched a penetrating and interesting introduction to Scala for Java developers by Professor Venkat Subramaniam ( https://www.youtube.com/watch?v=LH75sJAR0hc ).
An important point is the exclusion of declared types instead of "type inference". Presumably, this means that a higher order compiler recognizes the type that I intend to use in context.
As an application security expert by profession, the first thing I tried to do was break this type of output ... Example:
// declare a function that returns the square of an input Int. The return type is to be inferred. scala> val square = (x:Int) => x*x square: Int => Int = <function1> // I can see the compiler inferred an Int for the output value, which I do not agree with. scala> square(2147483647) res1: Int = 1 // integer overflow
My question is, why did the compiler not notice that the “*” is an overflow operator and wraps the inputs with something more protective like BigInteger?
, -. , Scala , , .
, @rightføld , ( , ). . BigInteger Java. , , - .
BigInteger
String . , , . , cstrings. BigInteger . , (, , ).
cstring ( strcmp, strcpy, strcat ..), , . , , , , . , , .
@rightføld , Java , , , BigInteger. , , ( ).
BigInteger (, python), , , ( ) Java.
, , . , , - Int BigInt. "" , .
* Int Int, Int
*
def *(x: Int): Int
, x Int, x*x Int *.
x
Int
x*x
, , Int BigInt .
BigInt
implicit class SafeInt(x: Int) { def safeMult(a: Int): scala.math.BigInt = scala.math.BigInt(x)*a }
, :
scala> val square = (x: Int) => x safeMult x square: Int => scala.math.BigInt = <function1>
. Int *(Int): Int, , , ; 2147483647*2147483647 - 1, ClassCastException - .
*(Int): Int
2147483647*2147483647
1
ClassCastException
Int ? Java/JVM; Scala Java. , Haskell . ( , JVM, Scala , , / , . , )
Scala, , , Spire, . , SafeLong, , , BigInt , Long, Python.
SafeLong
Long
, BigInteger , , Int. * Int return BigInteger s.
" , " , w60. , , . , List(Nil, "1"), List[Serializable], Serializable - , List String share - , Serializable, , .
List(Nil, "1")
List[Serializable]
Serializable
List
String
, , " Int BigInteger?" - .
, , , , scala - , : " Java".
If you need a type of security that you think is desirable, then one approach is to define a partial function that protects against numerical overflow, and then returns either the [Int] option, or even, possibly, [Int, BigInteger],
The type inference for your square function is correct - given that it is inferred from the specified input types and function type * ... in my opinion it is not broken.