SIP-67 - Improve strictEquality feature for better compatibility with existing code bases#97
SIP-67 - Improve strictEquality feature for better compatibility with existing code bases#97mberndt123 wants to merge 26 commits intoscala:mainfrom
Conversation
fix indentation
|
Thank you for the proposal. Here is the feedback from the SIP Committee:
|
|
Hey @soronpo, I'm sorry, I'm afraid I can't do that. Please consider the following enum: I'm going to contend that it shouldn't ever be allowed to compare two This is not a bug, this is a feature. Now you might say, OK, then maybe we can make the Alas, while this does prevent nonsensical comparisons with (insert sad trombone sound here) Now you might ask: How come it works just right for That seems like the sweet spot! The reason this works is that The conclusion from all of this is that it's impossible to make this work correctly by providing a magic |
I would not consider this to be a valid use of enum. Have you seen this type of code in the wild? |
Not sure offhand, but it seems like it would be unsurprising when constructing a DSL interpreter. (Where the enum is a kind of expression, and the leaf is an instantiation of one expression type.) The interpreter for my own QL language is still on Scala 2, but I could see myself trying to build it along those lines if it was Scala 3, so I don't think that's just a strawman. |
Still I'm not sure |
I have seen ADTs with functions inside |
From the Scala 3 book.
Personally I have almost exclusively written Scala 3 and would use enums for this kind of ADT (with a function). If that is not the correct way to do it, then the correct way must be elusive. |
|
Yeah, agreed. My understanding of the Saying that only some ADTs count, and other reasonably well-formed ones don't seems kind of un-Scala to me. A key element of Scala is that functions are values; intuitively, I would expect them to work here like any other value type. |
|
I have to agree with @jducoeur , what's the actual argument against functions in The GADT mention is not accidental, the main use case for that is encoding commands: enum Cmd[A] {
case Read() extends Cmd[String]
case Write extends Cmd[Unit]
}and command-like GADTs will often have functions in them to allow sequencing: enum Cmd[A] {
case Read() extends Cmd[String]
case Write extends Cmd[Unit]
case FlatMap[O, A](fa: Cmd[O], f: O => Cmd[A]) extends Cmd[A]
}I feel like the argument that |
|
Let me clarify. If you want function arguments that should not be part of the pattern match, then these should come as a second argument block of the case, IMO. enum Cmd[A]:
case Read() extends Cmd[String]
case Write extends Cmd[Unit]
case FlatMap[O, A](fa: Cmd[O])(val f: O => Cmd[A]) extends Cmd[A]If you want them to be part of the pattern match, you put them in the first block where they have same equality treatment like all the other arguments. |
|
I admit that I never played with strict equality, so this might not make much sense, but:
Do we need a Now, from what I can tell based on some quick tests, the compiler really wants a |
|
Hi @JD557,
Yes, I had this in mind and I was going to propose it – you beat me to it. It can't be done with just a magic I. e. Then all we would need is a magic |
First of all, I'd like to address the question of "in the wild" examples of functions within ADTs. This is definitely something that people do, e. g. I think this is perfectly good code. It should be possible to use |
|
I've pushed a new revision that is based on a minor change to |
I think the point is for equality. Pattern matching does not fall under this category beyond reachability concerns, IMO. |
|
But |
For the record, strict equality is applied to |
|
Aha, thanks @soronpo for the clarification. Yes, nobody knows what |
|
@mberndt123 Perhaps update the proposal to upfront clarify the scope of being |
|
Pattern matching uses locally {
val x: Any = 5L
println(x == 5) // true
println(x.equals(5)) // false
println(x match { // yes
case 5 => "yes"
case _ => "nope"
})
} |
Hi Björn, What @soronpo wrote there is not a clarification, it is his opinion, and it is in fact exactly where the controversy is. Currently, pattern matching against a constant (whether it's a literal or a case object or just a |
|
AHA!! Thanks also to @mberndt123 and @sjrd for yet more clarifications. Maybe it's just me who didn't get the actual controversy, but perhaps the intro to the SIP can be improved by referring to I think I'm leaning towards the stricter end of the design space of the future language - it is after all called strict equality. |
What I meant is that I think it should be equals and therefore not affected by strict equality |
|
It has had the semantics of IMO we should judge the present SIP with respect to the established semantics of pattern matching. |
I'm ok with keeping == and just inferring CanEqual under pattern matching, as I have already mentioned. |
|
This SIP was approved to move into the implementation stage. Congrats @mberndt123 ! |
I think this would help both the committee, and the users who want to try the changes out. Users especially have trouble reading and digesting spec-ese. It's useful not only to have examples of what the proposal does change, but what it doesn't. The full story of the proposal is: here's what already worked even before the proposal; here's examples that the proposal does fix; here's examples that don't work and it might be surprising but we're certain the behavior is correct; here's examples that don't work and we might have hoped to fix but it's out of scope for now but maybe a subsequent SIP could address it. I know that may sound like a lot, but I'm not imagining tons of examples, just key ones that would make the SIP clear to everyone. |
|
Thanks @soronpo and @SethTisue. I've added a handful of examples, I hope that clarifies things |
|
Please note that the SIP template has changed:
Thanks! |
|
New to this SIP. I always thought Scala would implement strict equality akin to Javascript, with a triple equals |
Such discussions would usually occur on https://contributors.scala-lang.org/ but I don't remember such discussion. |
Note that Strict equality is much further-reaching than that, though, intentionally -- it's not just opt-in on an ad hoc call-site basis, it prevents you from handling equality in an ad-hoc way, and enforces some discipline instead. (Still deciding how much I like it in practice, but I appreciate the principle.) |
Hi there,
I'd like to use the
strictEqualityfeature for the improved type safety it provides, but currently find it too inconvenient to use due to an unfortunate interaction with pattern matching. This SIP is my attempt to fix that.There have been no comments in the Pre-SIP thread for the past two weeks, and it's a very small (though impactful) change to the language, so I felt it was time to submit it.
Best regards
Matthias