Jump to page: 1 2
Thread overview
[phobos] Pureness of enforce()
Nov 09, 2010
Jonathan M Davis
Nov 09, 2010
Robert Jacques
Nov 09, 2010
Don Clugston
Nov 12, 2010
Jonathan M Davis
Nov 09, 2010
Robert Jacques
November 09, 2010
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
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
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
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
----- 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
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



----- 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
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
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
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

« First   ‹ Prev
1 2