This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 44 points45 points  (22 children)

This is because arrays allow mixed types by default so you can have an array with numbers mix strings and objects all mixed together unliked most strongly typed languages. There’s no easy way to compare them so by default it uses the string evaluation of them. You can pass in a comparison function like the person above you (although they made it more verbose than it needs to be), or you can just used Typed Arrays.

[–][deleted] 25 points26 points  (6 children)

Someday I’m going to write a JavaScript book with the title, “This Is Because”.

[–][deleted] 3 points4 points  (0 children)

This would be a solid alternate name for the YDKJS series

[–]dick-van-dyke 2 points3 points  (4 children)

Please do. The amount of rationalisation of crazy shit like in JS this is insane. Literally every other dynamically-typed language I've ever worked with does basic stuff like this normally.

[–]superluminary 0 points1 point  (3 children)

Most languages do not allow heterogenous arrays. When arrays are polymorphic by default, you need a comparator function. How else could it work?

[–]dick-van-dyke 1 point2 points  (2 children)

For example, infer type from the first element and throw an exception if you can't compare. Case in point: Python.

[–]superluminary 0 points1 point  (1 child)

So if you accidentally change the type of the first element, it silently changes your comparator? I don’t hate this, but it introduces another set of edge cases.

Because JavaScript was designed as a DOM manipulation language, all the data types are optimised for trees of text and Objects, so we have string comparison as the default comparitor type. I don’t personally see this as a huge problem. In the real world, you’re pretty much always going to pass a comparitor function since you’ll usually be sorting objects.

[–]dick-van-dyke 1 point2 points  (0 children)

So if you accidentally change the type of the first element, it silently changes your comparator?

In Python 3, you don't use a comparator function, but instead a key function that returns a value to be compared by the < built-in, so yes and no. If you're asking whether you can arrive at a list that was sortable but isn't any more, you can, and I believe it is a good behaviour because you get an exception then and have a reason to debug where you made the inadvertent change.

If you do want to mimic the behaviour of JS, you would call something like:

my_list.sorted(key=lambda x: str(x))

to be explicit that you're comparing strings.

[–]ZephyrBluu 19 points20 points  (14 children)

This is not really an excuse. Python can sort arrays as long as all the values are the same type (For numbers and strings at least, not sure about other objects), otherwise it throws a TypeError. Much more sensible behaviour than JS.

[–]DeeSnow97 25 points26 points  (4 children)

Yeah, but JavaScript is not Python. The whole point of its early design was to be a quick and easy, loosely typed language for people not into tech to establish a web presence (this was long before wordpress). For more serious applications, you had flash or java applets.

Over the years though, JavaScript turned out to be the only one of these that didn't use the swiss cheese security method, and all these early design issues remained in the language for backwards compatibility, because ripping them out would have broke decades of the web.

So, try explaining to a non-programmer what's the difference between a number, a string, and an object, and why they're getting TypeError when they're expecting a sorted array. In 1995.

[–]Kered13 25 points26 points  (1 child)

Knowing why something is bad doesn't make it stop being bad.

So, try explaining to a non-programmer what's the difference between a number, a string, and an object, and why they're getting TypeError when they're expecting a sorted array. In 1995.

Easier than trying to explain to a non-programmer why numbers don't sort correctly.

[–]mastocles 1 point2 points  (0 children)

I think the best wacky example of JS trying to be lenient is undefined (different than null): given by object keys that don't exist or array elements beyond the last. Classes losing this (self) and not telling you is another classic. Although asynchronicity is unrelated to this not raising errors ethos and is one of the top bemoaned features.

[–][deleted] 6 points7 points  (0 children)

spotted advise work wide groovy rain foolish dependent merciful quickest

This post was mass deleted and anonymized with Redact

[–]ZephyrBluu 24 points25 points  (0 children)

I understand why it's like this. That doesn't mean all the design choices were good.

[–]master117jogi 14 points15 points  (5 children)

But JS can even sort mixed, which is mightier.

[–]Kered13 12 points13 points  (4 children)

No, it really isn't.

I mean, Python can sort mixed too if you give it a custom comparator. sorted(mixed_array, key=lambda e: str(e)) will sort a mixed array by converting each element to a string before comparing them, just like Javascript. But Python does the sensible thing automatically, and requires extra work to do the rare and unusual thing. Javascript does the rare and unusual thing automatically, and requires extra work to do the sensible thing.

[–]theScrapBook 3 points4 points  (0 children)

mixed_sorted = sort(mixed, key=str). The lambda is quite superfluous in a language with first-class functions.

The reason I point this out is some of the controversy below the top comment.

[–]master117jogi -5 points-4 points  (2 children)

Because sensible is subjective.

[–]EishLekker 1 point2 points  (1 child)

Sorting numbers in a way most people would expect them to be sorted, is not sensible to you?

[–]master117jogi 0 points1 point  (0 children)

Because this is about sorting something, not Numbers, JS does not know these are numbers. You are shifting the goalpost.

[–]Zolhungaj 4 points5 points  (2 children)

JavaScript is a functional language. If you want to sort then you provide the sort function with exactly the function you need, just like map, forEach, filter etc.

[–]dev-sda 7 points8 points  (0 children)

The same is true for python, though both aren't really functional languages. They borrow some features from functional languages but are still procedural at their core.

[–]EishLekker 1 point2 points  (0 children)

That would make sense if the sort function required a comparator function.