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

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.

Related

Purescript: Convert Maybe Type to Type

The following simple code converts an Integer value to a string value and logs it.
module Main where
import Effect (Effect)
import Effect.Console (log)
import Prelude ((<>), Unit, discard)
import Data.Int (toStringAs, radix)
type CustomerFeedback = {
customerServiceScore :: Int,
productQualityScore :: Int,
onTimeDeliveryScore :: Int
}
feedback :: CustomerFeedback
feedback = {
customerServiceScore : 4,
productQualityScore : 2,
onTimeDeliveryScore : 6
}
stringifyCustomerFeedback :: CustomerFeedback -> String
stringifyCustomerFeedback feedback = "Service: " <> toStringAs (radix 10) feedback.customerServiceScore
main ∷ Effect Unit
main = do
log (stringifyCustomerFeedback(feedback))
However, running this code produces the following error:
Could not match type
Maybe Radix
with type
Radix
while checking that type Maybe Radix
is at least as general as type Radix
while checking that expression radix 10
has type Radix
in value declaration stringifyCustomerFeedback
Questions would be as follows:
How do you change the code above so it outputs a string as expected and not an error?
What's the point of a Maybe Radix type if using it where you would use a Radix causes an error? How do you use a Maybe value?
The idea of the radix function is that you give it a number and it creates a Radix from it. But not every number constitutes a valid Radix. For example, if you give it -5, it shouldn't work. And neither should 0 or 1 for example. For some technical reasons, radices above 32 are also deemed invalid.
So that's why it returns Maybe: it would be Nothing in case the number you gave it wasn't a "valid" radix.
And the use case for that function is when you don't actually know the number ahead of time. Like if you get it from the user. Or from some sort of config file or whatnot. In that case, if you get a Nothing, you would interpret that as "invalid user input" or "corrupted config file" and report an error accordingly. And you won't even get as far as calling toStringAs. This is one of the big selling points of static types: applied properly, they can force you to write a correct, reliable program, without ignoring edge cases.
However, in case you already know that you're interested in decimal radix, just use decimal. It's a Maybe-free constant provided by the library, along with some other frequently used ones, such as binary and octal.
stringifyCustomerFeedback feedback = "Service: " <> toStringAs decimal feedback.customerServiceScore

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

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.

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.

Syntax of calling a function in scala

Hi I am studying the scala language and have a question. I am reading a book and one of the example says that 0 to 2 is same as (0).to(2). How can I interpret this syntax?? I mean, I can see that to is a function that takes one integer value as its parameter. But what is "(0)." part?? Thanks
In scala any method taking a single parameter can be written with infix syntax.
So for instance if you have
class Foo(x: Int) {
def add(y: Int) = x + y
}
val a = new Foo(42)
then these two method calls are exactly equivalent
a.add(4) // 46
a add 4 // 46
The reason why there's a parenthesis around the 0 is that in older versions of scala the 0. would have been interpreted as a floating point number, due to the ambiguous value of . (which can be both a decimal separator and a method selector). Since scala 2.11 (or 2.10, I don't remember), this has been fixed, so you can now safely type
0.+(2) // Int: 2
and get an Int back, whereas you would have had a Float in the past, as the compiler would have seen it as
0.0 + (2) // Float: 2
I mean, I can see that to is a function that takes one integer value as its parameter.
No, it's not a function, it's a method.
Methods are invoked by sending a message to an object:
foo.bar(baz)
This means "send the message bar with the object referenced by baz as argument to the object referenced by foo. This will in turn cause the method bar in foo's class or one of its ancestors to be invoked.
So, to is the message, 2 is the argument, and 0 is the receiver of the message.
Scala allows you to use either a . or whitespace for message sending:
foo bar(baz)
// is the same as
foo.bar(baz)
Also, when using whitespace for message sending, you can leave off the parentheses of the last argument list if it has only a single argument:
foo bar baz
// is the same as
foo bar(baz)
And lastly, parentheses are not only used for argument lists, they are also used for grouping. (And tuple literals as well.) You can always surround an expression with parentheses to clarify its precedence:
(foo).bar(baz)
// is the same as
foo.bar(baz)

Scala closures on wikipedia

Found the following snippet on the Closure page on wikipedia
//# Return a list of all books with at least 'threshold' copies sold.
def bestSellingBooks(threshold: Int) = bookList.filter(book => book.sales >= threshold)
//# or
def bestSellingBooks(threshold: Int) = bookList.filter(_.sales >= threshold)
Correct me if I'm wrong, but this isn't a closure? It is a function literal, an anynomous function, a lambda function, but not a closure?
Well... if you want to be technical, this is a function literal which is translated at runtime into a closure, closing the open terms (binding them to a val/var in the scope of the function literal). Also, in the context of this function literal (_.sales >= threshold), threshold is a free variable, as the function literal itself doesn't give it any meaning. By itself, _.sales >= threshold is an open term At runtime, it is bound to the local variable of the function, each time the function is called.
Take this function for example, generating closures:
def makeIncrementer(inc: Int): (Int => Int) = (x: Int) => x + inc
At runtime, the following code produces 3 closures. It's also interesting to note that b and c are not the same closure (b == c gives false).
val a = makeIncrementer(10)
val b = makeIncrementer(20)
val c = makeIncrementer(20)
I still think the example given on wikipedia is a good one, albeit not quite covering the whole story. It's quite hard giving an example of actual closures by the strictest definition without actually a memory dump of a program running. It's the same with the class-object relation. You usually give an example of an object by defining a class Foo { ... and then instantiating it with val f = new Foo, saying that f is the object.
-- Flaviu Cipcigan
Notes:
Reference: Programming in Scala, Martin Odersky, Lex Spoon, Bill Venners
Code compiled with Scala version 2.7.5.final running on Java 1.6.0_14.
I'm not entirely sure, but I think you're right. Doesn't a closure require state (I guess free variables...)?
Or maybe the bookList is the free variable?
As far as I understand, this is a closure that contains a formal parameter, threshold and context variable, bookList, from the enclosing scope. So the return value(List[Any]) of the function may change while applying the filter predicate function. It is varying based on the elements of List(bookList) variable from the context.