|Posted by H. S. Teoh|
in reply to Dom DiSc
Posted in reply to Dom DiSc
On Fri, Jan 14, 2022 at 04:19:42AM +0000, Dom DiSc via Digitalmars-d wrote:
> On Friday, 14 January 2022 at 03:41:49 UTC, H. S. Teoh wrote:
> > No, they are not inherently orderable, the orderings you mentions are external orders imposed on them.
> Nothing is inherently ordered. The order is always some new property given to the object in question. Numbers are nothing then a (unordered) set plus an order given to them (an axiom on its own). The order is never "inherent" and there are always endless different ways to assign an order to a set of objects.
Now you're just splitting hairs. Number types in a *programming language* (we're not talking about abstract mathematics here) are inherently-ordered types. This is why `1 < 2` always evaluates to true, and `2 < 1` always evaluates to false in D. It makes no sense to impose a different ordering on the ints themselves. But in a list of numbers, you *can* order them by a different ordering, e.g., if they represent indices into some other orderable object. Such non-default orderings, though, do not belong to the int type itself. They are external orderings imposed upon ints that are not its inherent ordering.
Many classes don't an inherent ordering, because there isn't any single ordering that makes the most sense for objects of that class. Objects like File can have any number of different orderings imposed on them -- order by size, by name, by creation time, by last access time, etc., precisely because a file itself isn't inherently ordered w.r.t another file. These are all external orderings, and therefore do not belong to File.opCmp. Instead, they should be predicates that the user can choose when sorting a list of File objects.
Since most classes don't have an inherent order, it doesn't make sense to assume they do, which is what we're doing when we put .opCmp in the base class of all classes. Since only a subset of classes are inherently ordered, it makes more sense to put .opCmp in either a subclass or an interface that derived classes can derive from.
> The important part is: it is mostly useful to do so (assigning a specific order to a set of objects), thereby making from a set an ordered set. And especially on computers a set always need at least some "default" order (e.g. address), otherwise you cannot access its elements.
This is a nonsensical argument. So the default order of every data type should be its address? You don't need .opCmp for that, just cast the pointer and compare its value. Every object already has an address, there is no need to spend a vtable slot for this.
The whole issue here is, does *every* class you can conceivably define in D need to have an .opCmp method? The answer is no, you don't. If you want to sort some objects by some order, you can always pass a predicate to std.algorithm.sort. If you have some classes that are inherently ordered and therefore could benefit from sharing a common .opCmp method, then inherit them from an Orderable base class or Orderable interface. There is no need for the base class of every class in the language to assume that every subclass needs an .opCmp.
> But I agree that it is useful to have a way to assign some predicate to a class by which its instances should be ordered (at least if you don't like the default order: the memory address where it is stored), but that need not be a member function, so I omitted it.
Well yes, which is exactly the point: most classes *don't need* an .opCmp -- you can just pass a predicate. The classes that could benefit from .opCmp are a subset of all classes, therefore they should inherit from a common Orderable base class or interface. So .opCmp doesn't belong in the base class of all classes in the language. QED.
Marketing: the art of convincing people to pay for what they didn't need before which you fail to deliver after.