higher-order funcs for ranges (with usual interface)

Lars T. Kyllingstad public at kyllingen.NOSPAMnet
Thu Feb 3 05:25:16 PST 2011


On Thu, 03 Feb 2011 13:53:44 +0100, spir wrote:

> On 02/03/2011 01:17 PM, Lars T. Kyllingstad wrote:
>> Why the reluctance to use template constraints?  They're so flexible!
>> :)
> 
> I cannot stand the "is()" idiom/syntax ;-) Dunno why. Would happily get
> rid of it in favor of type-classes (built eg as an extension to current
> interfaces). For instance, instead of:
> 
>      void func (T) (T t)
>          if (is(someConstraint1) && is(someConstraint2))
>      {
>          ...
>      }
> 
> use:
> 
>      void func (SomeTypeClass T) (T t)
>      {
>          ...
>      }
> 
> For instance (untested):
> 
>      void func (T) (T t)
>          if (isInputRange(T) && is(ElementType!T == E))
> -->
>      void func (InputRange!E T) (T t)
> 
> where InputRange is a (templated) interface / type-class.
> 
> Type-class checks on /type/ /template/ parameters (as opposed to type
> checks on regular value parameters) would be performed structurally (as
> opposed to nominally). D knows how to do this, since that's what it
> needs to perform when checking is() constraints.

I agree that is() is rather ugly.  Same with __traits.  If you haven't 
already done so, I suggest you vote up this issue:

  http://d.puremagic.com/issues/show_bug.cgi?id=3702

Anyway, you can hide is()'s ugliness in the most common cases, though, by 
defining new templates.  For instance, I wouldn't mind having the 
following in std.range as an overload of isInputRange:

  template isInputRange(R, T)
  {
      enum isInputRange = isInputRange!R && is(ElementType!R == T);
  }

Then, you'd simply write

  void func(R)(R range) if (isInputRange!(R, E)) { ... }

-Lars


More information about the Digitalmars-d-learn mailing list