On 02/03/2011 02:25 PM, Lars T. Kyllingstad wrote:
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

Done!
(I did not get all the details 'cause no time for a deep look, but anything impulsed by the motivation of getting rid of is() and __traits can hardly be a Bad Thing ;-)

What do you think of type classes, as an alternative to Don's proposal in issue #3702.
See also "Type Classes as Objects and Implicits":
http://ropas.snu.ac.kr/~bruno/papers/TypeClasses.pdf

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

A great improvement, indeed.

While we're at defining a set of constraints in a template, let us make it an interface / type-class that the E must (structurally) satisfy, and just write:
    void func(InputRange!E R)(R range) { ... }

What do you think?

Note: a template is not always required, I guess:
    void writeElements (Iterable Elements) (Elements elements) {
        foreach (element, elements) {
            write(element,' ');
        }
    }
(In this case, because write is itself generic.)

Denis
--
_________________
vita es estrany
spir.wikidot.com

Reply via email to