-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
The issue with Value/Ref#== having a default implementation #10277
Comments
You can send a PR for the first option and see how it goes. Without trying this there's no way to weight this. |
I don't think option 1 makes any sense, honestly. While there are use cases for stricter and type-safe equality, I doubt it's the best choice for the omnipresent We should probably add something like Ruby's |
I just want to add that in some languages equality between different types is a compile error. Haskell is one such example. In C# I think they disallow comparing intw to strings, but then you can compare any reference type to any other reference type. I really commend someone to see if this is possible. I'm almost sure the friction will be too great, but at least we'll have these reasons documented. |
I can try it. I will try option 1 which is more interesting. Option 2 (which just adds a new method) could be done even now by anyone who reopens a few types and defines that method in there. They don't even need official help from the language. I agree with everything said about friction, breaking change, etc., but I think it would be quite strange if a type-safe language had to use a non-standard operator (i.e. something other than So option 1 is certainly worth trying, at least so that we know where we stand as Ary says. So my plan is, make
If you have better instructions than this, sure let me know. I already did some of this yesterday. Will update when there are news. Thanks. |
@docelic Did you get anywhere with your trials? |
Hey @straight-shoota , thanks for checking. I did some basic testing:
This revealed that the first/simplest cases where the fallback to default I took care of those two types of cases globally by defining a specific In src/time/location.cr:140:64
140 | if with_seconds == true || (seconds != 0 && with_seconds == :auto)
^
Error: no overload matches 'Bool#==' with type Symbol (In that example, From that I figured I couldn't go through code and replace all errors with My next attempt will be to leave the default/fallback |
But, apart from any further testing/investigation, a more interesting question is -- do you see any way in which this ticket could move or these are just last comments before closing it? From what I could tell, it is too late to change the behavior of Your thoughts/suggestions? |
At this point we're really just at an exploration stage. It's impossible to say how it might end up some day. #8893 is a very similar matter. It's a bit more advanced already and has shown that stricter type restrictions help identify (and subsequently avoid) bugs. We can probably get useful information from collecting statistics of |
Discussion about the same problem in Julia: JuliaLang/julia#40717 |
In the last ameba release there was added |
I realized that Crystal currently allows comparisons that always fail:
I asked on Crystal chat and @asterite and @straight-shoota report that comparing anything to anything (defaulting to returning
false
) was allowed because otherwise comparing union types would be problematic, and the language would be too rigid. Previous or similar tickets about this issue, which explain it, are #2996, #6154, and #8893. (And #1730 which asks about the same issue.)(For a very brief example, if such comparisons were prevented, they would have prevented some very reasonably-looking code from working, such as:
{1, "a", nil}.includes? 'x'
)In any case, the reason why these comparisons are allowed (and always returning false) is this fallback implementation of
#==
in typesValue
andReference
:This seems to me as undesirable because it (1) removes type safety from arguably the most basic operator in a language (
==
), and also it partially masksComparable
.I think that both arguments:
Are completely valid, and in fact they represent two different use cases which shouldn't be hidden behind a single
#==
operator.My suggestion is that we add a new operator which implements the other case.
Option 1:
The default implementation of
#==
is removed, so that the only working#==
comes fromComparable
or a specific implementation of#==
, and is type safe.Another operator (for example
==?
) is added which does what#==
currently does (returnsfalse
as a fallback).Option 2:
#==
is left as-is, and another operator is added, which enforces type checks.I think option 1 would be clean and consistent, certainly preferrable, and option 2 would maybe be easier/more viable, all things considered.
@straight-shoota mentioned that he was preparing an RFC about this issue.
@asterite said: "It would be nice if equality was type safe. Someone can try it and see how hard it is to make the std specs pass with that change, and how the code changes."
Comments welcome.
The text was updated successfully, but these errors were encountered: