February 18, 2013 Re: Purity, @safety, etc., in generic code | ||||
---|---|---|---|---|
| ||||
On Sunday, February 17, 2013 20:44:29 H. S. Teoh wrote: > The thing is, AFAIK, there's no way to express "this function is pure if ElementType's opEquals is pure", ditto for const, @safe, etc.. It's all or nothing: either you force all element types to implement every qualifier, or you get none at all, even if *most* instantiations actually can get them all. Furthermore, there's currently no sane way to vary qualifiers at compile-time (so that one could, say, use static if to enable/disable qualifiers depending on what is supported). @safe, pure, and nothrow are supposed to be inferred for templated functions. _That_ is how the @safe, pure, nothrow problem was supposedly solved. This works in some cases, but last time I checked was very buggy overall. For instance, IIRC, if it was the struct that was templated, none of its member functions had their attributes inferred like they were supposed to (I'd have to go digging through bugzilla to see what the exact set of currenly reported inferrence bugs is though). So, I think that the problem is essentially solved for @safe, pure, and nothrow as long as the implementation issues get solved. Now, as for const, I don't think that the problem has been solved yet. We really need some sort of inferrence there, which is why a number of months ago I created this enhancement request for inferring inout: http://d.puremagic.com/issues/show_bug.cgi?id=8407 AFAIK though, no one's even looked at it, so I don't think that it's had any effect as of yet. One of the compiler devs will need to take it up for it to make it in. - Jonathan M Davis |
February 18, 2013 Re: Purity, @safety, etc., in generic code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 2/17/2013 9:23 PM, Jonathan M Davis wrote:
> So, I think that the problem is essentially solved
> for @safe, pure, and nothrow as long as the implementation issues get solved.
Yup, I believe that for templates using inference is the way to go. Currently, dmd does a rudimentary job of it, much improvement is possible.
|
February 18, 2013 Re: Purity, @safety, etc., in generic code | ||||
---|---|---|---|---|
| ||||
On Sun, Feb 17, 2013 at 09:23:44PM -0800, Jonathan M Davis wrote: > On Sunday, February 17, 2013 20:44:29 H. S. Teoh wrote: > > The thing is, AFAIK, there's no way to express "this function is pure if ElementType's opEquals is pure", ditto for const, @safe, etc.. It's all or nothing: either you force all element types to implement every qualifier, or you get none at all, even if *most* instantiations actually can get them all. Furthermore, there's currently no sane way to vary qualifiers at compile-time (so that one could, say, use static if to enable/disable qualifiers depending on what is supported). > > @safe, pure, and nothrow are supposed to be inferred for templated functions. _That_ is how the @safe, pure, nothrow problem was supposedly solved. Oh? So you're saying that templated functions shouldn't need any attributes, because they will be inferred? > This works in some cases, but last time I checked was very buggy overall. For instance, IIRC, if it was the struct that was templated, none of its member functions had their attributes inferred like they were supposed to (I'd have to go digging through bugzilla to see what the exact set of currenly reported inferrence bugs is though). So, I think that the problem is essentially solved for @safe, pure, and nothrow as long as the implementation issues get solved. It would be nice if we could work on this. One of D's major selling points right now is its metaprogramming features; but that is a bit tarnished by the poor attribute inference. > Now, as for const, I don't think that the problem has been solved yet. We really need some sort of inferrence there, which is why a number of months ago I created this enhancement request for inferring inout: > > http://d.puremagic.com/issues/show_bug.cgi?id=8407 > > AFAIK though, no one's even looked at it, so I don't think that it's had any effect as of yet. One of the compiler devs will need to take it up for it to make it in. [...] It would be *very* nice if const inference were implemented. It would greatly increase the practicality of D's const. Right now, I'm forced to forego const-correctness in many places because of these kinds of issues. T -- Let's call it an accidental feature. -- Larry Wall |
February 18, 2013 Re: Purity, @safety, etc., in generic code | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Sun, Feb 17, 2013 at 10:08:13PM -0800, Walter Bright wrote: > On 2/17/2013 9:23 PM, Jonathan M Davis wrote: > >So, I think that the problem is essentially solved for @safe, pure, and nothrow as long as the implementation issues get solved. > > Yup, I believe that for templates using inference is the way to go. Currently, dmd does a rudimentary job of it, much improvement is possible. That's good to know. It would be very cool if things like std.conv.to and std.format can be inferred pure/const/nothrow/@safe if the particular set of parameters with which they are instantiated permits it. There are many places in my code where I'd love to be able to use std.format, but can't because it would break pure/@safe/nothrow. T -- There are two ways to write error-free programs; only the third one works. |
February 18, 2013 Re: Purity, @safety, etc., in generic code | ||||
---|---|---|---|---|
| ||||
On Sunday, February 17, 2013 22:19:19 H. S. Teoh wrote:
> On Sun, Feb 17, 2013 at 10:08:13PM -0800, Walter Bright wrote:
> > On 2/17/2013 9:23 PM, Jonathan M Davis wrote:
> > >So, I think that the problem is essentially solved for @safe, pure, and nothrow as long as the implementation issues get solved.
> >
> > Yup, I believe that for templates using inference is the way to go. Currently, dmd does a rudimentary job of it, much improvement is possible.
>
> That's good to know.
>
> It would be very cool if things like std.conv.to and std.format can be inferred pure/const/nothrow/@safe if the particular set of parameters with which they are instantiated permits it. There are many places in my code where I'd love to be able to use std.format, but can't because it would break pure/@safe/nothrow.
They're supposed to be, but the inferrence isn't advanced as it needs to be, and key stuff (like Appender) still can't be pure last time I checked. Similar issues exist with nothrow (and probably @safe), including issues in druntime (like with dup not being nothrow).
Also, David Nadlinger's suggestions on making @trusted applicable to statements or blocks of code rather than just whole functions would help a lot with dealing with @safe stuff, but that probably needs a DIP to sort it out before anyone can look at implementing changes like that.
- Jonathan M Davis
|
February 18, 2013 Re: Purity, @safety, etc., in generic code | ||||
---|---|---|---|---|
| ||||
On Sunday, February 17, 2013 22:13:10 H. S. Teoh wrote:
> On Sun, Feb 17, 2013 at 09:23:44PM -0800, Jonathan M Davis wrote:
> > On Sunday, February 17, 2013 20:44:29 H. S. Teoh wrote:
> > > The thing is, AFAIK, there's no way to express "this function is pure if ElementType's opEquals is pure", ditto for const, @safe, etc.. It's all or nothing: either you force all element types to implement every qualifier, or you get none at all, even if *most* instantiations actually can get them all. Furthermore, there's currently no sane way to vary qualifiers at compile-time (so that one could, say, use static if to enable/disable qualifiers depending on what is supported).
> >
> > @safe, pure, and nothrow are supposed to be inferred for templated functions. _That_ is how the @safe, pure, nothrow problem was supposedly solved.
>
> Oh? So you're saying that templated functions shouldn't need any attributes, because they will be inferred?
In general, yes. There are some cases where it may make sense to mark a templated function with attributes anyway, but in general, you can't, because the attributes may not work with some template arguments (using @trusted on templated functions is particularly evil). So, for the most part, @safe, pure, and nothrow should be unnecessary on templated functions, but the inferrence isn't good enough yet in a lot of cases, making it quite iffy at present.
Attribute inferrence was added precisely because without it, there was no way to use @safe, pure, or nothrow with std.algorithm and its ilk, not without requiring that all template arguments work with them, which is far too restrictive.
- Jonathan M Davis
|
February 18, 2013 Re: Purity, @safety, etc., in generic code | ||||
---|---|---|---|---|
| ||||
Attachments:
| 2013/2/18 Jonathan M Davis <jmdavisProg@gmx.com> > On Sunday, February 17, 2013 20:44:29 H. S. Teoh wrote: > > The thing is, AFAIK, there's no way to express "this function is pure if ElementType's opEquals is pure", ditto for const, @safe, etc.. It's all or nothing: either you force all element types to implement every qualifier, or you get none at all, even if *most* instantiations actually can get them all. Furthermore, there's currently no sane way to vary qualifiers at compile-time (so that one could, say, use static if to enable/disable qualifiers depending on what is supported). > > @safe, pure, and nothrow are supposed to be inferred for templated > functions. > _That_ is how the @safe, pure, nothrow problem was supposedly solved. This > works in some cases, but last time I checked was very buggy overall. For > instance, IIRC, if it was the struct that was templated, none of its member > functions had their attributes inferred like they were supposed to (I'd > have > to go digging through bugzilla to see what the exact set of currenly > reported > inferrence bugs is though). So, I think that the problem is essentially > solved > for @safe, pure, and nothrow as long as the implementation issues get > solved. > (This is just my personal schedule) In 2.062, followings are merged - #1543 Issue 5933 & 7159 & 9377 - Invoke function semantic3 correctly where it is required - #1096 Issue 8504 - Template attribute inferrence doesn't work - #1381 Issue 8847 - voldemort + inout confuses "is" In my thought, they were blockers for implementing 7511. - Issue 7511 - attribute inference does not work for methods of templated aggregates So, I'll begin to implement experimental patch for 7511 in near future. > Now, as for const, I don't think that the problem has been solved yet. We > really need some sort of inferrence there, which is why a number of months > ago > I created this enhancement request for inferring inout: > > http://d.puremagic.com/issues/show_bug.cgi?id=8407 > > AFAIK though, no one's even looked at it, so I don't think that it's had > any > effect as of yet. One of the compiler devs will need to take it up for it > to > make it in. I think const must not be inferred for member function, because it affects to the function overloading. For example, the const-ness for class method will be inferred from base class overridden method with current compiler, but it causes a serious problem. http://d.puremagic.com/issues/show_bug.cgi?id=8366 Instead, you should declare two methods in generic code - one is mutable, and another is const/inout. Kenji Hara |
February 19, 2013 Re: Purity, @safety, etc., in generic code | ||||
---|---|---|---|---|
| ||||
Posted in reply to kenji hara | On Monday, 18 February 2013 at 07:46:24 UTC, kenji hara wrote:
>> Now, as for const, I don't think that the problem has been solved yet. We
>> really need some sort of inferrence there, which is why a number of months
>> ago
>> I created this enhancement request for inferring inout:
>>
>> http://d.puremagic.com/issues/show_bug.cgi?id=8407
>>
>> AFAIK though, no one's even looked at it, so I don't think that it's had
>> any
>> effect as of yet. One of the compiler devs will need to take it up for it
>> to
>> make it in.
>
> I think const must not be inferred for member function, because it affects
> to the function overloading. For example, the const-ness for class method
> will be inferred from base class overridden method with current compiler,
> but it causes a serious problem.
>
> http://d.puremagic.com/issues/show_bug.cgi?id=8366
>
> Instead, you should declare two methods in generic code - one is mutable,
> and another is const/inout.
>
> Kenji Hara
I'll say upfront that I don't understand this problem completely, but I was trying to solve it anyway!
What bothers me is that the spec for 'inout' functions suggests that they generate the same runtime code, so it seems weird that there should have to be different vtable entries for the same code.
Following that thought, perhaps 'inout' class member functions could be treated specially in the case of classes. If the base class defines a method using inout,
class A
{
bool foo(inout Object o) inout { return true; }
}
... it defines a single function in the vtable, which applies to mutable, const, and immutable. If a subclass then defines a mutable method, that function is added to the vtable for that class and all descendent classes. It must be defined with override, despite that it actually creates a new function underneath:
class B : A
{
override bool foo(Object o) { return false; }
}
I am in the position of someone who knows he doesn't know everything he needs to know, but who doesn't want a good idea to go unmentioned either. Do you think this idea has merit?
|
February 19, 2013 Re: Purity, @safety, etc., in generic code | ||||
---|---|---|---|---|
| ||||
Posted in reply to kenji hara | On Monday, 18 February 2013 at 07:46:24 UTC, kenji hara wrote:
> I think const must not be inferred for member function, because it affects
> to the function overloading. For example, the const-ness for class method
> will be inferred from base class overridden method with current compiler,
> but it causes a serious problem.
>
> http://d.puremagic.com/issues/show_bug.cgi?id=8366
>
> Instead, you should declare two methods in generic code - one is mutable,
> and another is const/inout.
>
I remember mentioning overloading on const as a bad idea in the past. I don't really see the point of it.
|
February 19, 2013 Re: Purity, @safety, etc., in generic code | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix Attachments:
| I have said that "method const qualifier inference on class inheritance is bad".
With 8138 or 8366, such inference suddenly add const qualifier to one of overloaded functions, and changes the meaning of overload list. More than worse, it may introduce newly relation between overloaded functions, and in the worst case, it will add new forward reference problem.
class C : B // or class C(T)
{
void foo() { ... foo(10); ... }
void foo(int n) { ... foo(); ... }
}
For pure/nothrow/@safe inference, if a mutual dependency is found, the
attributes are inferred to impure/throwing/@system due to avoid forward
reference issue.
But, we cannot define such 'default qualifier' for const inference. So it
must raise forward reference error if a mutual dependency is found. AND it
will break existing valid code.
And bug 8366 can allow to hijack derived class by base class. If a base class add const qualifier to its method, it affects to the overload list in its derived class, not only the method that directly overrides modified one.
We should avoid language features that is hijacking/fwdref error prone.
Kenji Hara
2013/2/19 deadalnix <deadalnix@gmail.com>
> On Monday, 18 February 2013 at 07:46:24 UTC, kenji hara wrote:
>
>> I think const must not be inferred for member function, because it affects to the function overloading. For example, the const-ness for class method will be inferred from base class overridden method with current compiler, but it causes a serious problem.
>>
>> http://d.puremagic.com/issues/**show_bug.cgi?id=8366<http://d.puremagic.com/issues/show_bug.cgi?id=8366>
>>
>> Instead, you should declare two methods in generic code - one is mutable, and another is const/inout.
>>
>>
> I remember mentioning overloading on const as a bad idea in the past. I don't really see the point of it.
>
|
Copyright © 1999-2021 by the D Language Foundation