template constraints when non-constrained template exists

Manu via Digitalmars-d digitalmars-d at puremagic.com
Mon Oct 5 04:05:42 PDT 2015


On 5 October 2015 at 20:30, Jonathan M Davis via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> On Monday, 5 October 2015 at 10:17:06 UTC, Manu wrote:
>>
>> On 5 October 2015 at 18:26, Jonathan M Davis via Digitalmars-d
>> <digitalmars-d at puremagic.com> wrote:
>>>
>>> In general, the traits in std.traits are designed to match an exact set
>>> of built-in types and that's it. And code using them is going to rely on
>>> that, making overloading them very risky IMHO.
>>
>>
>> I don't think it's risky, I think it should be expected. Surely a type
>> which has a concept of 'isSigned' should respond accordingly to the standard
>> introspection tools? It would be the responsibility of the author of a
>> fully-featured library to make sure this works.
>
>
> These traits were written and documented as only working with built-in
> types. Changing that now could easily mean that existing code would would
> then allow user-defined traits passed template constraints on templates that
> will not work with user-defined types - especially when you consider that
> these traits could be combine with other traits to restrict what's accepted
> to a fairly specific subset.
>
> If these traits had be designed from the get-go with the idea that they
> would work with any user-defined type that met certain criteria, then that
> would be different, but they weren't.

So... they may be subject to new bug reports when the constraints are lifted?

> Also, I think that a trait which _was_ supposed to work with user-defined
> types would have to be very carefully written. This very quickly gets into
> the camp where implicit conversions sit, and those can be _really_ bad for
> template constraints, because it's very easy to write a template constraint
> that accepts implicit conversions and then end up with a template that works
> with the target type but does not actually work with the types that
> implicitly convert to it. They have their place, but you have to be very
> careful with them.

Extending a trait would only happen in the context that the module
that extends it is also made present within the same scope; ie,
`import std.traits, saturatingint;`
With that in mind, it's pretty unlikely you'd have weird hijackings
and incompatibilities appearing all over the place since the import
statement pretty much makes your intent to use a thing clear.

> It probably does make sense to declare some traits designed to work with
> both the built-in types and user-defined types for some of these arithmetic
> operations, but I expect that they would have to be written very carefully
> to avoid problems, and I don't think that it makes sense to change the
> existing traits to work that way. I would be very surprised if such a change
> did not break existing code.
>
> - Jonathan M Davis

I am personally yet to give a single f... care, when any change that
makes D better also breaks code. And that includes the time when I was
maintaining a reasonably substantial codebase used commercially.
D is not finished yet, not by a long shot. I'm so bored of this
excuse, it's predictable and seriously tiring. (not from you
specifically, it comes from all angles)

But anyway, what do I do? I need to inject one of these types into a
tree which uses std.traits.
This demonstrates a fairly serious scalability problem. It's come up
quite some number of times for me.

D is all about composition, D is all about duck typing. I'm doing
exactly the sort of thing that modern idiomatic D encourages you to
do.
This isn't an acceptable end-of-the-story, but I'll leave it here, and
other people can decide what's right.


More information about the Digitalmars-d mailing list