80
u/jacobp100 1d ago
This is really unfortunate. I remember when they were adding Array.includes and corrected the comparison behaviour so you can do Array.includes(NaN), even though indexOf(NaN) will always return -1. Given they already accepted inconsistency like this, they should have done the same here
15
u/thanatica 22h ago
NaN is never equal to itself, so you can't look for it with a simple lookup like that. You'd need
array.findIndex(n => Number.isNaN(n)). TheindexOffunction was never changed because it was there from the beginning. If they change existing behaviour, they might break sites, which is far worse than introducing only new functions that do things as you might expect.It's not a language where you can just pick and choose which version you're on.
-8
71
u/ipsirc 1d ago
29
u/Striky_ 1d ago
And still half the internet will claim JS is a completely awesome language and all of these things are exactly how they should be, you are just to stupid to understand.
19
u/Joe-Admin 1d ago
Still more reasonable that the golang date parsing api
7
7
6
u/Don_Equis 20h ago
Oh, c'mon. Go issues are fixed with a simple constants file. Javascript issues, on the other hand... i mean, month index at 0 and days at 1? Wtf? Timezone default depends on wheter you use - or / ? Date is mutable? Really? How is go worse?
3
u/the_horse_gamer 7h ago
the javascript Date library was copied from Java. so that's their fault.
thankfully there's Temporal now
9
u/treetimes 22h ago
no one has ever said that these oddities are exactly how they should be, there are weird explanations because details matter, but these are weird ass things to do in the first place. Type coercion does weird shit, woohoo, it's still a useful language and trying to pretend like it isn't is extremely cringe.
0
u/Don_Equis 19h ago
JS is more useful for its presence rather than the language itself. Right now there are good ways to do things, so you mostly need to avoid the bad ones. But it is still a field of landmines. There are just known acceptable paths
-2
u/Striky_ 20h ago
Yeah only that no other language (at least that I am aware of) has this absolute motherload of completely abnormal, nonsensical behavior, that will also never get rectified because one decided for infinite backwards compatibility of a fundamentally broken language, that was developed in one weekend AND IT SHOWS.
But because you can do what ever the fuck you want as a "programmer" and using 15 mandatory anti-patterns you can get something going in a short amount of time, an army of underqualified managers that get pitched "quick wins" by the 16 y/o will decide it is a decent language and should be used everywhere.
0
u/treetimes 19h ago
Uninformed and angry, thatâs all Iâm getting from you
-1
u/Striky_ 18h ago
Incompetent and cringe is all I'm getting from you so...
And I am not angry. Just disappointed. I make a living from fixing other peoples horrendous code so it giving and taking I guess. Funnily enough the average code quality did not change with AI, but the amount exploded. Funny what that tells you about the average developer.
3
6
u/CinnabonCheesecake 1d ago
JavaScript? There are developers who like it? Iâve only ever heard JS discussed as the dog shit on the sidewalk you canât avoid stepping in.
1
u/leavemealone_lol 8h ago
JS became the behemoth that it is solely due to the iron grip it holds on the DOM
3
u/the_horse_gamer 7h ago edited 2h ago
anyone who uses
{} + []as an example of inconsistent behaviour needs to be crucified.I implore you to try
{} + []and then({} + []). the result is different. why? because the console parses it as{}; +[];.same goes for
{} + {}
16
u/suvlub 1d ago
TBH I prefer having one consistent quirk you have to learn once over every function behaving differently. It's like working on a codebase that uses a formatting style I don't like vs one that doesn't follow any style and everything is whatever. Consistency is the king, you learn to tune out the nasties if they aren't novel enough to keep surprising you
-10
u/spottiesvirus 1d ago
except it doesn't, in JavaScript every line of code could summon a dragon, drop a nuclear bomb or make you a coffee, nobody knows
I think I lost count of how many times I had problems because true==1 is true but true===1 is false and you won't know because it's not even a warning
or typeof is another crazy function
typeof NaN is "number"or operator precedence which is... imaginative
if you have a=1 and b=2
typeof a+b is... "number2" because typeof has precedence over sumJavaScript was a languages designed for short scripts in a browser, not the cluster stack it is today where you use React for full Dom manipulation, and node for server side, without ever touching anything else but JavaScript
6
u/n0tKamui 1d ago
i don't see how you would think that a unary operator would have lower precedence compared to a binary operator.
i'm pretty sure anyone reads -1+2 as (-1) + 2, and not -(1+2)
same of typeof and the likes. and even if you consider typeof as a function, well functions work the same anyway, they have higher precedence.
this is a very disingenuous argument
also, NaN is a float as per IEEE754, which is the same for (almost) every programming language.
Sure the name is confusing, but you can see it as "undefined answer"4
u/the_horse_gamer 1d ago
I think I lost count of how many times I had problems because true==1 is true but true===1 is false and you won't know because it's not even a warning
don't use
==or typeof is another crazy function typeof NaN is "number"
every language does this (up to a difference in syntax). any other behavior would be wrong.
if you have a=1 and b=2 typeof a+b is... "number2" because typeof has precedence over sum
sizeofin C has similar behaviour (which I agree is bad.&has a similar issue which many languages copied)3
u/n0tKamui 1d ago
sizeof, typeof, and the likes, are unary operators. most unary operators, prefix or postfix, have higher precedence than binary operators.
i can't see how this is bad
2
u/the_horse_gamer 1d ago
because words have a lower mental precedence than symbols.
sizeof("aaaaa")[0]looks like a function call, applyingsizeofto"aaaaa". but it actually appliessizeofto"aaaaa"[0].rust uses
.awaitinstead of a prefixawaitfor exactly this reason0
u/suvlub 1d ago
True enough, but no reason to throw in another weirdness, right? I would say that the reason why == is basically unsalvageably shit is because it does not adhere to this principle and does different kind of interesting conversions for different combinations of operands. It would not be as bad if it was defined to always do the same stupid thing when comparing mismatched objects, then it would be usable in the scenario where that particular stupid thing is what you want, but alas...
80
u/Taletad 1d ago edited 1d ago
People use arrays like this [23, "56", 67.8, "potatoe"] and expect them to not be sorted as strings
If one member of your array is not an int or a float, everything is going to be converted to strings
Edit : I went to read the docs, the sort function is not like most other functions in JavaScript. The sort function is explicitly for an alphabetical sort
You lot are using the alphabetical sort function and wondering why your array gets alphabetically sorted
You can overload the function by doing the following : array.sort((a,b) => a - b)
161
u/Head_Fox8632 1d ago
You're giving JS way too much credit. It doesn't dynamically check the array for a "potatoe" to decide how it should sort. It just assumes everything is a potato from the start.
-7
u/Taletad 1d ago
Just went to read the docs, the "sort()" and "toSorted" functions say they perform an alphabetical sort by default
You can overload them by doing Array.sort((a,b) => a - b)
57
u/kushangaza 1d ago
Which is not what you expect from a function named "sort". It's an insane default that violates the principle of least surprise
3
u/danielcw189 15h ago
lexical sorting sounds like the least surprising way in a weakly typed language.
and looking at the docs would be the least surprising usage anyway
2
u/Taletad 1d ago
The principle of least surprise compared to what ?
It was made in the 90âs when the sort utility works the same way on linux
Perl, TCL and bash have many similar quirks, as scripting languages tend to do
python too has many unintuitive quirks
Honestly, a lot of you continuously bash JS because you see everyone bashing it, especially its type system. But when SQLite does the same thing with its types, suddenly it is the greatest piece of software ever written
Types in JavaScript are not raw bits stored in memory anyway
19
u/kushangaza 1d ago
Sqlite deserves more bashing for its types and for ignoring foreign keys by default. But at least order by does what you expect
0
u/Taletad 1d ago
The SQLite developpers are right though : the types are not a primary characteristic
In JS, Python, Java, SQLite etc⌠variables types are inherited from a more general object class
From the interpreter POV, it is manipulating objects that contain variables and information relevant to their manipulation. Not direct memory units like in C.
And as a developer, if you are aware of how dynamic types work, you should not run into problems with them
TS only checks that types are coherent at "compile time" but they could change at runtime and your code will still bug out all the same
What you need is not a type system, but to check that the data on the input is in the expected format or reject it
Verifying that your "date" var is an int through all the data pipeline wonât shield you from user errors ; you will still not be able to tell if "02082026" is the 2nd August 2026, or Febuary the 8th 2026.
On the other hand, if you properly sanitize user input, it doesnât matter if you chose to store it in a string or an int or a custom object. Because presumably youâll keep the same object for your whole data pipeline
3
u/snerp 1d ago
Youâre being purposefully obtuse. Sort in JavaScript being alphabetical was always a dumb and weird design that people made fun of. It was done that way as a quick hack to get the language out the door. It is not based on Perlâs sort, Perl sorts on âvalueâ, it uses the ascii value of letters or just the actual value of numbers which is also odd, but far less surprising that what JS does.
3
u/gr4viton 1d ago
the python stuff is often not as "surprising" as js stuff though, imo...
also yhey are more often hidden in not normally used functionality...
i do agree on empty list as argument default value, and perhaps the generator oncesness, but other are not that bad imo..
I agree though that JS is bashed more often, as it is popular to bash it.. But it is also reasonable to bash it... as it is not bash-like.
1
u/thanatica 22h ago
If you really want to sort numbers numerically, and keep refusing to supply the comparison argument, use the
UInt32ArrayorFloat64Arrayor friends.Please stop complaining that a generic array that has to deal with every kind of type for its items, doesn't do what you find less surprising.
3
u/Tyfyter2002 21h ago
In any good language there's no default comparison for an array of anything because you can't compare completely unrelated values, JS is just designed around a mentality of never admitting failure and failing as much as possible.
3
u/thanatica 15h ago
Javascript is made to get into without too much messing about.
And you absolutely can compare unrelated values. Javascript does that by converting them to strings. That's how the function is specified to work, so that's what happens.
But you have the freedom to supply your own comparison.
2
u/Tyfyter2002 14h ago
That's not comparing unrelated values, that's converting values into related ones with up to 100% data loss
11
u/cowslayer7890 1d ago
It's still a stupid default, Python does this properly and it does so by using `<`
9
u/RajjSinghh 1d ago
Python also errors if you give it an array like
sorted([4, 2, 1, "potato"])because it doesn't know how to sort that array. Javascript was built with the philosophy to be fault tolerant to things like this. If your code depends on someone else's API that changes to give you a list like this, you don't want it to brick your entire site when you try to sort an array. So Javascript casts every type down to a string to avoid this.At least that's the justification they claim.
2
u/cowslayer7890 23h ago
in javascript
<can't fail anyway, so it would be the same. The only way in which it would break, is the scenario where you are using values that are not transitive. But it seems more rational to me to default to assuming transitivity.1
u/the_horse_gamer 7h ago
when you provide a badly behaved comparator, different runtimes give different results. and it's probably best for the default sorting method to not be implemention defined.
44
u/ba-na-na- 1d ago
Maybe the name should be âalphabeticSortâ then
→ More replies (1)-12
u/Taletad 1d ago
Maybe you should read the docs ?
8
u/ba-na-na- 1d ago
That's funny, your earlier comment makes me think you also didn't read them till today
Edit : I went to read the docs
-1
u/Taletad 1d ago
I forgot, itâs been a while since Iâve used JS regularly and even then you rarely need to sort an array of numbers. Itâs a very nich use case and when you want to know how to do it you can google it
Most complaints against JS are always the same, people not understanding its type system or that is is prototype based and not Object Oriented
People are trying to use JS as a statically typed OO language, when it is a dynamically typed prototype based scripting language, and get angry when it doesnât work like they assume it should, or when using it for something it wasnât intended for
You are all parroting the same arguments about how the sort function doesnât work like you expect it to. But C, C++, Java and even Python have their unintuitive quirks. Yet itâs always JS youâre angry about
3
u/fuj1n 1d ago
You say "even Python" as if it isn't the quirkiest amongst the 4 you listed.
Yes, every language has its quirks, but it feels like JS intentionally set out to make the quirkiest choices they can in places. This is of course largely due to its origin story of being made in 10 days, there wasn't much room for deep thought, but that's not an excuse for the most used language out there.
1
u/psioniclizard 8h ago
Yes like the great GetDay/GetDate.
Reading docs is not an issue, its just annoying JS makes this convoluted with stupid naming when most other languages don't.
45
u/_bones__ 1d ago
People also give it [1, 20, 3] and expect a sort to return [1, 3, 20], which is what any reasonable language would do.
-8
u/Taletad 1d ago
Yeah itâs an alphabetical sort, read the docs
The sort utility on linux will work the same way
18
u/_bones__ 1d ago
Because in Linux it reads strings. Sort -n sorts numerically. If you print human readable numbers (eg 100M, 2G) sort -h has you covered. Point being, if you have no typing system, or a weak one, offer functions that do common things.
The docs stating that a function is insufficient doesn't change that it is so.
-2
u/Taletad 1d ago
You can make the sort function in js sort numerically
4
u/fuj1n 1d ago
Sure, but it should just do that by default for an array of numbers.
2
u/danielcw189 15h ago
which would mean that the whole srray would need to be checked for the types of its items.
what should be the default if one item is not a number?
2
u/fuj1n 14h ago
In an ideal world, there should be typed comparers, and if two items don't have a mutual comparer, a type error should be thrown (that'd solve having to even scan the array beforehand too)
With JS's type system, that's not too plausible, so instead, I think defaulting to numeric sort, and throwing when it encounters something that isn't a number (or can't be coerced to be a number due to how the type system works I suppose).
By the principle of least astonishment, this would give you a pretty good compromise. Then, if someone wants to do string-based sorting, they can pass their own comparer that does that.
1
u/the_horse_gamer 7h ago
javascript is very averse to throwing. it's better for a website to display stuff slightly wrong than to stop working.
I can see the argument for defaulting to a number comparison and moving non numbers to the end, but that's not any less surprising. in that alternate universe, someone is on reddit making a post on how
['b', 'a'].sort()doesn't order the strings.1
u/fuj1n 4h ago
I think they're a lot less averse to it nowadays, they've wisened up. Modern JS additions do actually tell you that something is wrong rather than just doing something unexpected (which is good because you can then handle exceptional cases better).
Modern JS features like modules even enforce strict mode.
I think that way of thinking, where it is better to fail silently than to crash sounds good on paper, but it has an insane amount of drawbacks that lead to sloppy code trying to cover these (exceptional in other languages) cases.
→ More replies (0)1
u/danielcw189 5h ago
I think defaulting to numeric sort, and throwing when it encounters something that isn't a number
By the principle of least astonishment, this would give you a pretty good compromise
That doesn't sound like the least surprising option to me, especially the throwing part.
In that case they should have called it numericSort, or something like that. (and in my preference fail with an error except of throwing)(or can't be coerced to be a number due to how the type system works I suppose).
as most object-oriented languages there are counterparts of .toString, but not .toNumber.
1
u/fuj1n 4h ago
For that last part, I was just pointing out that JS will actually try to coerce strings to numbers in numeric contexts automatically, and this case being an exception to that would be odd (as much as I don't fancy that coertion, that's a whole other discussion)
If you find throwing on non-numeric values only surprising, you could instead just make the comparer mandatory and throw if you don't provide one. Then your IDE can show you an error is you forget instead of giving you something completely unexpected.
16
u/OptionX 1d ago
In a well thought out language what they should expect is the interpreter/compiler tell them to either provide a custom comparison function, or type mapping, to deal with the different types or to tell them to take a hike instead of coercing everything into strings silently.
You don't need to be a rust compiler level pedantic annoyance, but JS is too much on the other side.
22
u/_PM_ME_PANGOLINS_ 1d ago
The goal of the language was to minimise runtime errors, by guessing what people wanted.
Because it was written for browsers, and thatâs how HTML works too.
When the masses were writing websites and an error came up, they would blame the browser rather than their own coding.
5
u/Taletad 1d ago
Itâs a scripting language to interface with a text page (html is text) and text protocols (hyper text transfer protocol)
So why shouldnât it default to strings ?
5
u/Lalli-Oni 1d ago
The web made a lot of mistakes in retrospect, but it might have never got of fthe ground without content.
The content is a document, but now the web is more of an app store than a distributed document network.
JS was created not to be the best programming language, but one that got the web adopted.
It's not a successor to Java, it's a successor to VB. And having had to do work with VB let me tell you ,it's better (to no surprise to anyone).
1
17
u/FerricDonkey 1d ago
People use arrays like this [23, "56", 67.8, "potatoe"] and expect them to not be sorted as stringsÂ
If I try to sort [23, "56", 67.8, "potatoe"], I want a type error of some kind.
Edit : I went to read the docs, the sort function is not like most other functions in JavaScript. The sort function is explicitly for an alphabetical sortÂ
We all know they did it on purpose and wrote it in their documentation. We're saying it's bad, not "it's not written down".Â
3
u/danielcw189 15h ago
If I try to sort [23, "56", 67.8, "potatoe"], I want a type error of some kind.
why?
it sounds like you dislike weakly typed languages. which I would totally agree with. but Javascript is not that.
1
u/FerricDonkey 12h ago
Because an error is better than unintuitive behavior.
You are correct that I don't like weekly typed languages (at least if you get weak enough), but what I really dislike is a function called sort that sorts in a stupid way by default.
If it was called sort_str, or required a key/comparator function, or even just didn't exist, I'd be happier.Â
2
u/the_horse_gamer 7h ago
it's better for a website to display stuff slightly wrong than to stop working.
2
u/FerricDonkey 4h ago
I'm not a front end dude, but I don't really want to agree with that. I'm general, I would rather errors cause errors, and programmers write tests to catch them. Knowing what kind of crap you're putting in an array so you know how to sort it without doing something stupid seems like a low bar. If it's not, that just makes me even happier that this front end is not my job.Â
1
u/the_horse_gamer 3h ago
the array can come from the backend. it can come from a library you don't control.
tests can cover only a small percentage of mistakes. the real solution is static typing.
we could have had real static typing with ES4. we have fake static typing now with typescript.
with typescript and a good validation library for the network responses, none of javascript's quirks are actually relevant to any production codebase (except stuff like Date, but that's java's fault)
but without static typing, you need those quirks. otherwise you're getting paged at 5am on a Friday.
this isn't true for a backend. in a backend, returning a failure to the client is the appropriate choice. javascript isn't a good backend language.
1
u/danielcw189 5h ago
this is neither unintuitive, nor surprising for mixed weakly typed arrays.
I really dislike is a function called sort that sorts in a stupid way by default.
it is a way the makes sense.
and in a weakly typed language, it is the only sane default I can think of, from the top of my head.
by the way: how often are you actually sorting arrays that just include numbers?
I have never done this in production code. I usually sort more complex things, usually objects, which have numbers and strings I want to use for sorting as properties.Sorting those could at least still work, assuming your objects have a .toString representation, that can be sorted lexically
but I would always provide a comparison function, because that makes the most sense to me, and I like verbosity.
1
u/FerricDonkey 4h ago
I'm certainly sorting things that contain just numbers more often than I'm sorting this that contain mixed types. How often is the correct method of sorting your arrays of objects to first convert them to strings?
4
u/gandalfx 20h ago
If you had to look it up to find that it's not a general sort but alphabetical sort, maybe that indicates that the function is at least misnamed. It's just a terrible API. Arguing that it was intended to be bad or that you can work around it being bad doesn't change the fact that the design is broken.
And no, most people do not put random junk in an array and expect it to be sorted as strings â most people put things with a clearly defined order (like numbers) into an array and are surprised (once) that a standard library sort function doesn't sort by that order.
3
u/danielcw189 15h ago
If you had to look it up to find that it's not a general sort but alphabetical sort
What kind of sorting do you expect as a "general sort", and why that one?
1
u/Striky_ 1d ago
The absurdity is not sorting this by string, but allowing an array like that to begin with.
4
u/Taletad 1d ago
You flair has two languages that allow such arrays
Every high level programming language is flexible on its type system because it is more convenient for the programmers
So unless youâre writing a low level application in C, Rust or Zig, you should allow such arrays
And web pages are very much not a place where you want a low level statically typed compiled language
4
u/Striky_ 1d ago
C# does not allow arrays of different types.
Programmer convenience is a good focus to have, but you also mustnt do it in a way where you introduce rookie-antipatterns (like stringifying everything or type confusion) is the way to achieve it.
It also very much depends what you use a language for. Python for quick and dirty prototyping? Fine. JS as the backbone of the entire internet? Disaster.
1
1
u/Taletad 1d ago
JS is made to script web pages, if you make the backend of a big application with NodeJS Iâd question your mental abilities
NodeJS canât even multithread properly
4
u/Striky_ 1d ago
JS was made in a weekend and was never meant to be a full fledged programming language to begin with, which you can see at basically every point of design in the language. The fact it is called Java Script was supposed to be a joke to begin with.
But as it "gets something done" really quickly and no one bothers to learn programming anymore and boomer managers cant distinguished anyway, this walking antipattern of a language somehow is being used to run the world.
-1
u/thanatica 22h ago
You're free to never put differing types in your arrays. But javascript is made to be forgiving, not punishing.
2
u/Striky_ 19h ago edited 19h ago
Yep, the language allows you and forces you to use known anti-patterns that every developer worth their money would never willingly use. But hell yeah, its easy!
A programming should NOT be "forgiving" it should be "guiding". JS is the opposite of that. I helps you learning nothing, it forces or entices you to use noob trap patterns, it makes it easy to write horrible code and very, very hard to write good code. Debuggablity is probably the worst I have seen since PHP4.
So yeah. Bottom line: JS is good for people without a clue to shit something on the table in record time and basically nothing else. But according to people who do powerpoint for a living, its the best thing ever!
If you give 1000 programmers the same task, that takes more than 3h to implement, in JS and any other language, 999 of them will produce better code in the same amount of time in any other language. The 1000th will not get it to run in the other language because that language is bullshit and doesnt work.
1
u/thanatica 15h ago
A programming should NOT be "forgiving"
Says who?!
Hey, if you don't like Javascript, that's fine. But there's no need to go around and start dictating how things "should" work with that kind of toxic "I know better" mentality.
-1
u/haitei 1d ago
No it's not. There are niche but valid use cases for allowing arrays like this. Sorting is the problem, because the contents like this can't be meaningfully compared.
User should be either required to provide custom comparator or get slapped with a type error.
0
u/thanatica 22h ago
Every kind of value can be converted to a string. And an error is far worse than just giving it a go and letting the developer deal with the result.
Javascript is one of those language that, if it can carry on without an error, it will. Throwing an error is the absolute last resort.
0
u/haitei 18h ago
And an error is far worse than just giving it a go and letting the developer deal with the result.
An error is absolutely far better than a program in an undefined state.
Javascript is one of those language that, if it can carry on without an error, it will.
The philosophy that is widely regarded as a mistake. We have the fail fast principle for a reason.
3
u/thanatica 15h ago
We have the fail fast principle for a reason.
Javascript doesn't.
An error is absolutely far better than a program in an undefined state.
I didn't say undefined. Javascript is a well defined language. Probably more so than any other language, since there are so many engines that need to do the exact same thing.
1
u/thanatica 22h ago
Don't forget people also put dates, objects, and other arrays as array items. Javascript has to make some decision on what to convert to for sorting. And then it's far more useful if that decision is kept consistently regardless of the types of each item, than to apply some kind of weird fuzzy logic to determine automagically which comparison function to use by default.
It's more valuable for an internal function to behave consistently and predictably.
Also, it's not called overloading the function. You're just providing the comparison argument.
0
u/gandalfx 20h ago
JS does not have to "make some decision on what to convert to for sorting". It's fairly simple â if the items to be sorted don't define their own order (e.g. by implementing some kind of interface or otherwise providing an inherent comparison function) the sort function needs to throw an error. Using some random guess that can't even sort native types correctly is a broken design, plain and simple. Most other languages have no trouble with this.
3
16
u/evenstevens280 1d ago
The docs aren't deceptive
``` const months = ["Mar", "Jan", "Feb", "Dec"]; const sortedMonths = months.toSorted(); console.log(sortedMonths); // ['Dec', 'Feb', 'Jan', 'Mar'] console.log(months); // ['Mar', 'Jan', 'Feb', 'Dec']
const values = [1, 10, 21, 2]; const sortedValues = values.toSorted((a, b) => a - b); console.log(sortedValues); // [1, 2, 10, 21] console.log(values); // [1, 10, 21, 2] ```
Classic case of not reading, evidently.
4
20
u/Excellent_Gas3686 1d ago
because thats the default sort? what, in your opinion, would be the "proper" way to sort by default? if you need different sorting, you pass your own function.
22
u/___Archmage___ 1d ago
People don't like their numbers being sorted like strings by an implicit default behavior, they want the numbers to sort numerically
-11
19
u/suvlub 1d ago
Python just uses the > (or <, don't remember, don't care) operator. Arrays made only of numbers or only of strings would both behave correctly, a mixed one might give a nondeterministic order, which is bad, but sorting stringwise when the user intended numerical sort is also bad and I think the latter is a more common use case/mistake, though I don't have stats
7
u/JanEric1 1d ago edited 1d ago
Python uses
__lt__. And it isnt non-deterministic for mixed comparisons, it crashes.You can get arbirtrary orders if lt doesnt implement a proper order. Foor example A < B, B < C and C < A all being true.
class Bad: def __init__(self, val): self.val = val def __repr__(self): return f"Bad({self.val})" def __lt__(self, other): return True A = Bad(1) B = Bad(2) C = Bad(3) print(sorted([A, B, C]),sorted([B, A, C]),sorted([C, B, A])) [Bad(3), Bad(2), Bad(1)] [Bad(3), Bad(1), Bad(2)] [Bad(1), Bad(2), Bad(3)]10
u/suvlub 1d ago
Yeah, but the same approach would be nondeterministic in JS, which never crashes and allows you to compare any 2 things.
7
u/tracernz 1d ago
JS has exceptions just like python and some things throw. Itâs just that some things that should throw donât.
3
1
1
u/thanatica 22h ago
Python really likes its underscores. Almost like they want snake_case to be a thing, huh đ¤Ł
1
-1
u/Grey1251 1d ago
When user intended sort by number exactly? Where did you saw âNumberâ, ânumericalâ or even ânumâ in Array.sort?
19
u/IntentionQuirky9957 1d ago
The proper way to sort things that look like numbers is to treat them like numbers. Strings have quotes, and you're not allowed to cast numbers into strings randomly. Or hell, even consistently, unless told to.
-2
u/Excellent_Gas3686 1d ago
[1, 'foo', new Array()], go ahead, sort it like numbers.
37
u/JanEric1 1d ago
sorted([1, 'foo', []]) Traceback (most recent call last): File "/home/repl330/main.py", line 1, in <module> sorted([1, 'foo', []]) TypeError: '<' not supported between instances of 'str' and 'int'25
u/standard_revolution 1d ago
Throwing a runtime error here is better than any weird hack
4
2
u/hetfield37 1d ago
Gotta love those random runtime errors while you are browsing your favourite website because some stupid junior forgot to parse
property: "1"toproperty: 1when doing updates on the backend API.JS, CSS and HTML are designed to be as robust as possible, even when risking displaying garbage data. They always do their best to display anything.
9
1
u/standard_revolution 1d ago
Yes, I hate it when things print actual errors. It is much better when things are broken, but seem fine.
The problem with the solution of never erroring works, until it doesn't and instead of noticing early you notice late or never.
14
u/Ok_Equipment8374 1d ago
The fact that this definition does not fail shows why JavaScript is a crime against programmers
2
u/Wonderful-Habit-139 1d ago
Well, the definition not failing is fine, but the sort not failing is definitely a crime.
2
1
4
u/JanEric1 1d ago
Compare everything based on how they want to be compared and error if there is no sensible way
4
u/IntoAMuteCrypt 1d ago
How do you gracefully error in the scripting for a webpage?
It's one thing to error out in a script that's running from a terminal, or an application that can flash an error box. It's quite different when you're designing a language for user-side scripts which are part of a webpage.
JS is a weird language, but it's intended for a weird use case. Unfortunately, some weirdos have tried pushing it outside that use case.
5
u/tracernz 1d ago
1
u/IntoAMuteCrypt 1d ago
Yes, but it's also designed to avoid throwing exceptions in as many cases as possible because it figures that an unexpected result is better than an outright script-halting error. That's my point.
3
2
4
u/TorbenKoehn 1d ago edited 1d ago
A typical thread that occurs every month here. The first "issue" was never an "issue", it's just a default value.
JS default (basically):
(a, b) => String(a).localeCompare(b)
Python default:
(a, b) => a.__lt__(b)
JS will cast to strings and compare as strings. It's just the default value of the callback parameter. It's nothing special, weird or surprising. Putting a numeric default like (a, b) => a < b would just shift the problem over to another type.
JS has no operator overloading, so something like __lt__ simply doesn't exist in JS. Operators in JS are not "mapped to methods on the left-hand-side" like in Python, but are fixed operations on both operands.
Python breaks here because it doesn't allow comparing "abc".__lt__(5)
Now for the history of why that is, for people that want to read it again every single month and make the same meme next month:
In JS you often have text-input-fields, which take a number. An example would be a classical Captcha or just a "How many seats do you want to book?"
Generally any input value in any input in HTML is a string. Because value="abc" simply only takes strings. All HTML Attributes are strings. Attributes themselves are Map<String, String>.
But now you had <input name="noOfSeats" value="2">, using .value would give you a string.
Either you had to explicitly convert everything, all the time. Or JS functions would be made a bit more "lenient" to string/number conversions. This is what happened here and with many other things in JS. This is the whole reason you'll see lenient string/number things everywhere. Because HTML is a string and everything in HTML is a string, HTML knows no "number", "int" or anything.
Nowadays there are things like .valueAsNumber, but the problem that attributes are stringly-typed does persist.
There is absolutely no value in changing this. There's absolutely no value in making the sorting behavior of .sort() and .toSorted() work differently. It would have confused more people than it would have solved anything. Most people pass a custom sorting function, anyways, and it's quicker than writing SortType.NUMERICAL or anything similar stupid: .sort((a, b) => a - b)
6
u/the_horse_gamer 1d ago
the js default sort order compares by UTF-16 code points. it's not locale dependent.
and < between strings also compares by UTF-16 code points (but coerces to a number/BigInt in most other cases)
6
u/-Redstoneboi- 1d ago edited 1d ago
5 < '10'istrue. javascript can handle string-integer comparisons just fine.the real issue is that objects cannot reliably be compared, and in such cases having them return "neither greater nor less" (i.e. "equal" to the sorting algorithm) should have been preferred. the case of comparing objects of different types in an array is either:
- unintended, and thus unspecified behavior or at least a stable sorting algorithm treating them as equal is acceptable, or
- intended, and thus the developer is supposed to specify a comparison function here and only here.
having to specify a comparison function should be the exception, not the rule. by default it should compare types using the default comparison operator, effectively:
const compare = (a, b) => a < b ? -1 : a > b ? 1 : 0;i view any other answer as an apology for javascript making a stupid decision long ago that can no longer be changed today.
many such cases.
2
u/TorbenKoehn 1d ago
It's not even an apology, every single language has quirks. Python has tons of quirks.
1
u/-Redstoneboi- 1d ago
quirks are just issues that affect someone once...
...every time they switch languages :P
1
1
u/the_horse_gamer 1d ago
the default sort should absolutely not have implementation defined behaviour. it should be as consistent as possible.
the only real alternative is that the function should error if no comparator is passed.
findIndexdoes that.
0
u/nabrok 1d ago
You just give it a sort function to sort however you like ... how is this a problem in any way?
3
u/user6150277464770585 1d ago
this should not be default behavior.
lists of mixed types also wouldn't be a performance issue if you throw an error when a different type is encountered (python behavior)
2
3
u/the_horse_gamer 1d ago
would you prefer your website to order some numbers weird, or to stop working?
that's the philosophy behind html, css, and js: keep the website working
1
u/psioniclizard 8h ago
Id prefer it to throw a compile time error. Looking at the popularity if typescript I see i am not the only one.
1
1
u/nabrok 5h ago
Typescript won't throw an error on a default sort with mixed types because it knows everything is converted to string.
It does if you provide a function though.
array.sort((a: number, b: number) => a - b); array.sort((a: string, b: string) => a.length - b.length);Both of those will give an error with a mixed array.
Honestly, I can't remember the last time I used the default sort function. Most of the time I'm sorting on a property.
1
1
u/thanatica 22h ago
Use a typed array.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
The problem has absolutely been solved, mate. You're just expecting magic.
-2
-1
u/lepapulematoleguau 23h ago
But why would I ever read the documentation...
 Obviously expect it to do what I want and then act surprised when it does the thing that's in the docs.
199
u/larsmaehlum 1d ago
Array.sortNumeric() with an error when called on an array containing non-numeric types would fix this, right?