> And whilst it is true to say that these IDs will consistently sort in the same order, that is equally true of standard GUIDs etc
GUIDs do not have a consistent sort order: https://devblogs.microsoft.com/oldnewthing/20190426-00/?p=10...
> the difference being the latter does not lead people to believe that the order has inherent meaning, which the former does.
That's mostly an accident of v4 UUIDs becoming the most common. v1 GUIDs had plenty of metadata with lots of semantic data in them that had all sorts of inherent meaning in the sort orders. That's part of why there are so many different ways to sort UUIDs in the first place (with again the above blog post being one of the best discussions on it). v1 GUIDs had machine identifiers and tried to be total orderable in distributed systems. It didn't work out well, there were privacy issues with the machine identifiers, and everyone switched to random v4 UUIDs. (That's relevant in discussions of the v6+ UUIDs which are trying to get back to partially semantically meaningful UUIDs again.)
The obvious counter-example to the Go example to me is Python: python dict (which also powers most "ordinary" python objects) had years of implementation behavior where keys were generally sorted lexicographically. It was undocumented behavior for many years and expected to change if the underlying implementation changed and people were directed towards SortedDict if they needed a dict with a reliable sort.
Python eventually decided to just document the implementation behavior and make it assumed that dict will generally behave with sorted keys, but also still suggests SortedDict for apps that need that guarantee of a total order. Reliable partial order is "good enough" for a lot of programs and a lot of algorithms.
> Something is either reliably sortable or it is not sortable at all.
ULIDs are reliably sortable, they just aren't a total order with respect to monotonic time and distributed clocks. I'm not discounting that there are needs for monotonic time and distributed clock coordination and such not, but I do think it's a bridge much further down from what ULIDs are trying to do.
ULIDs are "UI stable" for sorting: if you've got a UI that shows data as it comes in and sorts by ULID keys the amount of "UI jiggle" is about as low as possible. You are still going to get "middle inserts" in between previous loaded items in a way that a user will sometimes notice, but not in a way that thrashes the UI or drastically changes the viewport. That's a sometimes useful property. (For more things than just UIs, but UIs are easy to visualize. It can also be a useful property in data locality/clustering in DB indexes as something that has been a sorting need in projects I've worked on, across several different kinds of database.)
You all are right, you can't rely on that if you've got a stateless backend whose operations only strictly rely on if the key is greater than the last key they saw on whether or not they have new data to work on. If that is your use case, you need something that isn't ULID. That's not a lot of applications' use case. I think where we are most disagreeing is that you all seem to think that that is an eventual use case for all applications, and in my experience it is much more rare and you have other problems than what style of IDs you are using by the time you get there. For what it is worth, ULIDs have been a reasonable compromise for my applications' needs versus total orderable things like Thrift/Snowflake/et al. They make a great replacement for v4 UUIDs, which are still the default "golden child" among a certain class of dark matter Enterprise developer. That's fine if those aren't uses that you have, I'm saying those are uses that have a lot of applications.