static interface

Bill Baxter wbaxter at gmail.com
Tue Nov 17 06:40:59 PST 2009


On Tue, Nov 17, 2009 at 5:51 AM, Leandro Lucarella <llucax at gmail.com> wrote:
> Bill Baxter, el 16 de noviembre a las 15:42 me escribiste:
>> 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".
>
> I think one could argue if being more restrictive is actually good or bad.
> Being more restrictive cold lead to less errors. Maybe if a struct empty()
> method returns, say, a pointer, I don't want to think it is *really*
> a range. Maybe that method is doing a lot of work and removing stuff, and
> then returning a pointer to some removed stuff. Anyway, I'm not saying
> that that couldn't happen even if empty() return bool (that's a risk when
> duck-typing, always :), I'm just saying I'm not so sure that being more
> restrictive is really a *bad thing*.

If that's what you want, the D way gives you the option of checking

       is(typeof(R.empty)==bool)

But yeh, that is klunkier than just writing out the function signature
you're expecting.


> And about what's nice or ugly, I agree the current way of doing stuff is
> not too bad, there are a few details that are not *that* nice. But with
> duck-typing I think the same that with tuples: those little details makes
> you feel that D doesn't support the concept so well, and make people
> resistant to use them. When something feels natural in a language, you use
> it all the time, for me, the current way to do tuples and duck-typing
> looks very artificial and harder than it should.

Agreed.  But as for the duck typing aspect, I think there isn't
necessarily an either-or choice here.
For instance, in D, we could allow a static interface to have a static
assert block:

     static interface InputRange(T) {
         static assert (meta.compiles({
               if (this.empty) {};  // this is a shortcut for T.init
         }));
         T front();
         void popFront();
      }

Or something like that.  "Invariant {}" might be better there.

>> But in terms of functionality it seems we cover pretty much everything
>> static interface gives you.
>
> I know that, I started this proposal just saying that =)

Ah.  Sorry, I missed that comment.

--bb



More information about the Digitalmars-d mailing list