On Tue, Nov 17, 2009 at 5:51 AM, Leandro Lucarella <llu...@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 <llu...@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