the meaning is the same high level: it has side effects, being it a destructive update, an in place operation or throwing an exception.
> `sorted` is a general function that gives you a sorted list from any iterable
iterable in Python is a very loose concept though.
And it's not very consistent too
sorted("gheliabciou")
['a', 'b', 'c', 'e', 'g', 'h', 'i', 'i', 'l', 'o', 'u']
you give it a str it returns a list of charin Ruby it makes much more sense
"gheliabciou".chars.sort.join
"abceghiilou"
You take out the chars from the string, sort them and then join them together againbecause a string cannot be sorted, sorting a string makes no sense, you sort the chars composing it.
Also, Python could not do this for many years, while Ruby could no prob
sorted("gheliabciouß⌚⌨⌛🆔🉑🈶🈚🈸🈺🈷🆚🉐㊙㊗🈴")Edit: ok, some do and some don’t. 🈶 is allowed but :laugh_with_tears: isn’t. I guess there’s a specific list of emojis that are getting stripped.
In that way `sorted` _is_ totally consistent - it always takes an iterable and returns a list of the elements. If we can't agree on that then I don't think there's much of a discussion to be had here.
except Iterable is the wrong "interface"
in Python it is defined as
> An iterable is any Python object capable of returning its members one at a time, permitting it to be iterated over in a for-loop.
which is not always what you want for sorting
quicksort doesn't work one element at a time
so basically you have to extract all the elements before sorting them
what about infinite streams?
At least Ruby Enumerable mixins explicitly states that
> The Enumerable mixin provides collection classes with several traversal and searching methods, and with the ability to __sort__.
Another problem with sorted is that it accepts any iterable, true, returning a list of items, but it is not clear how you can tell if the object is an iterbale or not
>>> sorted(123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
ok >>> isinstance(123, iterable)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'iterable' is not defined
mmmmmaybe it's because int is not iterable?
>>> isinstace("abc", iterable)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'iterable' is not defined
so the solutions are # fails for strings in Python 2
>>> try:
_ = iter(some_object)
except TypeError as te:
print('is not iterable')
or # if 2.6 >= Python < 3.3
from collections import Iterable
# if Python >= 3.3
from collections.abc import Iterable # <- personal note, abc stands for...? core maybe?
# no idea on how to do it in Python < 2.6
>>> isinstance("abc", Iterable)
True
not only it's very ugly, but it can also fail in mysterious ways. As per documentationChecking isinstance(obj, Iterable) detects classes that are registered as Iterable or that have an __iter__() method, but it does not detect classes that iterate with the __getitem__() method. The only reliable way to determine whether an object is iterable is to call iter(obj).
while in Ruby it's straightforward
[3] pry(main)> [1, 2].is_a? Enumerable
=> true
[4] pry(main)> "abc".is_a? Enumerable
=> false
[5] pry(main)> "abc".chars.is_a? Enumerable
=> true
In the Python case, `list.sort()` operates on the object, so you can kind of expect it to do mutation (but there's no convention / guarantee). Though it only makes sense as a function that the list object itself implements.
`sorted` is a general function that gives you a sorted list from any iterable, and because working with iterables is such a common thing in software, Python has a bunch of standard functions like that. It's nice because you learn them once and they apply absolutely everywhere.
Ultimately you learn the behaviours of a language and they become second nature. I find both Ruby and Python very clean and easy to read.