You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Scalac and Dotty both implicitly convert from function literals to PartialFunction. For example, one can write:
valfoo:PartialFunction[Int, String] = x => x.toString
However this conversion is different in Dotty and Scalac. The compilers need to generate an implementation for def isDefinedAt(x: A): Boolean. Both compilers inspect the rhs of the function literal:
Dotty: if the rhs is a match, implements isDefinedAt in term of the cases, otherwise returns true
Scalac: if the rhs is a match, implements isDefinedAt in term of the cases, otherwise fails to compile
This leads to surprising behaviors:
vala:PartialFunction[Int, String] = x => x match { case1=> x.toString }
a.isDefinedAt(2) // Dotty: false, Scalac: falsevalb:PartialFunction[Int, String] = x => { x match { case1=> x.toString } }
b.isDefinedAt(2) // Dotty: true, Scalac: falsevalc:PartialFunction[Int, String] = x => { println("foo"); x match { case1=> x.toString } }
c.isDefinedAt(2) // Dotty: true// Scalac:// error: type mismatch;// found : Int => String// required: PartialFunction[Int,String]
I would argue that a function literal is a partial function that is always defined and both Dotty and Scalac are wrong.
Note: It works like this in Dotty because the compiler desugars partial function literals into function literals:
{ case1=> x.toString } // becomes x => x match { case 1 => x.toString }
Then when the compiler generates the isDefined method, it doesn't differentiate between a tree that was originally a partial function literal and one that was a function literal
The text was updated successfully, but these errors were encountered:
Dotty's clearly wrong (incompatible with Scalac) here, and in a way that could actually cause breakage for code that is pretty simple to write.
The 2.12 spec (Sec. 6.23) mandates that x => x match { … } can be treated as a partial function. Spec changes would have to go eventually through the usual review. I'd say Dotty-only spec. changes on small details are mostly technical debt — we should just fix Dotty now.
The situation for x => { x match { case 1 => x.toString } } is a bit fishier. Distinguishing between that and x => x match { case 1 => x.toString } seems clearly a bug — most phases should treat those trees as equal. The spec doesn't discuss this case, and I'll grant that's arguably a (minor) spec bug. But I think Scalac's precedent is enough to resolve doubts.
I see your logic; but both x => x match { case 1 => x.toString } and x => { x match { case 1 => x.toString } } are very similar to { case 1 => x.toString }, so I see why the spec makes sense, even though here Scala is trying to be a bit smarter, but in a pretty fragile way.
Overall, I guess we should just follow the spec and Scalac here.
As usual, I'm biased to make things compatible unless we actually have a rewrite, and we should only bother with rewrites for cleanups that exceed some threshold of "importance".
Scalac and Dotty both implicitly convert from function literals to
PartialFunction
. For example, one can write:However this conversion is different in Dotty and Scalac. The compilers need to generate an implementation for
def isDefinedAt(x: A): Boolean
. Both compilers inspect the rhs of the function literal:match
, implementsisDefinedAt
in term of thecase
s, otherwise returnstrue
match
, implementsisDefinedAt
in term of thecase
s, otherwise fails to compileThis leads to surprising behaviors:
I would argue that a function literal is a partial function that is always defined and both Dotty and Scalac are wrong.
Note: It works like this in Dotty because the compiler desugars partial function literals into function literals:
Then when the compiler generates the
isDefined
method, it doesn't differentiate between a tree that was originally a partial function literal and one that was a function literalThe text was updated successfully, but these errors were encountered: