I've just fixed UFCS for the experimental type function branch

H. S. Teoh hsteoh at quickfur.ath.cx
Fri Sep 11 14:54:33 UTC 2020

On Fri, Sep 11, 2020 at 11:54:20AM +0000, Paul Backus via Digitalmars-d wrote:
> Yeah, that's basically the traits/typeclasses approach: you commit to
> a particular set of constraints, and the compiler checks your generic
> code against them *prior* to instantiation with any particular type
> (or "monomorphization," as the Rustaceans call it).
> The main downside is that you can't do design-by-introspection. Once
> you commit to a typeclass, its interface is all you get.

Not necessarily.  You can accept the most general type class in the sig
constraints (or omit it altogether), and introspect in the function

To take it a step further: what if you can progressively refine the
allowed operations on a template argument T within the template function
body?  To use your example of InputRange vs. RandomAccessRange: the
function declares it accepts InputRange because that's the most general
class. Then within its function body, it tests for RandomAccessRange
with a static if, the act of which adds random access range operations
on T to the permitted operations within the static if block.  In a
different static if block you might test for BidirectionalRange instead,
and that would permit BidirectionalRange operations on T within that
block (and prohibit RandomAccessRange operations).

This way, you get *both* DbI and static checking of valid operations on
template arguments.


Don't modify spaghetti code unless you can eat the consequences.

More information about the Digitalmars-d mailing list