static interface

Bill Baxter wbaxter at gmail.com
Mon Nov 16 15:42:42 PST 2009


On Mon, Nov 16, 2009 at 9:25 AM, Leandro Lucarella <llucax at gmail.com> wrote:

This topic is actually very close to a discussion last week about
retrieving error messages from failures of __traits(compiles, xxx).

My question is: is it really that much of an improvement?

I've rearranged your code to see the equivalent snippets side-by-side:

> static interface InputRange(T) {
>        bool empty();
>        T front();
>        void popFront();
> }


> template isInputRange(R)
> {
>    enum bool isInputRange = is(typeof(
>    {
>        R r;
>        if (r.empty) {}
>        r.popFront;
>        auto h = r.front;
>    }()));
> }

There's actually not that much difference here.  Of course we would
like several general improvements that have been discussed before:
1) some kind of template 'this' so we don't have to repeat the template name.
2) something better than is(typeof()) (or __traits(compiles, ...)) to
check if code is ok. [hoping for meta.compiles(...)]

In some ways the current code is better, because it actually checks if
a construct works or not, rather than requiring a specific function
signature.  Whether the code will work is really the minimal
restriction you can place on the interface.  A specific may be too
tight.  For instance, above you don't really care if empty returns
bool or not.  Just if you can test it in an "if".

>
> struct Stride(T): InputRange(T) {
>        // implementation
> }
>

> struct Stride(T) if (isInputRange!(T)) {
>        // implementation
> }

There's really not a significant difference in those two.


> size_t walkLength(InputRange range, size_t upTo = size_t.max)
> {
>        // implementation
> }

> size_t walkLength(Range)(Range range, size_t upTo = size_t.max)
> if (isInputRange!(Range))
> {
>        // implementation
> }

Here is the only one where I see a significant improvement.  Basically
that all comes from not having to repeat yourself.
So maybe we'd be better off attacking that repetitiveness directly.

But in terms of functionality it seems we cover pretty much everything
static interface gives you.
The only exception may be that static interfaces could give you better
error messages about why your type doesn't satisfy the requirements.
That's where better ways to get the error messages from
__traits(compiles,...) errors come in.  But it's harder to make that
useful in D without giving up overloading.  In D if T doesn't satisfy
isInputRange!(T), it might satisfy some other overload of the
template.

--bb



More information about the Digitalmars-d mailing list