April 09, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Tuesday, 9 April 2013 at 07:41:55 UTC, Manu wrote:
>
> How does one specify that in their code? Is 'strong pure' a keyword?
You can't and this is the most stupid thing about pure in D. Compiler can detect which one it is, but you can't force it to accept "pure" only as "strong pure".
|
April 09, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright Attachments:
| On 9 April 2013 14:39, Walter Bright <newshound2@digitalmars.com> wrote:
> On 4/8/2013 5:37 AM, Manu wrote:
>
>> Only builtins are pure in the sense of 'C'. Even functions considered
>> PUREstrong by the frontend may update an internal state, so the rules
>> just
>> don't apply. Except for maybe global functions... In any case, the
>> only
>> benefit you can reap from 'D pure' functions are that they are more
>> likely
>> to be const-folded / inlined.
>>
>> Oh my god... ..... this is the most upsetting thing I've heard all day! :(
>> No really, I have been SOOOO excited for so long about this optimisation
>> potential in D!
>> There's gotta be something that can be done! >_<
>>
>
> I believe Iain is incorrect. Pure functions cannot squirrel away any persistent state.
>
Are you saying the example above is not actually valid code?
struct Foo {
int a = 0;
pure int bar( int n ) { // Weakly pure
a += n;
return a;
}
}
That's not pure. Call it twice with the same args, you'll different
answers. How can that possibly be considered pure in any sense?
And it's useless in terms of optimisation, so why bother at all? What does
it offer?
|
April 09, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot Attachments:
| On 9 April 2013 17:54, Dicebot <m.strashun@gmail.com> wrote:
> On Tuesday, 9 April 2013 at 07:52:20 UTC, Manu wrote:
>
>> But that's meaningless though, because there's always the possibility that
>> something somewhere else may have a non-const reference to that thing.
>> Can you suggest a case where const could EVER be used in any sort of
>> optimisation?
>> I don't think const can possibly offer anything to the optimiser in any
>> language, only type safety... I'd love to be wrong.
>>
>
> Don't forget, D variables are thread-local by default. If you get a const variable that is not shared or __gshared, compiler can safely assume that it will never change in this scope.
>
Errrm, only globals are shared by default.
Locals or allocated memory are not thread-local, can be passed wherever
they want, including other threads.
|
April 09, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Tuesday, 9 April 2013 at 08:00:38 UTC, Manu wrote:
> Errrm, only globals are shared by default.
> Locals or allocated memory are not thread-local, can be passed wherever
> they want, including other threads.
No, globals are also thread-local by default. Everything is. And it was intended that all variables that are supposed to be shared by threads in any reference-based manner are marked by shared, so you can't get it without copying or casting shared away (undefined!).
Well, have I mentioned that "shared" implementation is somewhat lacking in D now? :)
|
April 09, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Tuesday, 9 April 2013 at 07:57:37 UTC, Manu wrote:
> Are you saying the example above is not actually valid code?
>
> struct Foo {
> int a = 0;
> pure int bar( int n ) { // Weakly pure
> a += n;
> return a;
> }
> }
>
> That's not pure. Call it twice with the same args, you'll different
> answers. How can that possibly be considered pure in any sense?
> And it's useless in terms of optimisation, so why bother at all? What does
> it offer?
It is valid code. It is "weak pure". "pure' keyword means both
"strong pure" or "weak pure" depending on function body. Crap.
|
April 09, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Tuesday, 9 April 2013 at 07:57:37 UTC, Manu wrote:
> Are you saying the example above is not actually valid code?
>
> struct Foo {
> int a = 0;
> pure int bar( int n ) { // Weakly pure
> a += n;
> return a;
> }
> }
>
> That's not pure. Call it twice with the same args, you'll different
> answers. How can that possibly be considered pure in any sense?
> And it's useless in terms of optimisation, so why bother at all? What does
> it offer?
deadalnix answered but too briefly it seems. I think the reason it's pure is because a struct's member functions are actually a kind of syntax sugar. Foo.bar above is rewritten underneath as something like:
pure int __Foobar(ref Foo __f, int n) {
__f.a += n;
return __f.a;
}
Therefore if a were defined outside the struct,
int a = 0;
struct Foo {
pure int bar( int n ) {
a += n; // Epic fail
return a;
}
}
... it would fail completely, but 'a' is a struct field and so passed by hidden pointer to the member function, which is therefore in essence weakly pure.
|
April 09, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot Attachments:
| On 9 April 2013 18:03, Dicebot <m.strashun@gmail.com> wrote: > On Tuesday, 9 April 2013 at 08:00:38 UTC, Manu wrote: > >> Errrm, only globals are shared by default. >> Locals or allocated memory are not thread-local, can be passed wherever >> they want, including other threads. >> > > No, globals are also thread-local by default. Sorry, that's what I meant, I typed the wrong thing >_< Everything is. Errrr, no? Only globals are thread-local. Everything else is either stack or heap allocated. And it was intended that all variables that are supposed to be shared by > threads in any reference-based manner are marked by shared, so you can't get it without copying or casting shared away (undefined!). > Yes but that's ultimately useless. If sharing is undefined, and you can only use pass something to another thread via shared, then you basically can't use threads. shared is facilitated by blind casting. And codegen (which doesn't know if something actually WAS shared or not) can't be assuming it wasn't. I can't imagine a situation other than immutable where the compiler is able to presume __restrict in this way. Well, have I mentioned that "shared" implementation is somewhat lacking in > D now? :) > It's almost a cruel joke. I try not to show that to people when I show them D ;) |
April 09, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot Attachments:
| On 9 April 2013 18:04, Dicebot <m.strashun@gmail.com> wrote:
> On Tuesday, 9 April 2013 at 07:57:37 UTC, Manu wrote:
>
>> Are you saying the example above is not actually valid code?
>>
>> struct Foo {
>> int a = 0;
>> pure int bar( int n ) { // Weakly pure
>> a += n;
>> return a;
>> }
>> }
>>
>> That's not pure. Call it twice with the same args, you'll different
>> answers. How can that possibly be considered pure in any sense?
>> And it's useless in terms of optimisation, so why bother at all? What does
>> it offer?
>>
>
> It is valid code. It is "weak pure". "pure' keyword means both "strong pure" or "weak pure" depending on function body. Crap.
>
How can 'weak pure' reasonably be called any kind of 'pure'? It's not pure
at all. The function returns a completely different result when called
twice. That's the definition of not-pure.
I suggest that no D language newbie would ever reasonably expect that
behaviour.
|
April 09, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
On Tue, 09 Apr 2013 09:41:43 +0200, Manu <turkeyman@gmail.com> wrote: > How does one specify that in their code? Is 'strong pure' a keyword? It's not a keyword. It's inferred by the compiler when a function is marked pure (or is a template function and is inferred pure), and all parameters are implicitly castable to immutable (i.e. POD or marked immutable). This includes, of course, the hidden 'this' parameter. -- Simen |
April 09, 2013 Re: To help LDC/GDC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Tuesday, 9 April 2013 at 08:31:06 UTC, Manu wrote: > Errrr, no? > Only globals are thread-local. Everything else is either stack or heap > allocated. Well, stack is also thread-local, isn't it? ;) Heap objection accepted. > Yes but that's ultimately useless. If sharing is undefined, and you can > only use pass something to another thread via shared, then you basically > can't use threads. > shared is facilitated by blind casting. And codegen (which doesn't know if > something actually WAS shared or not) can't be assuming it wasn't. > I can't imagine a situation other than immutable where the compiler is able > to presume __restrict in this way. My memories may be vague (I have been reading about it in a d-concurrency mail list used a looong time ago) but initial concept was quite elegant: everything that is intended to be shared should me marked with qualifiers. Function shall accepts shared parameters, do locks on them (which casts away shared in a library) and then use in regular functions. This clearly defines the distinction between functions that need to take care of synchronization and functions that can just work. I still think it is a clever concept, but without proper support in D/Phobos implementation is has become a cumbersome restriction. Once again, that is what my memory says, I'd like to be corrected by someone who has actually participated in that mail list. |
Copyright © 1999-2021 by the D Language Foundation