November 09, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tue, 2010-11-09 at 08:48 -0800, Andrei Alexandrescu wrote:
> On 11/9/10 8:34 AM, Don Clugston wrote:
> > On 9 November 2010 16:15, Robert Jacques<sandford at jhu.edu> wrote:
> >> On Tue, 09 Nov 2010 06:21:38 -0500, Lars Tandle Kyllingstad <lars at kyllingen.net> wrote:
> >>> It is not possible to annotate
> >>> enforce() with 'pure', however, because it takes a lazy parameter, which
> >>> is just shorthand for a (possibly impure) delegate.
> >
> >> Well, long term, we need modifiers to apply to delegates. i.e. it should be possible to declare a pure delegate.
> >
> > You can already do that.
> >
> > int delegate(int x, int y) pure @safe foo;
>
> Cool! Then overloading enforce on purity should be the solution.
>
> Andrei
How would you do that? If you mean defining enforce() like
void enforce(bool test, string delegate() pure msg) pure
{
if (test) throw new Exception(msg());
}
that would mean that the compiler must be able to implicitly convert a string parameter to a delegate returning string, as well as automatically detecting whether that delegate is pure.
string lastError;
void main()
{
enforce(true, "failure"); // Call pure enforce
enforce(true, lastError = "failure"); // Call non-pure enforce
}
-Lars
|
November 09, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don Clugston | On Tue, 09 Nov 2010 11:34:57 -0500, Don Clugston <dclugston at googlemail.com> wrote:
> On 9 November 2010 16:15, Robert Jacques <sandford at jhu.edu> wrote:
>> On Tue, 09 Nov 2010 06:21:38 -0500, Lars Tandle Kyllingstad <lars at kyllingen.net> wrote:
>>> It is not possible to annotate
>>> enforce() with 'pure', however, because it takes a lazy parameter,
>>> which
>>> is just shorthand for a (possibly impure) delegate.
>
>> Well, long term, we need modifiers to apply to delegates. i.e. it
>> should be
>> possible to declare a pure delegate.
>
> You can already do that.
>
> int delegate(int x, int y) pure @safe foo;
Cool. I love being out of date. :) Although, some syntactic sugar (or auto-magical detection) for the pure delegate literal would be nice, as 'delegate() @safe pure{return 5;}' is a lot more clunky than '(){return 5;}' or the just '5' if the function takes an 'int delegate() pure @safe foo[]...'
|
November 12, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tue, 2010-11-09 at 08:48 -0800, Andrei Alexandrescu wrote:
> On 11/9/10 8:34 AM, Don Clugston wrote:
> > On 9 November 2010 16:15, Robert Jacques<sandford at jhu.edu> wrote:
> >> On Tue, 09 Nov 2010 06:21:38 -0500, Lars Tandle Kyllingstad <lars at kyllingen.net> wrote:
> >>> It is not possible to annotate
> >>> enforce() with 'pure', however, because it takes a lazy parameter, which
> >>> is just shorthand for a (possibly impure) delegate.
> >
> >> Well, long term, we need modifiers to apply to delegates. i.e. it should be possible to declare a pure delegate.
> >
> > You can already do that.
> >
> > int delegate(int x, int y) pure @safe foo;
>
> Cool! Then overloading enforce on purity should be the solution.
I am not quite satisfied with the conclusion of this discussion. There are currently two big problems with enforce() taking a lazy parameter:
1. It prevents enforce() from being marked as pure, thus preventing major parts of Phobos from being pure, thus again preventing a lot of user code from being pure.
2. It prevents any function that uses enforce() from being inlined, thus
degrading performance. (See the "std.algorithm.sort slow as molasses"
discussion, from July, on this list.)
Solving these two issues require changes to the compiler, and I suspect it's not at the top of the priority list.
Until that happens, can we please follow Steve's suggestion and make
enforce() non-lazy and temporarily add a lazyEnforce() for those cases
where the error message is actually expensive to construct?
-Lars
|
November 12, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars Tandle Kyllingstad | We should leave enforce() as is and defining eagerEnforce() or pureEnforce().
1. No backwards-incompatible change
2. enforce() continues to mimic assert()'s behavior wrt its second argument
3. I'm not sure there will more pure functions than impure out there. If there are more impure functions, using enforce() becomes a net pessimization
If we make the change, I see "Effective D" item #35: "Beware of enforce()'s inefficiency".
Andrei
On 11/12/10 4:20 AM, Lars Tandle Kyllingstad wrote:
> On Tue, 2010-11-09 at 08:48 -0800, Andrei Alexandrescu wrote:
>> On 11/9/10 8:34 AM, Don Clugston wrote:
>>> On 9 November 2010 16:15, Robert Jacques<sandford at jhu.edu> wrote:
>>>> On Tue, 09 Nov 2010 06:21:38 -0500, Lars Tandle Kyllingstad <lars at kyllingen.net> wrote:
>>>>> It is not possible to annotate
>>>>> enforce() with 'pure', however, because it takes a lazy parameter, which
>>>>> is just shorthand for a (possibly impure) delegate.
>>>
>>>> Well, long term, we need modifiers to apply to delegates. i.e. it should be possible to declare a pure delegate.
>>>
>>> You can already do that.
>>>
>>> int delegate(int x, int y) pure @safe foo;
>>
>> Cool! Then overloading enforce on purity should be the solution.
>
>
> I am not quite satisfied with the conclusion of this discussion. There are currently two big problems with enforce() taking a lazy parameter:
>
> 1. It prevents enforce() from being marked as pure, thus preventing major parts of Phobos from being pure, thus again preventing a lot of user code from being pure.
>
> 2. It prevents any function that uses enforce() from being inlined, thus
> degrading performance. (See the "std.algorithm.sort slow as molasses"
> discussion, from July, on this list.)
>
> Solving these two issues require changes to the compiler, and I suspect it's not at the top of the priority list.
>
> Until that happens, can we please follow Steve's suggestion and make
> enforce() non-lazy and temporarily add a lazyEnforce() for those cases
> where the error message is actually expensive to construct?
>
> -Lars
|
November 12, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | ----- Original Message ---- > From: Andrei Alexandrescu <andrei at erdani.com> > To: Discuss the phobos library for D <phobos at puremagic.com> > Sent: Fri, November 12, 2010 12:17:15 PM > Subject: Re: [phobos] Pureness of enforce() > > We should leave enforce() as is and defining eagerEnforce() or pureEnforce(). > > 1. No backwards-incompatible change > > 2. enforce() continues to mimic assert()'s behavior wrt its second argument > > 3. I'm not sure there will more pure functions than impure out there. If there are more impure functions, using enforce() becomes a net pessimization > > If we make the change, I see "Effective D" item #35: "Beware of enforce()'s inefficiency". It's difficult to tell what you mean here by inefficiency -- inefficiency of eager version of enforce because the argument is pre-evaluated, or inefficiency of lazy version because it cannot be inlined... In any case, here is the message I wrote about it: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=115131 I'd say enforce should be the common case, and the common case is that you are using constant-folded strings as the argument to enforce. This almost begs for an 'auto lazy' feature. -Steve |
November 12, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Friday, November 12, 2010 09:17:15 Andrei Alexandrescu wrote:
> 3. I'm not sure there will more pure functions than impure out there. If there are more impure functions, using enforce() becomes a net pessimization
Well, since few of them are likely to call globals or C functions, most of them should theoretically be pure. The main problem we're likely to run into (I would think) would be cases where functions are called which could be pure depending on the implementation. For instance, front could be pure in many (probably most) cases, but in others it can't be. It would be _huge_ to be able to reliably make functions that use such functions pure in cases where they can be and non-pure where they can't. The same would go for nothrow. Unfortunately, I think that that that would currently mean having multiple versions of functions where they use template constraints to determine whether the pure, nothrow, pure nothrow, or non-pure non-nothrow version should be used (bleh). I wonder if we need some kind of inout for pure and nothrow.
Ideally, we would make absolutely everything that can be pure (and/or nothrow) pure (and/or nothrow). The lack of it makes using pure and nothrow in user code a pain. At least with nothrow, you can catch all exceptions and then assert 0 that there weren't any (in cases where you're sure that there won't be any) - though having to do so _is_ annoying - but you can't do that with pure.
- Jonathan M Davis
|
November 12, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Schveighoffer | On 11/12/10 10:21 AM, Steve Schveighoffer wrote: > > > > > ----- Original Message ---- >> From: Andrei Alexandrescu<andrei at erdani.com> >> To: Discuss the phobos library for D<phobos at puremagic.com> >> Sent: Fri, November 12, 2010 12:17:15 PM >> Subject: Re: [phobos] Pureness of enforce() >> >> We should leave enforce() as is and defining eagerEnforce() or >> pureEnforce(). >> >> 1. No backwards-incompatible change >> >> 2. enforce() continues to mimic assert()'s behavior wrt its second argument >> >> 3. I'm not sure there will more pure functions than impure out there. If there are more impure functions, using enforce() becomes a net pessimization >> >> If we make the change, I see "Effective D" item #35: "Beware of >> enforce()'s inefficiency". > > It's difficult to tell what you mean here by inefficiency -- inefficiency of eager version of enforce because the argument is pre-evaluated, or inefficiency of lazy version because it cannot be inlined... The former. I consider the latter a correctable QoI issue. > In any case, here is the message I wrote about it: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=115131 To which I replied that I doubt usage inside Phobos is representative. Good runtime error messages have been a low (== 0) priority to Phobos. In application code I almost always need to construct a string with text(). > I'd say enforce should be the common case, and the common case is that you are using constant-folded strings as the argument to enforce. > > This almost begs for an 'auto lazy' feature. Now that would be interesting. By and large, I'd be okay with being able to overload on purity. Andrei |
Copyright © 1999-2021 by the D Language Foundation