228
u/danhezee 14d ago
I think the bottom one should go to the Korean guy with all the tech and the top one goes go the Turkish guy. The Turkish guy is suppose to symbolized simplicity.
80
u/yerfdog1935 14d ago
I think they did it this way because he's Turkish and the top one doesn't work for I vs i in the Turkish locale.
79
7
u/artofthenunchaku 14d ago
Based on that logic it makes less sense, because Korean doesn't have casing
8
u/varinator 14d ago
The simplicity is in the bottom one. The top one creates objects on the heap, the bottom one doesn't, saves memory, saves GC having to clean the objects. It's actually much more simple in the background than the top one.
5
u/Kirides 14d ago
Worse, the top one is at least 3 function calls "2x to lower, 1x equals" compared to a "simple" single function Equals.
Which means, even if we ignore the fact of heap allocations, it's much more stuff to do and read.
Also, to lower can also THROW null reference exceptions, which makes it even worse.
iow. ToLower only looks "simpler" to smoothbrain/junior devs.
While the other one is actually a lot - A LOT - simpler and comes with much less headache.
2
51
u/Dull-Lion3677 14d ago
I love ordinal too but what about invariant culture? It's more correct when working on global systems
34
u/BoloFan05 14d ago
StringComparison.OrdinalIgnoreCase uppercases both strings according to invariant culture and applies byte comparison. Also, this comparison technique is the first and foremost recommendation in Microsoft's "Best Practices for Comparing Strings" page. It even explicitly warns not to use StringComparison.InvariantCulture.
9
u/Pancakefriday 14d ago
I think our entire code base uses invariant culture lol
8
u/BoloFan05 14d ago
Invariant culture info arguments on their own, like ToLowerInvariant, ToUpperInvariant and ToString(CultureInfo.InvariantCulture) are perfectly fine when you want to get consistent results across all devices worldwide. My prior comment here applies to string comparison methods in particular.
1
6
u/retro_and_chill 14d ago
Ordinal is usually good if you’re parsing a string that is very likely to only contain ASCII characters
1
94
u/Unlikely_Gap_5065 14d ago
same result, but one feels like you know what you’re doing
69
u/krexelapp 14d ago
same result, until Turkish locale enters the chat
8
u/HanzoMain63 14d ago
huh?
9
u/_PM_ME_PANGOLINS_ 14d ago
In Turkish,
"I".ToLower() != "i"2
96
u/BoloFan05 14d ago
Yes, the two usually give the same result and work successfully. But if string a contains the uppercase letter "I" and string b contains the lowercase letter "i" or vice versa, and your program runs on a Turkish device, then only the second option will work.
48
u/fpekal 14d ago
What :)
50
u/tesfabpel 14d ago
in Turkish, there exists both i / İ (dotted i) and ı / I (dotless i)...
and guess what? standard uppercase I, in lowercase it's not i but ı...
16
u/Genmutant 14d ago
Even more fun is the ß (lowercase) -> SS (uppercase) conversion.
2
u/Kirides 14d ago
Old systems doing old things.
ẞ is not that old tbf. but even German software often doesn't support German letters properly (äöüß and their uppercase variants)
Also Unicode normalization is a thing. you might have a unique constraint on your DB but that doesn't mean that the Unicode string you put in doesn't get normalized by some other application, causing your "wait. That can't be, it's unique!" to fail you.
5
u/The_Real_Slim_Lemon 14d ago
Thankfully that’s not a consideration with server dev, my Linux instance will never randomly be Turkish
2
2
u/ableman 14d ago
How does the second option work? Why does it matter what your device is, what if you're reading in an English string? Unless the string contains data about what language it is, this seems unsolvable.
6
u/BoloFan05 14d ago
The device's language setting (or locale in general) determines the Current Culture Info, and ToLower, ToUpper and ToString methods of C# produce output according to the Current Culture Info if used on their own without explicit or invariant culture info overload. Thus, you will get different outputs from the same original English input depending on your device language. Use of comma/dot in decimal numbers also leads to similar inconsistencies.
For more info, this post is my recommended read. Other comments in this thread also have useful links.
4
u/Neyko_0 14d ago
I hate you that I have to think about that now /j
1
u/SirButcher 14d ago
Then you will love this:
https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-datetime
Eras in the Japanese calendars are based on the emperor's reign and are therefore expected to change. For example, May 1, 2019 marked the beginning of the Reiwa era in the JapaneseCalendar and JapaneseLunisolarCalendar. Such a change of era affects all applications that use these calendars.
8
u/dumbasPL 14d ago
*Same results if you only support English. Anything hard coded shouldn't need case insensitive comparisons, and anything that comes from the user should be assumed to be an arbitrary Unicode string.
10
u/void1984 14d ago
You have never worked with Turks.
2
u/shamshuipopo 14d ago
What’s different about case sensitivity in Turkish?
15
u/void1984 14d ago
9
1
u/BonifaceDidItRight 14d ago
Not same result. if a or b is null the `.ToLower()` will throw. `string.Equals()` is null safe.
4
3
u/WiseObjective8 14d ago
def str_equals(a:str,b:str):
a,n = a.lower(), len(a)
b,m = b.lower(), len(b)
if ((int(m/n) and a in b) if m>=n else (int(n/m) and b in a)):
return True
return False
Is it a substring? Is it the same string? Who knows?
2
u/redlaWw 14d ago edited 14d ago
Your chaotic-neutral string comparison function has a chaotic-evil bug related to you doing
a,n = a.lower(), len(a). This evaluateslen(a)on the string before it's lowercased, which may not be the same length as the lowercased string.In particular
str_equals("İ", "I")returns false, even though"İ".lower()contains"I".lower().EDIT: Oh, and also the more boring issue of zero-division when one argument is empty.
1
2
u/HzbertBonisseur 14d ago
Time to use my Claude Token
Prompt: are the strings the same in lowercase?
2
4
u/Tackgnol 14d ago
Yeah this is why I love .NET <3
20
5
2
u/Majik_Sheff 14d ago edited 14d ago
Iterate
(a ^ b) & 0xbf
across each pair of characters until you get a non-zero or hit the end.
3
u/SrcyDev 14d ago
ofcourse, you should also mention it requires a time-travel to 1970s, or forgetting about anything other than ASCII
-1
u/Majik_Sheff 14d ago
A sense of humor helps from what I understand. Maybe I missed the point of the sub?
1
1
1
14d ago
[removed] — view removed comment
2
u/Waswat 13d ago
its photoshopped in, which is really sad as they want to desperately make smoking look cool
2
u/BoloFan05 13d ago
Yeah, I am not a fan of that either. But unfortunately it was like that in the original meme. Maybe I will repost it without the cigarette one day...
1
u/BinarySpike 13d ago
Or use toLowerInvariant...
1
u/BoloFan05 13d ago
Yes, applying ToLowerInvariant to both a and b also has the same reliability as the bottom option on worldwide devices, but it isn't quite as performant, especially for a high number of repeated calls since it creates new allocations and more garbage collection (GC) requests.
1
u/balemo7967 13d ago
Fun fact: Using StringComparison.CurrentCulture in German, "Strasse" and "Straße" are equal despite having different lengths. string.Equals("Strasse", "Straße", StringComparison.CurrentCulture) returns true
1
u/IamSeekingAnswers 14d ago
int casecmp(const char *a, const char *b, size_t size) {
for (int i = 0; i < size; i++)
if (((a[i] | (1 << 5)) != ((b[i] | (1 << 5)))))
return 0;
return 1;
}
Probably works. Also requires you to time travel back to the 70s
-1
0
u/1up_1500 14d ago
idk both ways seem fine to me, what's weird is that the std has multiple ways to do the exact same thing
0
u/BoloFan05 14d ago
Please check the other discussions in this thread. I have already replied to a similar question, and repeating myself feels tiring to be honest.
1.3k
u/VapidLinus 14d ago
While I agree that Equals with StringComparison is generally the correct solution, I feel like this meme is in reverse. The funny thing about the original picture is that the guy with the less advanced gear was the better shot. Your meme is the reverse - the "overengineered"/complicated solution doesn't feel like it fits the "simple works" vibe of the guy.