For me, ruby is full of a lot of little conveniences that shouldn't necessarily be used in production systems. I always cry loud that code should be quickly "scannable", and the data-structures we choose to use can help a lot in the quicker understanding an unfamiliar piece of code.
But I stress again: these types of decisions are best left up to the team or org. It's ultimately low-stakes.
That ship has sailed - it was partly for the convenience of debugging, but the general purpose dict is now ordered.
It's only by insertion order - it's expensive to change the order - but the order can by relied upon and is being used.
Edit: some detail on changing the order - you can either remove all the key/value pairs up to the first one you want to change and add them back, or you can create a new dict with the pairs in the desired order. With Rust you can choose whether or not to have insertion order preserved https://stackoverflow.com/questions/42723065/how-to-sort-has...
I don't feel it's arbitrary, though, and to get a little clever about it I feel that ordered hashes are arbitrary and that's why I don't like to rely on it in _production_ code.
"Records" (aka hashes, aks dicts, aka maps, etc) are inherently unordered. Relying on insertion order or keyed values is super brittle.
So again, the fact that they are ordered is super convenient! It shines in one-off, temporary situations like debugging or writing a quick script to group something by a specific value without having to do any further sorting. But I don't believe it should ever be replied on in a production system, just for the fact that if the order ever changes, there are possibly many places that have to change.
If it was sorted by a criteria of my choosing, sure. But I don't know when I last cared about insertion order...
Even for singly linked lists, implementations for general purpose use usually keep pointers to the first and last elements so that you can use it as an O(1) FIFO queue, as well as prepend in O(1) time.
If you only keep a pointer to the head of the linked list, then it can be practically used a LIFO queue (stack), and a few other corner cases, but not much else. (A FIFO isn't very useful if adding an item is O(1) but removing an item is O(N), or vice versa.)
Clojure 1.11.1
user=> (first [])
nil
user=> (first {})
nil
user=> (last [])
nil
user=> (last {})
nil
user=> Clojure 1.11.1
user=> (first {:one 1 :two 2})
[:one 1]
user=> (last {:one 1 :two 2})
[:two 2]