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
String has no operator< etc #15693
Comments
Added Area-Library, Triaged labels. |
cc @sgjesse. |
We haven't yet found enough use-cases where string-comparisons with '<' are useful and work internationally. Most of the time it is a sign that the code is doing something wrong. We provide a compareTo operator, since some data-structures need to sort their elements. These data-structures usually don't care for the actual order, as long as the elements have a specific deterministic order. The String.compareTo works for this use-case. Some clases, like DateTime, provide compareTo, but cannot provide the operators <, >, <=, >=, that are consistent with compareTo. This is, because compareTo only looks at the absolute time-value (is the dateTime before/after the other dateTime), but "==" looks at the attached timezone too. '<=' would need to be consistent with compareTo (for the "<" part), and at the same time with "==", which is unfortunately not possible. |
There is the use case caused by Dart not having character code literals: Programmers are likely to want to compare single characters, so they write something like: |
thanks for the explanations, florian. i had a rather long discussion with justin f. the dart contracts seem to be (2) seems to be the thing causing the desire to make DateTime's == disagree with that induced by compareTo. as far as i can tell, java does not require (2):
so the right argument for String and DateTime not having < isn't "we can't", but "we don't want to". ok, that was a lot of babbling. here's my proposal. on the other hand, if you dart guys are willing to live with a homomorphism that is not an isomorphism, anyway, let us know if you guys can choose a contract and update the docs. it would be helpful. thanks! |
We don't require (2) either (although it generally is the expected behavior). I agree with a-e. Doubles are an exception, but that's because IEEE forces it on us. Note that Strings do not fall into the same category as DateTime. Strings could have a-e work, but the main-reason we don't add it, is because comparing strings without locale frequently is an error. Maybe you have a really good use-case for adding the comparison operators, and we will have to revisit our decision. TL;DR: we (and in particular I) don't want to add comparison operators to Strings, because they give the impression that their comparison operator sorts them alphabetically. |
florian, that's fine to not change any implementation. but can we get docs on Comparable explaining the intended/recommended contracts so that all this reasoning is more public? e.g. before this thread, it wasn't obvious to me that for some classes, compareTo and == intentionally disagreed, nor that it should explain the lack of implementing <, <=, etc. |
I have updated the documentation of Comparable (on bleeding edge). |
thanks a bunch. i think there are a few typos: |
Thanks for the proof-reading :) I agree that the description can probably be reduced significantly. This gist is supposed to be: The < operator family should be compatible with the == operator, and they should be used only for less-than/greater-than relations. (This is unrelated to Comparable, but there is no better place to write it). By a "less-than/greater-than" ordering, I mean an ordering that you would naturally use the words "less than" about. Numbers are the natural example. Temperatures would be another example (they are just a single number too, just with a meaning). Wrt. total/partial ordering; The compareTo method must be total (it's only allowed to return negative, zero or positive, there is no fourth option). If it isn't total, sorting and SplayTreeMap will break. Well, technically, all functions are total on their domain, so you just have to make sure that the compareTo method doesn't get values outside of the domain where it works - i.e., it must always be used in a setting where it is total. The < operator should preferably be total too, but if it isn't (with some good reason), probably nothing breaks. It's just a case of a<=b and b<=a both being false (NaN is the classical example). It's still annoying since if a<b, a==b and a>b are all false, then the equality (b<=a) == !(a<b) doesn't hold. |
thanks for the explanation. still, you may want to back off from the "less-than/greater-than" concept. how about this? (1) If any of <, <=, ==, >=, > are defined, they should be consistent with each other. Examples |
This comment was originally written by @tatumizer We discussed it at length in some earlier threads, and I still think current way of defining == for DateTime is the worst out of all possibilities. Among other things, it leads to Map based on DateTime as key to be inconsistent with TreeMap (the latter requires compareTo to be in sync with ==). |
We don't expect to add (And I still think we should have character code literals). |
to reproduce:
'foo' > 'bar' yields
"Unhandled exception: Class 'String' has no instance method '>'."
that sucks. so we need 'foo'.compareTo('bar') > 0, which looks horrible.
javascript and python let us compare strings with <, >, <=, etc.
dart lets us compare numbers (1 < 2). why not strings?
Comparables should get <, >, <=, etc defined for free.
here is one possible implementation: if a class implements Comparable
and a relational operator is not explicitly overridden, let it just
delegate to compareTo. who would complain about such a feature?
Dart VM version: 1.0.2.1_r30821 (Tue Dec 3 12:51:29 2013) on "linux_x64"
The text was updated successfully, but these errors were encountered: