Thread overview | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 09, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
enforce(x) is basically a substitute for if (x) throw new Exception; which doesn't violate the purity rules. 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. enforce() is used virtually everywhere in Phobos, and this means that a lot of functions that could otherwise be marked as pure, currently can't. One example is std.conv.to(), which should definitely be pure. (In fact, I tried marking it as such, which is what got me thinking about this in the first place.) What to do? -Lars |
November 09, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars Tandle Kyllingstad | On Tuesday 09 November 2010 03:21:38 Lars Tandle Kyllingstad wrote:
> enforce(x) is basically a substitute for
>
> if (x) throw new Exception;
>
> which doesn't violate the purity rules. 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.
>
> enforce() is used virtually everywhere in Phobos, and this means that a lot of functions that could otherwise be marked as pure, currently can't.
>
> One example is std.conv.to(), which should definitely be pure. (In
> fact, I tried marking it as such, which is what got me thinking about
> this in the first place.)
>
> What to do?
The simplest is just to ditch it in favor of writing
if(x) throw new Exception;
or the equivalent. It really isn't much more code, it doesn't run any of the code necessary to create or throw the exception unless it has to, and it doesn't have to create a delegate. Granted, using enforce() is kind of nice, but if it can't be made pure, it's not worth it. All it really does is save you from putting the if and the throw in the statement. It's virtually identical otherwise.
Now, if we can find a way to make enforce() pure (probably with compiler help to deal with the lazy/delegate issue) that would be better, but I think that purity is worth _far_ more than the little bit of typing that enforce() saves you.
- Jonathan M Davis
|
November 09, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars Tandle Kyllingstad | A while back, I suggested changing enforce to not take a lazy argument. In my investigation 90% of uses of enforce do not need the lazy argument (because the string is constructed at compile-time).
My suggestion is to remove lazy from enforce, mark it as pure, and create a lazyEnforce that takes a lazy argument for use in the few places it's needed.
-Steve
----- Original Message ----
> From: Lars Tandle Kyllingstad <lars at kyllingen.net>
> To: Phobos mailing list <phobos at puremagic.com>
> Sent: Tue, November 9, 2010 6:21:38 AM
> Subject: [phobos] Pureness of enforce()
>
> enforce(x) is basically a substitute for
>
> if (x) throw new Exception;
>
> which doesn't violate the purity rules. 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.
>
> enforce() is used virtually everywhere in Phobos, and this means that a lot of functions that could otherwise be marked as pure, currently can't.
>
> One example is std.conv.to(), which should definitely be pure. (In
> fact, I tried marking it as such, which is what got me thinking about
> this in the first place.)
>
> What to do?
>
> -Lars
>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>
|
November 09, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lars Tandle Kyllingstad | On Tue, 09 Nov 2010 06:21:38 -0500, Lars Tandle Kyllingstad <lars at kyllingen.net> wrote:
> enforce(x) is basically a substitute for
>
> if (x) throw new Exception;
>
> which doesn't violate the purity rules. 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.
>
> enforce() is used virtually everywhere in Phobos, and this means that a lot of functions that could otherwise be marked as pure, currently can't.
>
> One example is std.conv.to(), which should definitely be pure. (In
> fact, I tried marking it as such, which is what got me thinking about
> this in the first place.)
>
> What to do?
>
> -Lars
Well, long term, we need modifiers to apply to delegates. i.e. it should be possible to declare a pure delegate. (Or a const delegate. Or an immutable delegate. Or a shared delegate, etc.) For example, right now, it's not possible to (type-) safely use a delegate in shared code. And David's std.parallelism is a prime case where many methods could be marked @safe instead of @here_be_dragons if delegate modifiers existed.
|
November 09, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Jacques | ----- Original Message ----
> From: Robert Jacques <sandford at jhu.edu>
>
> Well, long term, we need modifiers to apply to delegates. i.e. it should be
>possible to declare a pure delegate. (Or a const delegate. Or an immutable delegate. Or a shared delegate, etc.) For example, right now, it's not possible to (type-) safely use a delegate in shared code. And David's std.parallelism is a prime case where many methods could be marked @safe instead of @here_be_dragons if delegate modifiers existed.
A pure delegate is not the same as a const, immutable, or shared delegate.
A const, immutable, or shared member function applies the const, immutable, or shared part to the hidden context pointer. So I believe the modifier should be hidden as well. What we do need at some point is for you to not be able to create such a delegate.
A pure function does not apply 'pure' to the context pointer or any other parameters, it applies directly to the function. So I think we will need the pure modifier as part of the delegate type. And I think that might solve the enforce problem.
@safe is similar to pure.
inout will be a weird one, because you don't know what the constancy of the hidden pointer is. What we probably need is const inout, immutable inout, and mutable inout delegates. Otherwise, the compiler cannot tell what to substitute for inout.
-Steve
|
November 09, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Jacques | On 11/9/10 7:15 AM, Robert Jacques wrote:
> On Tue, 09 Nov 2010 06:21:38 -0500, Lars Tandle Kyllingstad <lars at kyllingen.net> wrote:
>
>> enforce(x) is basically a substitute for
>>
>> if (x) throw new Exception;
>>
>> which doesn't violate the purity rules. 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.
>>
>> enforce() is used virtually everywhere in Phobos, and this means that a lot of functions that could otherwise be marked as pure, currently can't.
>>
>> One example is std.conv.to(), which should definitely be pure. (In
>> fact, I tried marking it as such, which is what got me thinking about
>> this in the first place.)
>>
>> What to do?
>>
>> -Lars
>
> Well, long term, we need modifiers to apply to delegates. i.e. it should be possible to declare a pure delegate. (Or a const delegate. Or an immutable delegate. Or a shared delegate, etc.) For example, right now, it's not possible to (type-) safely use a delegate in shared code. And David's std.parallelism is a prime case where many methods could be marked @safe instead of @here_be_dragons if delegate modifiers existed.
I agree. For the time being, if pressed to choose between @pure and lazy, I'd choose the latter. Use of enforce() in Phobos is probably not representative for application code, where error messages are more elaborate and may be loaded from a string table etc.
Andrei
|
November 09, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Schveighoffer | ----- Original Message ---- > From: Steve Schveighoffer <schveiguy at yahoo.com> > A const, immutable, or shared member function applies the const, immutable, or > > shared part to the hidden context pointer. So I believe the modifier should >be > > hidden as well. What we do need at some point is for you to not be able to create such a delegate. Didn't finish that thought. I meant to write: What we do need at some point is for you to not be able to create such a delegate unless the type system allows it. That is, if you have a const object, you shouldn't be able to get a delegate to an immutable member function. -Steve |
November 09, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Jacques | 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; |
November 09, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don Clugston | 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
|
November 09, 2010 [phobos] Pureness of enforce() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tue, 2010-11-09 at 08:23 -0800, Andrei Alexandrescu wrote:
> On 11/9/10 7:15 AM, Robert Jacques wrote:
> > On Tue, 09 Nov 2010 06:21:38 -0500, Lars Tandle Kyllingstad <lars at kyllingen.net> wrote:
> >
> >> enforce(x) is basically a substitute for
> >>
> >> if (x) throw new Exception;
> >>
> >> which doesn't violate the purity rules. 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.
> >>
> >> enforce() is used virtually everywhere in Phobos, and this means that a lot of functions that could otherwise be marked as pure, currently can't.
> >>
> >> One example is std.conv.to(), which should definitely be pure. (In
> >> fact, I tried marking it as such, which is what got me thinking about
> >> this in the first place.)
> >>
> >> What to do?
> >>
> >> -Lars
> >
> > Well, long term, we need modifiers to apply to delegates. i.e. it should be possible to declare a pure delegate. (Or a const delegate. Or an immutable delegate. Or a shared delegate, etc.) For example, right now, it's not possible to (type-) safely use a delegate in shared code. And David's std.parallelism is a prime case where many methods could be marked @safe instead of @here_be_dragons if delegate modifiers existed.
>
> I agree. For the time being, if pressed to choose between @pure and lazy, I'd choose the latter. Use of enforce() in Phobos is probably not representative for application code, where error messages are more elaborate and may be loaded from a string table etc.
No, but the fact that enforce() cannot be pure means that the Phobos
functions that use enforce() can't be pure either. And that *is* a
problem for user code.
Also, a while ago, Steve (at least I think it was him) made a good case
that making enforce() non-lazy will actually *improve* performance,
because that would allow inlining.
-Lars
|
Copyright © 1999-2021 by the D Language Foundation