-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Numeric widening and weak conformance #2451
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Could we simply remove weak conformance from the language altogether? Seems like a thing inherited from Java that few like anyway. |
Strictly speaking we don't have weak conformance in dotty anymore. What we have is a new, more restricted and more localized rule. It applies to
If the expressions in these scenarios all have primitive numeric types, we make sure it's the same numeric type by widening as necessary. The new rule is less sweeping and much easier to specify than the old one. (See |
Could we experiment with disabling it completely, i.e. making it union type or a type error? It still seems like the new approach wouldn't address the problems some people complain about with longs getting "widened" to floats, and precision being lost. |
I believe there's lots of code out there, in particular dealing with numerics where you write something like
and so on. What's the point in requiring people to write The other observation I have is that the amount of heat is often inversely proportional to the importance of an issue. This one here is about as unimportant as it gets. Scala's original weak conformance rules could be criticized for being too complicated. The new rules aren't. Are there constructed corner cases where they might do something that surprises some people? Sure. Should we care? I guess you know my position. |
@odersky, in cases where constants are explicitly written, we can actually check if precision is lost during numeric conversion in compile time. |
@DarkDimius Indeed.
(from my brainstorming in #2289 (comment)) |
@odersky I think the "heat" argument works both ways: we shouldn't make too much fuss about allowing people to write So as a more radical alternative, could we instead infer the type of literal numbers to be the intersection of all the types in which those literals are precisely representable, and then deal with removing the intersections during erasure?
The LUBs in an expression like This may also help solve the problem which still exists in both Dotty and Scala where expressions like I think the challenge would be in finding the correct point to widen the type. It seems to work well for singleton literals currently (though maybe we're all just too accustomed to working with their widened primitive types instead of the singleton types), but having types like And cases like this would remain problematic:
unless they were typed explicitly as
And as a wild future idea, could we support |
@odersky what about the following: object Foo{
def main(args: Array[String]): Unit = {
val list = List(1.2, 92233720368547751L, 4)
val long = 92233720368547751L
println(list)
println(list(1))
println(list(1).getClass)
println(list(1).toLong)
println(long)
println(list(1).toLong == long)
}
} sbt: [info] Running Foo
List(1.2, 9.2233720368547744E16, 4.0)
9.2233720368547744E16
double
92233720368547744
92233720368547751
false (https://scastie.scala-lang.org/btdDoZBcRNqJRWm12VMXWA) Here, we have the same literal resulting in two different, unequal values, due to widening/conformance/whatever. There are no type annotations here, so I don't expect any implicits to kick in: if anything, I'd expect to get a Surely the same literal resulting in different values is a real problem, and that's not just pedantic busywork? I don't really care what the solution is, whether it's union types or intersection types or inferring |
Somebody would have to take this on. This means:
It's a big project. I don't see anybody in the core team having the stamina to do it. Until that changes or we have an outside contributor I will close the issue. |
Currently we're doing what scalac is doing WRT to this issue. Example:
from a user standpoint, this should in a stricter language have been inferred as
List[Int | Double]
. In scalac they have a flag for thisYwarn-numeric-widen
. Which is not yet implemented in Dotty.If we choose not to make inference for this type of construct stricter, then we should definitely implement the
Ywarn-numeric-widen
-flag.The text was updated successfully, but these errors were encountered: