Thread overview | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 29, 2013 trusted purity? | ||||
---|---|---|---|---|
| ||||
Is there *any* way to make a call to a non-pure function in a pure context, if you know you won't violate your own purity? This is something you can do with @safe (@trusted), but what about pure? For example, "free" is not pure, because you can't call it twice on the same pointer. But if you manage the pointer yourself inside a struct, you can guarantee the purity of your own functions. But the language won't allow you to do that. Related question: Can a function that "sometimes throws" be considered as pure? |
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | I've been working on a pull request and came up with something like this: private void initialize(A...)(auto ref A args) { auto m = cast(void* function(size_t size) pure)&malloc; _store = cast(Impl*) enforce(m(Impl.sizeof)); auto r = cast(void function(in void* p, size_t sz) nothrow pure)&GC.addRange; static if (hasIndirections!T) r(&_store._payload, T.sizeof); emplace(&_store._payload, args); _store._count = 1; } The purity of "emplace" depends on the purity of the ctor called. I'm not sure how to fix that. |
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Henning Pohl | By the way, my post is related to the impurity of RefCounted: http://d.puremagic.com/issues/show_bug.cgi?id=9998 |
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Henning Pohl | On Monday, 29 April 2013 at 11:15:20 UTC, Henning Pohl wrote: > I've been working on a pull request and came up with something like this: > > private void initialize(A...)(auto ref A args) > { > auto m = cast(void* function(size_t size) pure)&malloc; > _store = cast(Impl*) enforce(m(Impl.sizeof)); > auto r = cast(void function(in void* p, size_t sz) nothrow pure)&GC.addRange; > static if (hasIndirections!T) > r(&_store._payload, T.sizeof); > emplace(&_store._payload, args); > _store._count = 1; > } I always forget you can cast the type of a function... > The purity of "emplace" depends on the purity of the ctor called. I'm not sure how to fix that. I'm not sure there's anything to fix there: If the CTor is not pure, then how could emplace be pure? I did some work on emplace that is awaiting to be pulled, which should improve its purity. On Monday, 29 April 2013 at 11:19:33 UTC, Henning Pohl wrote: > By the way, my post is related to the impurity of RefCounted: http://d.puremagic.com/issues/show_bug.cgi?id=9998 Yes, that is also what I am investigating. The cast is would indeed be a fix for malloc/free. RefCounted's isInitialized/refCount still need to be marked as pure though. I'm still worried about what it means for a pure function to throw... (I'm thinking about the "enforce(malloc)" scheme) |
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Monday, 29 April 2013 at 11:32:33 UTC, monarch_dodra wrote:
> I'm still worried about what it means for a pure function to throw... (I'm thinking about the "enforce(malloc)" scheme)
If malloc returns null, we are out of memory. In D this is not an exception, it is an error. So I guess we just need to check the pointer returned by malloc and throw an OutOfMemoryError on failure. Thus if the ctor called is nothrow, it can be marked as nothrow, too.
So in this case, there should be no problem making it pure.
|
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Henning Pohl | On Monday, 29 April 2013 at 11:50:11 UTC, Henning Pohl wrote:
> On Monday, 29 April 2013 at 11:32:33 UTC, monarch_dodra wrote:
>> I'm still worried about what it means for a pure function to throw... (I'm thinking about the "enforce(malloc)" scheme)
>
> If malloc returns null, we are out of memory. In D this is not an exception, it is an error. So I guess we just need to check the pointer returned by malloc and throw an OutOfMemoryError on failure. Thus if the ctor called is nothrow, it can be marked as nothrow, too.
>
> So in this case, there should be no problem making it pure.
I've hit this issue before: In D, if the *managed* memory runs out, then it is an error (since then *everything* crumbles: arrays, GC. etc). The reason it is an error is that since the memory is managed by the language, there is nothing the user can do anyway, so throwing is pointless.
for unmanaged memory, on the otherhand, the user *can* do something about it, so throwing is better.
I myself am not sure I 100% agree with this, but that was the conclusion last time I tried to transform an malloc=>Exception into a malloc=>Error+Nothrow
|
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Monday, 29 April 2013 at 12:08:58 UTC, monarch_dodra wrote:
> I've hit this issue before: In D, if the *managed* memory runs out, then it is an error (since then *everything* crumbles: arrays, GC. etc). The reason it is an error is that since the memory is managed by the language, there is nothing the user can do anyway, so throwing is pointless.
>
> for unmanaged memory, on the otherhand, the user *can* do something about it, so throwing is better.
>
> I myself am not sure I 100% agree with this, but that was the conclusion last time I tried to transform an malloc=>Exception into a malloc=>Error+Nothrow
What about using allocators the user can specify? The default one would be malloc + Error + nothrow. All the signatures of RefCounted have to change depending on the allocator's ones, though. This is where attribute inference is rather needed.
|
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Henning Pohl | I'm getting strange behavior trying to cast to pure. This is my test program: //-------- import std.stdio; import core.stdc.stdlib; void main() { auto p1 = &core.stdc.stdlib.free; auto p2 = cast(void function(void*))&core.stdc.stdlib.free; auto p3 = cast(void function(void*) pure)&core.stdc.stdlib.free; auto pp1 = core.stdc.stdlib.malloc(5); auto pp2 = core.stdc.stdlib.malloc(5); auto pp3 = core.stdc.stdlib.malloc(5); writeln(p1); p1(pp1); writeln(p2); p2(pp2); //This hangs writeln(p3); //Never reaches here p3(pp3); } //-------- Am I doing something wrong? Could somebody else test this? I'm on win32. I've also been getting some object violations trying to use this cast... |
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Monday, 29 April 2013 at 10:58:45 UTC, monarch_dodra wrote: > Is there *any* way to make a call to a non-pure function in a pure context, if you know you won't violate your own purity? > > This is something you can do with @safe (@trusted), but what about pure? > This raise the case once again for trusted as a statement and not as a qualifier. Tis would solve the purity issue. > Related question: > Can a function that "sometimes throws" be considered as pure? Yes as long at its behavior depends only on parameters. |
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 4/29/2013 3:58 AM, monarch_dodra wrote: > Is there *any* way to make a call to a non-pure function in a pure context, if > you know you won't violate your own purity? Vee haf veys: 1. put "debug" before the impure code (but you'll have to compile with -debug) 2. put the impure code in a separate function, take its address, and cast its address to being a pointer to a pure function. (Of course, such a cast should be rejected by @safe code.) 3. Put the code in an extern(C) function, compiled separately as impure, but declared as pure in the client. C functions don't get name mangling, so the compiler won't know it's impure. I feel it's a good thing that you'll need to jump through some hoops to do this, otherwise 'pure' would not be very useful. > Related question: > Can a function that "sometimes throws" be considered as pure? deadalnix's answer is correct. |
Copyright © 1999-2021 by the D Language Foundation