Ruby does that. From [1] "[Array#join] Returns a string created by converting each element of the array to a string, separated by the given separator."
The difference is that nil (Ruby's None) disappears
Either way it's a partial function that is not defined for most of its domain. The only difference is how its arguments (including self) get arranged at call sites, right?
That happens all the time, since Python is dynamically typed. For example a[10] gives an IndexError if a has less than 11 elements. So with static typing, we should restrict indexing to ensure that the number of elements needed are present, and remove indexing from general lists. But you wouldn't remove indexing from lists, that's one of the main functions...
the key difference is that in ruby, `join` is implemented in the `Enumerable` mixin (which provides a whole suite of functionality to any object with an `each` method). if your own class wants to support `join`, it has to both implement `each` and explicitly mix in `Enumerable`.
in python, `join` is implemented in the `string` class, and the argument is an iterable. therefore, if your class wants to support `join`, it needs to implement the `__iter__` method (python's equivalent of ruby's `each`), but it does not need to also mix in an implementation of `join`.
it's mostly a cultural difference between ruby and python - the ruby ecosystem leans more heavily towards mixins and implementing generic functionality by attaching methods to objects, whereas the python ecosystem leans more heavily towards implementing generic functionality by providing functions (or methods on an external class) that accept generic objects.
A class that wants to support join has to implement to_s. The definition of join is
> join(separator=$,) → str
> Returns a string created by converting each element of the array to a string, separated by the given separator. If the separator is nil, it uses current $,. If both the separator and $, are nil, it uses an empty string.
If the class doesn't implement to_s Object.to_s kicks in and displays something like "#<SomeClass:0x000055a321fa2bb0>"
split was the clear winner here. Given splitBy, I basically recreated split as a lambda.
I tried to create an analog to that where splitBy would come out looking better. I figured that if we didn't know the dimensionality of our data, then delimiters becomes an array of arbitrary length and we could pass data.!splitBy into something like delimiters.reduce. When actually writing that, however, I wound up recreating split again:
Because when the Javascript engine will try to concatenate all the strings in the Array (the expected behavior of join), it will first translate every object in the array to a string.
Javascript always falls back to string, that is also why we have === and == operators.
Python's type system is a bit more strict because it will not attempt to serialize your objet if you haven't explicitly done it yourself.
My point is: Python doesn't use this notation because it would not make sense in Python.