On Tuesday, 4 February 2014 at 02:04:55 UTC, Chris Williams wrote:
And of course, even being able to read it, one would still need to track down isInputRange() and isImplicitlyConvertible() to know what they do.

Having to know what a particular concept does is pretty much the same as having to know what an interface does. Even so, `isImplicitlyConvertible` should be intuitive to programmers with some experience in any statically typed language.

2. When using classes and interfaces, type checking is as simple as writing the type to be passed in as a parameter. With struct-typing, people need to manually append a series of checks all over the place, which results in things like the following:

auto uniform(T, UniformRandomNumberGenerator)(ref UniformRandomNumberGenerator urng) if (!is(T == enum) && (isIntegral!T || isSomeChar!T));

Even though isUniformRNG() exists and is used on other implementations of uniform(), it isn't used here, because whoever developed the function forgot to include it on this particular function.

Repeatedly needing to check for something nameless yet specific like what the above does, is probably cause for introducing a new concept.

I'll admit that getting constraints right is difficult, because it's impossible to unit test whether an error happened because of an immediate resolution failure or something else. We need some improvement here if we want to keep aiming for tight constraints.

3. Non-extensible. To "extend" an SList or whatever, I would have to write a wrapper class with methods that forward to the SList methods, if I wanted my object to be able to interoperate with Phobos, or I would need to modify Phobos so that the body of SList was a template that could be mixed in (assuming I didn't want to override any methods, just add new ones).

Use UFCS to add new methods.

Reply via email to