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 31 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 |
|
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.) |
e23b4e9 to
8216075
Compare
|
Hi there, I've updated this SIP to incorporate feedback that I've gathered. I’d appreciate it if the committee could take another look! |
|
@soronpo @Gedochao it's a bit unfortunate that we skipped a SIP meeting or two, as this could very likely have been approved by the committee in time for 3.9.0-RC1 but since the user feedback has been uniformly positive, and since it only affects an experimental feature, perhaps it's actually not too late for 3.9? |
You mean approve the update as experimental? I don't think we need even a meeting for that since changes being made are an inherent part of the experimental phase. However, we cannot promote it to a stable feature before 3.10. |
right, agreed, we're just trying to see if scala/scala3#25850 can make 3.9 sorry, I should have been clearer |
|
Core agreed today that the implementation can land in 3.9, assuming no new doubts arise at the April 24 SIP meeting. Reasoning: the feature is experimental anyway, and the implementation changes don't appear risky. |
|
Great news @mberndt123 ! |
|
@mberndt123 One minor thing: In example 1 there is reference to a "compiler bug" -- for the record and for later reading when this is merged it would be good if you could insert a link to an actual issue on the compiler so it will be easy to eventually see when it is fixed for the ones landing on the sip text in any kind of future... (res0 should be 1...) |
|
...and many thanks for your thorough investigations and well-written SIP :) @mberndt123 |
|
@bjornregnell |
…25850) Hi, after collecting feedback for strictEqualityPatternMatching ([SIP-67](scala/improvement-proposals#97)), I've come to the conclusion that only enabling this behaviour for `case object`s isn't useful and it's better to enable it for all `object`s. Declaring ADTs without the `case` modifier for the relevant objects isn't that uncommon and there's no reason to not have it work in that case, too. I've amended SIP-67 accordingly and I hope the SIP committee will approve the change soon.
…cala#25850) Hi, after collecting feedback for strictEqualityPatternMatching ([SIP-67](scala/improvement-proposals#97)), I've come to the conclusion that only enabling this behaviour for `case object`s isn't useful and it's better to enable it for all `object`s. Declaring ADTs without the `case` modifier for the relevant objects isn't that uncommon and there's no reason to not have it work in that case, too. I've amended SIP-67 accordingly and I hope the SIP committee will approve the change soon.
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