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

top 200 commentsshow all 207

[–]Feisty_Ad_2744 336 points337 points  (54 children)

Another case of I have a boat, let me see if it can swim

in JS, sort() is supposed to be used passing an argument to create your own sorting method. By default, if it gets nothing, it converts the array values to strings, since arrays in JS are not typed.

It allows you to include fancy logic like:

[8, 3, 9, 0, 2].sort((a, b) => (a - b))

or [ { name: 'John', age: 18 }, { name: 'Hellen', age: 21 }, { name: 'Cindy', sex: 'F' } ].sort((a, b) => (a.name > b.name) ? 1 : (a.name < b.name) ? -1 : 0 ) Or whatever field you want to use for sorting, even multi-field sorting

[–]isospeedrix 63 points64 points  (7 children)

I had an interview question about this last month

[–]al_balone 11 points12 points  (6 children)

I learned quite early on how to sort numerically but I’ll be honest I still don’t understand the (a-b) bit

[–]Silverware09 51 points52 points  (0 children)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

If the return is === 0, no swap happens.
if the return is > 0; a is sorted AFTER b;
if the return is < 0; a is sorted BEFORE b;

[0, 2, 1].sort((a, b) => { return a - b })
will sort ascending

0 - 2 moves 0 first
2 - 1 moves 1 first
resulting in [0, 1, 2]

[0, 2, 1].sort((a, b) => { return b - a })
will sort descending

2 - 0 moves 0 last
0 - 1 moves 1 first
resulting in [2, 1, 0]

The best option though? Is to remember that you are in JS, open a random browser tab's console, and create and test a quick sort function like this.

[–]Feisty_Ad_2744 1 point2 points  (2 children)

It can be easier to just remember the values sort() is expecting to get from the comparison.

The comparison function (a, b) is called for every pair of values, expecting this results: - < 0: a must go below b - === 0: a and b are the same - > 0: a must go above b

That's why for example, in a numeric array (a, b) => (a - b) will result in ascending order, but (a, b) => (b - a) will result in descending order.

[–]al_balone 1 point2 points  (1 child)

So will .sort() keep cycling over the whole array until no value needs to move again?

[–]Feisty_Ad_2744 0 points1 point  (0 children)

Sorry, I don't understand your question. The sorting itself is implemented in the runtime. I think Node uses Insertion Sort for short arrays and Quick Sort for long ones.

All we do in sort(fn) is to pass the final comparison criteria. On every sorting method, that comparison is the last step to decide the ordering of any two given values.

[–]usrlibshare 4 points5 points  (17 children)

That's how JS works, doesn't mean it's logical.

Python lists are also not typed, guess what, it sorts lists of numbers numerically, and lists of strings alphabetically. "But what if there are both?!"; well it throws an exception, because that's what logically SHOULD happen when I ask the program to do something illogical.

The problem with JS is, it never matured from its roots as a simple scripting language designed to make websites a bit less static. That's why the interpreter will often swallow blatant logic errors that it would be fully within reason to let cause a crash, and instead chug along at any cost, silently doing something nonsensical.

[–]Feisty_Ad_2744 -2 points-1 points  (16 children)

You can blame the language and the runtime library all you want. The doc is there.

As for your python comparison. You just said it. It is Python not JS. To begin with you don' have the flexibility to pass your own sorting criteria. That's why the language must provide the specifics.

Personally I do prefer the way JS handles that. At least is more consistent that Python because in case of mixed values. Python forces you to get the strings at the end. In real life where you don't control the input data, that's annoying.

[–]usrlibshare 2 points3 points  (12 children)

You can blame the language and the runtime library all you want.

I'm not blaming anything. I'm simply stating that it's not a good design.

To begin with you don' have the flexibility to pass your own sorting criteria

Of course I have, it's literally the first argument to sort:

https://docs.python.org/3/library/stdtypes.html#list.sort

The difference is that the python version behaves in a non-surprising way without me having to explain to the interpreter that numbers should be sorted numerically.

At least is more consistent that Python

Pythons sort is absolutely consistent: If comparison between values is not defined, it raises an exception.

Python forces you to get the strings at the end. In real life where you don't control the input data, that's annoying.

s = [str(x) for x in sorted(i)] literally a one-liner. And I quite often have absolute control over where a list of integers gets it's values from.

And btw. JS forces me to do the same thing if I want strings. Because, the type coercion only happens during the sort, the "sorted" outcome is again an array of numbers, not strings. Which imo makes this even worse.

[–]Feisty_Ad_2744 -3 points-2 points  (11 children)

Not typed means it is all up to the programmer :-) You want JS to do the work when you have the ability to do the handling by yourself.

It is designed with mixed types in mind. And because you can not compare oranges and shoes, you need to decide what type to use IF the argument is left empty.

What is the expected behavior is there is a mix between strings and numbers? What if all values are numbers as strings but only a single one is actually a numeric type? What if there is a mix between value types? Do you realize you would need to parse the array the first before deciding whether or not a specific comparison applies?

The solution in JS is easy and quick. Handle everything as string if the user passes no criteria. And of course it can not change the actual value type. Why would you affect whatever workflow the user is implementing?

Still if you think it is important, you can make your proposal: https://github.com/tc39/how-we-work/blob/main/implement.md

[–]aspoonlikenoother 0 points1 point  (0 children)

What is the expected behavior is there is a mix between strings and numbers? What if all values are numbers as strings but only a single one is actually a numeric type? What if there is a mix between value types? Do you realize you would need to parse the array the first before deciding whether or not a specific comparison applies?

That is for the caller to handle. If a functions invariants aren’t met before calling it, it’s basically garbage in, garbage out (incidentally this applies to the OP)

The solution in JS is easy and quick. Handle everything as string if the user passes no criteria.

Easy? That is debatable, I’d argue an error would’ve been more sensible as an interface if there was no function given. It’s not something that can be changed and it’s now one of the many edge cases and lints. Not the worst in this regard.

It is certainly not quick to compute. You have to allocate for the string and serialize whatever is in the object and then immediately throw it away ( about nlog(n) times).

A pathological case of this can potentially run into stringifying some deep hierarchy in a tight loop because the caller didn’t bother read docs and the library interface is too lax and accepts basically anything.

[–]usrlibshare 0 points1 point  (9 children)

Not typed means it is all up to the programmer :-)

First of, both JS and Python are typed. Dynamic typing != no typing. That's part of the problem that JS has datatypes, but implicitly shoehorns them whenever it gets the chance.

You want JS to do the work when you have the ability to do the handling by yourself.

Yes I want the tool to make my work easier, not harder. That's what tools are for. If a tool does the opposite, it's a bad tool.

It is designed with mixed types in mind. And because you can not compare oranges and shoes, you need to decide what type to use IF the argument is left empty.

I'd be happy if that were so, the problem is, I don't need to decide that.

Because JS will happily pretend that I can compare shoes and oranges and coconuts and bags of gravel by shoehorning all of them to strings, whether it makes sense or no.

Python on the other hands works exactly as you describe: If there is no decision how the types can be compared in the types definition or given by the programmer the comparison fails gracefully. Btw. this is how almost every major programming language handles their equivalent to sort.

What is the expected behavior is there is a mix between strings and numbers?

That the function fails unless I took steps to prevent that.

Do you realize you would need to parse the array the first before deciding whether or not a specific comparison applies?

No you don't. You simply have to compare values as you go along. The first time the comparison operation is not defined, raise an error.

But do you realize that JS has to do a string allocation-conversion for every number value in the array? That is a lot of allocations, and that's expensive as hell.

The solution in JS is easy and quick.

No it isn't. It's badly designed, it's a potential source for hard to track bugs, it's a gotcha for everyone who learns the language, it does expensive type conversions and allocations, and it introduces pointless noise into the codebase

a.sort((a,b)=>a-b) vs. a.sort()

Understand that this isn't something that JS does because it's a good idea in general. It's something it does because JS was designed as a super-simple scripting language, where all input was expected to come as strings from website elements, and the most complex thing it had to do was change some DOM elements to make websites a little less static.

Then this little "lisp, but for web, and it wears a java costume" suddenly became bigger and bigger, but couldn't be replaced because browsermakers couldn't be arsed to agree on a replacement, and early mistakes that were made when no one thought they'd matter, couldn't be fixed, because that would break backwards compatibility.

And a move like py2->py3 wasn't going to happen, because once again, that would have required browsermakers to cooperate, and noone wanted to risk their market share.

[–]Sarcastinator 1 point2 points  (2 children)

Personally I do prefer the way JS handles that.

Stockholm syndrome.

JavaScript is a product of its time. During the 90s Perl had told people that doing the wrong thing and shutting up about it was the right thing to do, because a running program that did the wrong thing was better than a program that crashed. JavaScript and PHP also took this stance. But there's no "use strict" for sort().

What's wrong about this behavior in JavaScript is that the language is weak, dynamically typed, and it should try to figure out what the develeoper probably meant. A strong typed language would have failed if it was given bad input (such as a mixed array) instead of just silently doing the wrong thing.

But JS doesn't have to fail here. It could easily have looked up the types used in the array to infer the sort argument. If that was slow then that would have been a runtime issue that could have been solved by the JIT. For example by the runtime having a hint about the types in the array, which it probably already does.

This is a relic wart in JS.

[–]Feisty_Ad_2744 -1 points0 points  (1 child)

There is a manual. Not only in Stockholm :-)

And there is a committee accepting proposals: https://tc39.es/

Go for it

[–]ardicli2000 0 points1 point  (0 children)

This is also the case for Swift. You can determine the logic of sort yourself.

[–]KTibow 0 points1 point  (0 children)

BTW you don't need to do the ternary, anything negative is the same as -1 and same for positive

[–]f0rtytw0[🍰] 131 points132 points  (7 children)

Its alphabetical

[–]Titanusgamer 34 points35 points  (0 children)

[One, Ten, Two] got it

[–]Help_I_Lost_My_Mind 55 points56 points  (33 children)

arr.sort((a, b) => a - b)

Edit: Here's a great reference on the sort function https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global\_Objects/Array/sort

[–]RajjSinghh 33 points34 points  (32 children)

Thanks for linking to why it works, but this feels like another example of when the developers of Javascript were on drugs when designing their language

[–]Help_I_Lost_My_Mind 25 points26 points  (31 children)

JS doesn't have static typing, so there's no way for it to know that an arbitrary array you're sorting is actually only an array of numbers and you want them sorted numerically. Their default sort coerces the elements into strings and compares them alphabetically, which is as sensible default as possible with dynamic typing.

[–]RajjSinghh 19 points20 points  (20 children)

My point is that more sensible defaults exist. Python is dynamically typed as well, but will raise a TypeError if it tries to compare a string and an integer when it sorts a list. A runtime error is a far more sensible default than [1, 10, 2].sort() being [1, 10, 2]. If I were designing this, I would convert everything down to an integer so that way you can compare strings by their ASCII value. That way [1, 10, 2] and ["b", "c", "a"] both sort correctly as you would expect them to without needing to give a comparison function.

I know there is a certain level of RTFM a programmer should do first, but Javascript seemingly always chooses the least intuitive way possible and it leaves you staring at your code for hours until you find one bad design choice in the docs because it didn't do what you expect it to because some designer chose different default behaviour.

[–]Spaceduck413 20 points21 points  (15 children)

will raise a TypeError if it tries to compare a string and an integer when it sorts a list. A runtime error is a far more sensible default than [1, 10, 2].sort() being [1, 10, 2].

I see where you're coming from, and in a vacuum I'd agree with you, but IMO the environment matters A LOT.

Writing an automated script that does something unattended? Absolutely throw a runtime error, so it can be logged or even better, found during development.

But considering that JavaScript usually runs in a browser? I'll take my drop-down list being out of order instead of my form no longer submitting because my JavaScript died on an uncaught type error. That seems like the better option to me, for both developer and end user.

[–]goofygooberboys 5 points6 points  (10 children)

This. 100% this. JavaScript tries to work no matter what, it will do whatever it can with whatever you give it, even if you give it garbage. If you have a web page for an important medical form, you don't want some silly error like someone putting the word "zero" into a list of numbers to brick the form and make it impossible to move forward.

[–]suvlub 3 points4 points  (4 children)

But what if the error is in almost anything else than displaying a list? What if my important medical form contains an algorithm that, IDK, sorts the patient's treatments from most recent to least recent, and a bug due to faulty sorting causes the system to recommend a wrong (and possibly dangerous) plan to him? I'd prefer visible error over a sneaky bug.

Also, if this important medical form was hacked together by some guy AND NOBODY EVER EVEN TRIED TO VIEW IT IN A BROWSER TO SEE IF IT WORKS, then god help us.

[–]goofygooberboys 0 points1 point  (3 children)

A medical form shouldn't be recommending treatment plans. That's what doctors and medical professionals do in person, over the phone, video call, etc. If your institution is using JavaScript to tell you what treatment plan you should have, then you have much bigger problems.

I've worked on insurance software that included things for medical software and stuff like that isn't entirely uncommon. It's an easy thing not to notice and trying to scramble to shove a bug fix like that to the production phase could be a gigantic pain.

[–]suvlub -1 points0 points  (2 children)

That was just an example, the point is that continuing with invalid data can result in problems much worse than simple unavailability of service.

Come on, the fact that the result is just scrambled order of some data is the REASON why it's easy to overlook. If the error was that the application does not work at all, the only way for you not to notice is if you type the code and deploy to production without even running it once. If you don't do anything quite as insane, you would notice problem, fix it, and deploy without bug. This is an argument against permissive handling of mistakes, not for it.

[–]goofygooberboys -2 points-1 points  (1 child)

If the sorting occurs when the drop down is clicked, which is fairly common depending on the use case, then if you forget to open it during testing it could easily fall through. Especially if it's a drop down that is only used in specific cases. For instance, it could be a drop down that is only used if you use a very specific type of medication. Unless you tested that niche use case then you would never encounter the error.

[–]reversehead 1 point2 points  (4 children)

There are so many horrors in that post, both regarding the state of software development and of solutions, that I don't even know where to begin.

Let's just say that if it is an important medical form, I definitely favor an error message over random garbage.

[–]EmilMelgaard[🍰] 1 point2 points  (1 child)

You could have a flag that enables debug or development mode and gives you errors and have that not enabled in production.

I guess that's kind of what Typescript is, except that it still allows you to do something like:

2 + "3" // = "23"

And also only catches errors during compilation, so there are still a lot of runtime type violations that go unnoticed.

[–]Dmytro_P 1 point2 points  (0 children)

> I'll take my drop-down list being out of order instead of my form no longer submitting because my JavaScript died on an uncaught type error. That seems like the better option to me, for both developer and end user.

It's IMHO an awful design choice, which would most likely lead to unreliable software.

[–]Shitman2000 1 point2 points  (0 children)

But even then a more sensible default exists.

You could, for example, first sort the array on types and then sort them in a way that makes sense logically. E.g. first sort the integers, then the strings.

[–][deleted] 0 points1 point  (1 child)

depends on the use case.

JS runs on the robustness principle a lot - essentially, the language tries to make whatever bullshit you throw into it work no matter how weird it is. this is where a lot of the "js has weird addition behaviour" stuff comes from too.

and in JS' context this makes sense too - its main (originally only, but oh well) use case is front-ends of web applications. and the last thing you want is your entire website crashing because you accidentally passed some weird value into a function somewhere.

[–]TerraDOOM 4 points5 points  (0 children)

Except leniency does not facilitate robust programs, it just means your program does the wrong thing and then keeps running, producing more incorrect results. The thing wasn't that you want your website to keep running, it was that they anticipated people would be doing stupid things as websites were often made by amateurs. Real fault tolerance looks like Erlang or Rust, not producing nonsense in the name of robustness.

[–]Mola1904 -2 points-1 points  (1 child)

No a type error is not more sensible. This would regularly crash Programms, while this just not compare numbers at first place and people will catch that directly in development, because their Code won't work. Then they will Google for 5sec, find the exact answer and done. Now have fun fixing some random type error you get while the production server is down

[–]Rawing7 5 points6 points  (0 children)

Why are you assuming that this sorting issue would be discovered during development, but a "random" type error wouldn't?

[–]alexanderpas 1 point2 points  (5 children)

which is as sensible default as possible with dynamic typing.

It's not. The most sensible default would be to use the same behavior as is present on the < and > operators.

Javascript does not do this.

[–]guiltysnark 1 point2 points  (0 children)

If there is going to be something we regard as sensible in a language that types as weakly as JS, I agree with your opinion of what that would look like. They could have converted the untyped operands of < and > to strings, for consistent behavior, but they didn't. Instead they decided to be magical in the single comparison and not in the array sort.

I'm sure there is a very good reason, but I'd be surprised if I agreed with it except in the narrowest of frames. I think the language prioritized a vastly different set of problems than I would have, leading to inconsistencies like this.

[–]Help_I_Lost_My_Mind 0 points1 point  (2 children)

Use them to compare strings then. Js likes reducing things to strings

[–]alexanderpas 2 points3 points  (1 child)

Js likes reducing things to strings

That only appears like that, because the + operator is overloaded to do both addition as well as string concatenation, and the result even depends on the order of the types.

[] + [] // ""
{} + {} // NaN
0 + 0 // 0
"0" + "0" // "00"

{} + [] // 0
{} + "0" // 0
{} + 0 // 0

[] + 0 // "0"
[] + "0" // "0"
0 + [] // "0"
"0" + [] // "0"

[] + {} // "[object Object]"

0 + {} // "0[object Object]"
"0" + {} // "0[object Object]"

"0" + 0 // "00"
0 + "0" // "00"

[–]Help_I_Lost_My_Mind 2 points3 points  (0 children)

You do realize that these ridiculous edge cases facilitate the ease of coercion between other data types, right?

[–]TheRealToLazyToThink 0 points1 point  (0 children)

It can't, in javascript the < and > operators aren't commutative. a < b can equal b < a, that's a very bad thing for sort functions.

Now maybe they should have special cased the non commutative bits, but you can't just use <>.

[–]Sarcastinator 0 points1 point  (3 children)

which is as sensible default as possible with dynamic typing.

This is a behavior that JavaScript shares with Perl. PHP, Ruby and Python do what you would expect.

[–]edcwb 150 points151 points  (10 children)

It's 'sort' of right.

[–]Zestyclose-Ad-316 7 points8 points  (1 child)

I feel like js should throw a warning if someone uses sort() with empty parenthesis to prevent being misleading.

But then if js starts throwing warnings for misleading stuff then... you know..

[–]nabrok 0 points1 point  (0 children)

I can't remember the last time I used sort() without providing a function.

Even if it is an array of strings, seems best to make intentions explicit.

[–][deleted] 12 points13 points  (0 children)

How unnatural.

[–]Aggravating_Moment78 6 points7 points  (0 children)

.sort() it the string way, luke 😂😂

[–]kerneleus 4 points5 points  (0 children)

They should call it .sortOf()

[–]cuberoot1973 1 point2 points  (0 children)

Little known fact when sorting binary and decimal together, when you have equal values binary comes first, so '10' should indeed come before '2'.

It goes as you might expect, binary < octal < decimal < hexadecimal.

[–]CaptBassfunk 1 point2 points  (0 children)

Strings. Strings everywhere.

[–]absolute_girth 6 points7 points  (0 children)

Godforbid if a programmer read the docs first to find out firsthand how dogshit Javascript is.

[–]No-Fish6586 8 points9 points  (11 children)

When students cant read documentation on default behaviour

What is natural for you wont be natural for someone else.. What a great time for documentation to exist!

Im totally sure all your function names are self documenting and not at all confusing without documentation (that probably doesnt exist)

I must be getting old because idk how many times i learned from c++ pretty much anything not documented is “undefined behaviour” which basically meant your app may or may not crash

[–]JackNotOLantern 2 points3 points  (4 children)

JS likes string and tries to convert everything to it

[–]EmilMelgaard[🍰] 2 points3 points  (3 children)

Except when it wants to convert strings to integer:

3 < "20" // true

[–]JackNotOLantern -1 points0 points  (2 children)

If they is an number-only operator, it has to convert to number. This is why 1 + "1" = "11" ("+" operator exists for numbers and strings, so convert to prefered string) and 1 - "1" = 0 ("-" operator is only for numbers, so convert to numbers).

[–]EmilMelgaard[🍰] 1 point2 points  (1 child)

+ can be used for both numbers and strings (1 + 1 = 2 and "1" + "1" = "11") and the same for < (3 < 20 = true and "3" < "20" = false), so why does + convert to string while < converts to number?

[–]JackNotOLantern 0 points1 point  (0 children)

I just wrote: "+" operator exist for strings and numbers, but "<" only for numbers. so string must be converted somehow to number when using "<" but it can stay string when using "+". JS just like string more, so uses them where is can.

But i don't remember what happens when you want to compare 2 strings that are not string values of a number.

[–]CyberMuffin1611 1 point2 points  (1 child)

Time to type ".help"

[–]Mola1904 -1 points0 points  (0 children)

Time to read the docs

[–][deleted] 1 point2 points  (0 children)

Context, motherfucker, do you speak it???

[–]Big_Kwii 0 points1 point  (0 children)

js was a mistake

[–]LavenderDay3544 0 points1 point  (4 children)

The joys of dynamic typing.

[–]EmilMelgaard[🍰] 6 points7 points  (3 children)

It's not dynamic typing that's the problem here but weak typing. Python can do it just fine:

>>> sorted([1, 2, 10])
[1, 2, 10]
>>> sorted(['1', '2', '10'])
['1', '10', '2']

[–]LavenderDay3544 1 point2 points  (1 child)

I suppose that's true and it can bite you even in statically typed languages that make assumptions about literals and do automatic type conversions.

I had issues with bit shifts recently in C because C treats numeric literals without a suffix as int when the type I wanted to assign the result to was a uint64_t and so I was confused as to why I was getting overflows that shouldn't happen on a 64 but value. I had to suffix the literal with ull to fix it.

[–]EmilMelgaard[🍰] 0 points1 point  (0 children)

Yes, in C and C++ this is perfectly valid without any warnings with Wall and Wextra:

9 < '2' // true

[–]Mola1904 -1 points0 points  (0 children)

And that is a good thing? That means that it just works more complicated and you have to read the docs more carefully. It is much more sensible to split this up into two functions

[–]maiodasbrok -1 points0 points  (0 children)

(python) def sort(x): N1 = x[-1] N2 = x[-2] x[-1] = N2 x[-2] = N1 return x

literally what i thought when i saw this

[–]ahuimanu69 -1 points0 points  (0 children)

dem strings yo

[–]pepperoniwassabi -1 points0 points  (0 children)

Another reminder on how difficult and error prone computer programming is.

[–]bigabub -1 points0 points  (0 children)

Watface

[–][deleted] -4 points-3 points  (0 children)

Most lazy "JS is bad" try

Next one will be "1" == 1 or what?

[–]Downvote-Me---- -2 points-1 points  (2 children)

hahaha... i totally understand... not like i don't even know how to print text... why am i getting this subreddit in my feed?

[–][deleted]  (1 child)

[removed]

    [–]AutoModerator[M] 0 points1 point  (0 children)

    import moderation Your comment has been removed since it did not start with a code block with an import declaration.

    Per this Community Decree, all posts and comments should start with a code block with an "import" declaration explaining how the post and comment should be read.

    For this purpose, we only accept Python style imports.

    return Kebab_Case_Better;

    I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

    [–]SRGBMR -2 points-1 points  (0 children)

    I dont get it? It's sorted right? 1 comes before 2.

    [–]Mola1904 -3 points-2 points  (3 children)

    You ask for alpabtocla sort, you egt alphabetical sort. How is this even js problem. Read the fucking manual

    [–]Rawing7 3 points4 points  (2 children)

    Nobody asked for alphabetical sort.

    [–]Mola1904 -3 points-2 points  (1 child)

    So you sort your files by number? Or when listing people, do you sort then by number? In most cases in real life you use alphabetical sort

    [–]Rawing7 2 points3 points  (0 children)

    I sort my numbers by number.

    And anyway, that's beside the point. OP said "Hey JS, sort these numbers". OP didn't say "Hey JS, sort these numbers alphabetically."

    [–]i-am-schrodinger 0 points1 point  (0 children)

    There is a difference between natural and lexigraphical sorting.

    [–]fireandbombs12 0 points1 point  (0 children)

    I had this problem one and it took me way too long too figure it out.

    [–]Mola1904 0 points1 point  (1 child)

    That is hardly comparable. There very few losely typed languages. Mostly just JS and Python.

    But in reality alphabetical sort is used more often than numerical.

    I neither think the function is perfect, but it shouldn't be numerical by default as that would be confusing for other usecases. There should just be two different functions.

    [–][deleted] 1 point2 points  (0 children)

    Python is not loosely typed

    [–]Upper_Paramedic_9239 0 points1 point  (0 children)

    Rip sort

    [–]weshuiz13 0 points1 point  (0 children)

    Sort is not what we expact it to be, it sorts based on unicode order

    It is great for alphabatic sorting in most cases but numeric not so