April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 4/29/2013 5:08 AM, 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.
You cannot call a function pure if it sometimes throws a recoverable exception and sometimes does not, and this is not based on the supplied arguments.
|
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 4/29/2013 10:19 AM, monarch_dodra wrote:
> I'm getting strange behavior trying to cast to pure. This is my
> test program:
You're casting a C function to a D function. This will cause crashes.
|
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Monday, April 29, 2013 12:58:44 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? > > 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. You can cast a pointer to the function. std.datetime does that for the LocalTime and UTC singletons. Take a look at the semi-recently added std.traits.SetFunctionAttributes. > Related question: > Can a function that "sometimes throws" be considered as pure? Throwing has nothing to do with purity. pure is purely a question of whether the function accesses module-level or static variables which can possibly be mutated after they're initialized. Strong purity (which is required for most/all optimizations) is then places additional requirements on the function parameters, but purity itself is simply a question of whether the function accesses module-level or static variables. So, throwing has nothing to do with it. - Jonathan M Davis |
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Monday, 29 April 2013 at 18:34:46 UTC, Walter Bright wrote:
> On 4/29/2013 10:19 AM, monarch_dodra wrote:
>> I'm getting strange behavior trying to cast to pure. This is my
>> test program:
>
> You're casting a C function to a D function. This will cause crashes.
OK, so say I have a documented pure C function, how do I call it from a pure scope? You say, take the address and cast it, but not if it's C...
|
April 29, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 4/29/2013 1:03 PM, monarch_dodra wrote:
> On Monday, 29 April 2013 at 18:34:46 UTC, Walter Bright wrote:
>> On 4/29/2013 10:19 AM, monarch_dodra wrote:
>>> I'm getting strange behavior trying to cast to pure. This is my
>>> test program:
>>
>> You're casting a C function to a D function. This will cause crashes.
>
> OK, so say I have a documented pure C function, how do I call it from a pure
> scope? You say, take the address and cast it, but not if it's C...
extern (C) {
int foo(int);
}
extern (C) {
pure int function(int) fp_pure_t;
}
...
cast(fp_pure_t)(&foo)
|
April 30, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra Attachments:
| Hmm. Interesting approach. I tried to utilize the "trusted pure" concept . template TrustedPure(alias func) { import std.traits, std.algorithm; alias F1 = FunctionTypeOf!(func); static if (functionAttributes!F1 & FunctionAttribute.pure_) { alias TrustedPure = func; } else { alias F2 = SetFunctionAttributes!( F1, functionLinkage!F1, functionAttributes!F1 | FunctionAttribute.pure_); auto ref TrustedPure(A...)(auto ref A args) pure // mark as expected @system // represent 'unsafe' operation. { // forward!args does not work, because // std.algorithm.move is not pure... return (cast(F2*)&func)(/*forward!*/args); } } } void main() pure // cannot add @safe, because TrustedPure functions are always @system { import core.stdc.stdlib; alias pmalloc = TrustedPure!(core.stdc.stdlib.malloc); alias pfree = TrustedPure!(core.stdc.stdlib.free); auto p = cast(int*)pmalloc(int.sizeof); *p = 100; pfree(p); } Kenji Hara 2013/4/30 monarch_dodra <monarchdodra@gmail.com> > 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 30, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Monday, 29 April 2013 at 20:51:50 UTC, Walter Bright wrote:
> On 4/29/2013 1:03 PM, monarch_dodra wrote:
>> On Monday, 29 April 2013 at 18:34:46 UTC, Walter Bright wrote:
>>> On 4/29/2013 10:19 AM, monarch_dodra wrote:
>>>> I'm getting strange behavior trying to cast to pure. This is my
>>>> test program:
>>>
>>> You're casting a C function to a D function. This will cause crashes.
>>
>> OK, so say I have a documented pure C function, how do I call it from a pure
>> scope? You say, take the address and cast it, but not if it's C...
>
> extern (C) {
> int foo(int);
> }
>
> extern (C) {
> pure int function(int) fp_pure_t;
> }
>
> ...
> cast(fp_pure_t)(&foo)
Thanks. That (kinda) worked. I just had to add an alias, because the compiler was complaining about: "Error: fp_pure_t is used as a type"
This works though:
//====
extern (C) {
int foo(int);
}
extern (C) {
alias pure int function(int) fp_pure_t;
}
...
cast(fp_pure_t)(&foo)
//====
That works.
|
April 30, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 4/29/2013 10:42 PM, monarch_dodra wrote:
> Thanks. That (kinda) worked. I just had to add an alias, because the
> compiler was complaining about: "Error: fp_pure_t is used as a type"
Yeah, I should have tested it before posting!
|
April 30, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Tuesday, 30 April 2013 at 17:06:00 UTC, Walter Bright wrote:
> On 4/29/2013 10:42 PM, monarch_dodra wrote:
>> Thanks. That (kinda) worked. I just had to add an alias, because the
>> compiler was complaining about: "Error: fp_pure_t is used as a type"
>
> Yeah, I should have tested it before posting!
Oh, no problem, you gave me the right answer anyways, that's what
counts. Thanks.
|
August 19, 2013 Re: trusted purity? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | I've been struggling with this, so here are my observations: On Monday, 29 April 2013 at 18:31:15 UTC, Walter Bright wrote: > 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? > 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.) This doesn't work with CTFE. I'm currently not seeing how I could make a function that needs to make a "trusted pure" call work at compile time: The function pointer cast will fail during CTFE, and if I add a "if (__ctfe)" block without it, then the function will be impure, due to the code inside the "if (__ctfe)" block. I've yet to solve this problem. > 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. Unfortunately, this doesn't work with templates. You have to force instantiation by inserting a straight up (dummy) call to the function, but that immediately makes the caller 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. I agree, but these aren't hoops, they're pole vaults. FYI, the problem I'm trying to fix is this one: * "uninitializedArray" returns an array with un-initialized elements. This, by definition, is not pure, since the value returned is garbage. I'm fixing the function so that it becomes *impure*. * "array" is implemented in terms of "uninitializedArray": Allocate an array, and then fill it. "array" is pure, since its return is defined. array also works with ctfe. I'm at a deadlock on this one. |
Copyright © 1999-2021 by the D Language Foundation