November 16, 2009 Re: static interface | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | Jesse Phillips, el 16 de noviembre a las 13:19 me escribiste: > Is there a reason not to have all interfaces compile time checked? It would still be allowable to state a class implements an interface and have the compiler check it. > > The reason I say this is it would remove the complexity of having the two types of interfaces. And if you wanted to be able to check for the interface at run-time the same interface can be used. The problem is "regular" interfaces provide dynamic dispatch. Andrei could implement all the range stuff using interfaces, but that would mean: 1) You have to inherit from the interface (i.e., you can't use arrays) 2) All calls to ranges functions are virtual (inefficient; this is particularly relevant since they are called inside loops => lot of times) A static interface don't have those problems, and I don't see a way to mix static and dynamic interfaces without introducing a "new" type of interfaces (static interface). -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Si pudiera acercarme un poco más, hacia vos Te diría que me tiemblan los dos pies, cuando me mirás Si supieras todo lo que me costó, llegar Hoy sabrías que me cuesta respirar, cuando me mirás | |||
November 16, 2009 Re: static interface | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu, el 16 de noviembre a las 12:19 me escribiste: > grauzone wrote: > >Leandro Lucarella wrote: > >>Why not? ;) > > > >The actual question is if Andrei/Walter are interested at all in this. Because they didn't show any interest so far. D will probably be doomed to compile time bug-typing I mean duck-typing forever. > > There's an embarrassment of riches when it comes to finding stuff to work on for D2. I think we need to resign ourselves to the idea that we need to focus only on one subset of the stream of good ideas that are being proposed. I completely agree and understand. I wish I had the time to make patches myself for the things I propose. But it's very different if something is not implemented because it sucks or just because the lack of men power :) If some good feature has Walter's blessing, maybe other person can implement it. Nobody wants to implement something if it doesn't have Walter's blessing, because we all know he's very tough to convince, and nobody wants to work on something it won't get accepted. > FWIW I was keen on structs interacting in interesting ways with interfaces (and submitted a number of enhancements in that directions) but then realized there are a number of problems that structs/interfaces cannot solve. I believe that a better path to pursue in checking interface conformance is via reflection. But that's very laborious, to be honest, I saw some points in std.range that would be hard to cover with static interfaces, but for those things you have all the flexibility you're already using. But static interfaces could cover a wide range of applications, making static duck-typing very easy to use. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Breathe, breathe in the air. Don't be afraid to care. Leave but don't leave me. Look around and choose your own ground. | |||
November 16, 2009 Re: static interface | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Leandro Lucarella | On Mon, Nov 16, 2009 at 9:25 AM, Leandro Lucarella <llucax@gmail.com> wrote:
> Why not? ;)
>
> I know you might want to hit me for bringing just another feature request inspired in Google's Go, but please do read it without preconceptions, because I think the features I'm suggesting are mostly already in D, but in a less convenient way.
I, for one, think these are great things to talk about.
Even if it's decided that it's a bad idea for D to get such a feature,
then as many people as possible should know that reason so we can talk
intelligently about why D does things the way it does. Because if
we're asking ourselves why D doesn't have X, you can bet there are
others who will wonder the same when they see D.
--bb
| |||
November 16, 2009 Re: static interface | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Leandro Lucarella | Leandro Lucarella wrote: > Andrei Alexandrescu, el 16 de noviembre a las 12:19 me escribiste: >> grauzone wrote: >>> Leandro Lucarella wrote: >>>> Why not? ;) >>> The actual question is if Andrei/Walter are interested at all in >>> this. Because they didn't show any interest so far. D will >>> probably be doomed to compile time bug-typing I mean duck-typing >>> forever. >> There's an embarrassment of riches when it comes to finding stuff to >> work on for D2. I think we need to resign ourselves to the idea that >> we need to focus only on one subset of the stream of good ideas that >> are being proposed. > > I completely agree and understand. I wish I had the time to make patches > myself for the things I propose. But it's very different if something is > not implemented because it sucks or just because the lack of men power :) > > If some good feature has Walter's blessing, maybe other person can > implement it. Nobody wants to implement something if it doesn't have > Walter's blessing, because we all know he's very tough to convince, and > nobody wants to work on something it won't get accepted. What I can tell is that Walter's keenness on adding/changing something has a 10-fold improvement if a patch is present. For example Walter was sort of ambivalent about opDollar and opDollar!(dim)() until Don simply added it. >> FWIW I was keen on structs interacting in interesting ways with >> interfaces (and submitted a number of enhancements in that >> directions) but then realized there are a number of problems that >> structs/interfaces cannot solve. I believe that a better path to >> pursue in checking interface conformance is via reflection. > > But that's very laborious, to be honest, I saw some points in std.range > that would be hard to cover with static interfaces, but for those things > you have all the flexibility you're already using. But static interfaces > could cover a wide range of applications, making static duck-typing very > easy to use. There's a saying that most all girls may look good in the dark. Paraphrasing that, I'd say all language features look nice and easy when (a) detail is not discussed, (b) all the rest of the language is assumed to be mastered. There are places in D where we can't do what we want to do. Those are top priority. Those that do easier what we can do anyway (struct mixins, static interfaces, even the better switch which I actually personally like) are below top priority. The barrier is fuzzy because either I, Walter, or Don may suddenly catch fancy to a specific thing to work on, but I wish we were more, not less disciplined about that. Andrei | |||
November 16, 2009 Re: static interface | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Leandro Lucarella | On Mon, Nov 16, 2009 at 9:25 AM, Leandro Lucarella <llucax@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 | |||
November 17, 2009 Re: static interface | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | Bill Baxter wrote:
> On Mon, Nov 16, 2009 at 9:25 AM, Leandro Lucarella <llucax@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".
Another, related way in which the current code is better is that it doesn't care whether empty, front, and popFront are functions or variables. As we know, the standard trick for infinite ranges is to declare empty as an enum, not a function.
BTW, I find it interesting that I see meta.* being mentioned in discussions and even used in code snippets all over the NG these days. It seems to be a popular proposal. I hope it gets implemented too. :)
-Lars
| |||
November 17, 2009 Re: static interface | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | Bill Baxter, el 16 de noviembre a las 15:42 me escribiste: > On Mon, Nov 16, 2009 at 9:25 AM, Leandro Lucarella <llucax@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*. 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. > 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 =) Again, this proposal is about what I say in the previous paragraphs. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- Be nice to nerds Chances are you'll end up working for one | |||
November 17, 2009 Re: static interface | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Lars T. Kyllingstad | Lars T. Kyllingstad, el 17 de noviembre a las 09:54 me escribiste: > >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". > > Another, related way in which the current code is better is that it doesn't care whether empty, front, and popFront are functions or variables. As we know, the standard trick for infinite ranges is to declare empty as an enum, not a function. Is not that hard to write: bool empty() { return false; } instead of enum bool empty = false; > BTW, I find it interesting that I see meta.* being mentioned in discussions and even used in code snippets all over the NG these days. It seems to be a popular proposal. I hope it gets implemented too. :) We all do ;) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------- FALTAN 325 DIAS PARA LA PRIMAVERA -- Crónica TV | |||
November 17, 2009 Re: static interface | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Leandro Lucarella | Leandro Lucarella wrote:
> Lars T. Kyllingstad, el 17 de noviembre a las 09:54 me escribiste:
>>> 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".
>> Another, related way in which the current code is better is that it
>> doesn't care whether empty, front, and popFront are functions or
>> variables. As we know, the standard trick for infinite ranges is to
>> declare empty as an enum, not a function.
>
> Is not that hard to write:
> bool empty() { return false; }
> instead of
> enum bool empty = false;
That's why I mentioned infinite ranges. An infinite range is *defined* as a range where empty is implemented as
enum bool empty = false;
isInfinite(Range) tests whether this is the case, which it wouldn't be able to do if empty() was a function.
-Lars
| |||
November 17, 2009 Re: static interface | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Leandro Lucarella | == Quote from Leandro Lucarella (llucax@gmail.com)'s article
> Lars T. Kyllingstad, el 17 de noviembre a las 09:54 me escribiste:
> > >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".
> >
> > Another, related way in which the current code is better is that it doesn't care whether empty, front, and popFront are functions or variables. As we know, the standard trick for infinite ranges is to declare empty as an enum, not a function.
> Is not that hard to write:
> bool empty() { return false; }
> instead of
> enum bool empty = false;
Yes, but there's a reason to use enum: This convention enables compile time introspection as to whether the ranges are infinite. It's also more efficient when inlining is disabled.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply