digitalmars.D - To help LDC/GDC
- bearophile (10/10) Apr 06 2013 I remember Walter saying two or more times that the semantics of
- Iain Buclaw (7/16) Apr 08 2013 This information could possibly be helpful. Though given that most of
- Timon Gehr (5/22) Apr 08 2013 Does GDC use the additional type information for optimization? Eg. if
- Iain Buclaw (10/40) Apr 08 2013 It uses some type information, eg:
- deadalnix (5/12) Apr 08 2013 const/wild can be muted via aliasing. I'm not sure how GCC's
- Iain Buclaw (6/16) Apr 08 2013 GCC's backend is pretty much C/C++ semantics. So the const qualifier is
- Manu (4/20) Apr 08 2013 But D makes no further guarantee. I don't see how const in D is any
- John Colvin (3/31) Apr 08 2013 D const is transitive, surely that makes a difference/presents an
- Manu (3/32) Apr 08 2013 No, I think that just makes it 'safer', or as many might say, "more
- Dicebot (3/3) Apr 08 2013 Casting away D const is undefined behavior. It is still not for
- Dicebot (4/7) Apr 08 2013 Minor fix: It is undefined in C++11 to cast away const from
- Jesse Phillips (2/5) Apr 08 2013 Minor correction, it is undefined to modify a const reference.
- Walter Bright (6/9) Apr 08 2013 In C++, it is legal to cast away const and mutate it. That is undefined ...
- Jacob Carlborg (5/7) Apr 09 2013 Didn't they change how const behaves in C++11, I'm thinking of this:
- Dicebot (4/11) Apr 09 2013 Yes, but it is changed only for multi-threaded code (because the
- Manu (7/20) Apr 09 2013 But that's meaningless though, because there's always the possibility th...
- Dicebot (4/14) Apr 09 2013 Don't forget, D variables are thread-local by default. If you get
- Manu (4/15) Apr 09 2013 Errrm, only globals are shared by default.
- Dicebot (8/12) Apr 09 2013 No, globals are also thread-local by default. Everything is. And
- Manu (17/26) Apr 09 2013 Sorry, that's what I meant, I typed the wrong thing >_<
- Dicebot (15/31) Apr 09 2013 Well, stack is also thread-local, isn't it? ;) Heap objection
- Walter Bright (2/4) Apr 10 2013 Not unless they are marked as "shared".
- Walter Bright (12/15) Apr 10 2013 Sure:
- Timon Gehr (7/19) Apr 09 2013 The back end can assume this only if the DMD front end does its
- deadalnix (8/20) Apr 09 2013 No, D have holes in its type system and so can't ensure anything.
- Daniel Murphy (6/12) Apr 09 2013 The const/pure etc systems are based on certain guarantees, and places w...
- deadalnix (4/22) Apr 09 2013 Right now it isn't bugs as it is how thing are defined. And will
- Timon Gehr (11/25) Apr 09 2013 That is certainly true, but mostly so because basically the only thing
- Manu (3/18) Apr 09 2013 The only optimisation possibility is for strong pure functions that are
- Timon Gehr (12/15) Apr 09 2013 No, strongly pure functions will always throw the same classes of
- Timon Gehr (2/20) Apr 09 2013
- deadalnix (3/7) Apr 09 2013 No as no guarantee can exists as long as type qualifier
- Andrei Alexandrescu (4/25) Apr 09 2013 Agreed. In parallel with work on improving quality, we also need to
- Walter Bright (2/8) Apr 10 2013 Having a bug in the compiler doesn't mean the language design is full of...
- Andrei Alexandrescu (4/18) Apr 10 2013 Unfortunately we have holes in the language definition, too. We can't
- Timon Gehr (7/21) Apr 10 2013 Generally it does not, but is it actually not full of holes in this
- Walter Bright (3/9) Apr 10 2013 Clearly, delegates should not be able to break purity, const, shared, et...
- Andrei Alexandrescu (7/19) Apr 10 2013 Yah, hence the holes :o). I think it's important to acknowledge that
- Walter Bright (3/21) Apr 10 2013 My point was that competing designs are very probably not necessary. We ...
- Timon Gehr (7/10) Apr 10 2013 Yes, IMO it is quite obvious how to do it. (transfer the meaning of the
- Walter Bright (4/15) Apr 10 2013 A delegate works exactly like a member function call. It has an implicit...
- Timon Gehr (7/26) Apr 11 2013 That's still not sufficient as a specification.
- deadalnix (4/18) Apr 10 2013 It is not about compiler bugs, it is about language definition.
- Manu (25/66) Apr 08 2013 Yes, I was just about to bring up __restrict, there is probably good
- Timon Gehr (2/5) Apr 08 2013 As far as I can see, restrict can easily be applied to immutable data.
- Manu (4/6) Apr 08 2013 I guess immutable is a subset of __restrict.
- Iain Buclaw (19/90) Apr 08 2013 At least, many array operations, eg: a[] += b[]. Require the arrays no...
- Manu (20/115) Apr 08 2013 Oh my god... ..... this is the most upsetting thing I've heard all day! ...
- David Nadlinger (11/34) Apr 08 2013 Iain, are you sure about that? (No offense, but you have been
- David Nadlinger (3/11) Apr 08 2013 (you also need nothrow, of course)
- Iain Buclaw (12/43) Apr 08 2013 e?
- Johannes Pfau (10/49) Apr 08 2013 e=20
- Johannes Pfau (11/23) Apr 08 2013 And to make it even worse AFAICT D's nothrow is also meaningless for
- Walter Bright (3/5) Apr 08 2013 There is. The setting up of the exception handling frames can be omitted...
- Walter Bright (3/12) Apr 08 2013 I believe Iain is incorrect. Pure functions cannot squirrel away any per...
- Manu (13/30) Apr 09 2013 Are you saying the example above is not actually valid code?
- Dicebot (3/17) Apr 09 2013 It is valid code. It is "weak pure". "pure' keyword means both
- Manu (6/24) Apr 09 2013 How can 'weak pure' reasonably be called any kind of 'pure'? It's not pu...
- Dicebot (6/14) Apr 09 2013 It is "weak pure" because it can be called by "strong pure"
- Timon Gehr (17/23) Apr 09 2013 (Actually this is not the definition of impure.)
- Jacob Carlborg (4/5) Apr 09 2013 "static" has quite a lot of overloads as well.
- ixid (2/30) Apr 09 2013 for -> loop?
- tn (7/37) Apr 09 2013 The returned results are different because the parameters you are
- Manu (3/39) Apr 09 2013 Ah, yes. Good point. I don't know how I missed that point prior!
- Walter Bright (4/8) Apr 10 2013 I explained it in another reply here.
- Zach the Mystic (8/19) Apr 10 2013 For some reason I was never confused by this issue, even though
- =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= (6/32) Apr 09 2013 It's pure in the sense that it can be used inside (strongly) pure
- Andrei Alexandrescu (3/7) Apr 09 2013 Me too. But then any innovation by definition has an element of surprise...
- Andrei Alexandrescu (4/22) Apr 09 2013 s/body/signature/
- Dicebot (16/20) Apr 09 2013 Not gonna argue latter but former is just wrong.
- "Pelle =?UTF-8?B?TcOlbnNzb24i?= <pelle.mansson.ok gmail.com> (8/29) Apr 09 2013 Think of all your member functions as non-member functions taking
- Dicebot (3/5) Apr 09 2013 I was under impression that pure is about verifying what function
- =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= (7/11) Apr 09 2013 .
- Dicebot (12/23) Apr 09 2013 You got me lost here again. Definition of pure in dlang.org says:
- Simen Kjaeraas (18/40) Apr 09 2013 e).
- Walter Bright (8/9) Apr 10 2013 Correct.
- kenji hara (10/32) Apr 09 2013 Both have weak pure. Purity is always calculated only from the function
- Jesse Phillips (3/15) Apr 09 2013 Isn't it
- =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= (6/22) Apr 09 2013 const is not sufficient, as someone else might have a mutable
- Walter Bright (3/5) Apr 10 2013 const is sufficient for strongly pure, because another reference is not
- deadalnix (6/12) Apr 10 2013 No !
- Walter Bright (3/5) Apr 10 2013 The argument doesn't need to be immutable because nobody can change it w...
- Timon Gehr (2/8) Apr 10 2013 (He has written DIP30. Under DIP30 this would no longer be the case.)
- deadalnix (3/9) Apr 11 2013 I explained the sentence just above how it is possible. Ignoring
- Walter Bright (3/12) Apr 11 2013 The delegate issue is a known one, and can be solved, and is not relevan...
- deadalnix (2/19) Apr 11 2013 See Timon's post. Both are deeply linked.
- Andrei Alexandrescu (3/23) Apr 09 2013 Both are weakly pure.
- Dicebot (8/27) Apr 09 2013 And that is even more surprising as foo2 perfectly matches
- John Colvin (3/28) Apr 09 2013 Don't you mean foo1? I have no idea what i'm talking about but
- Dicebot (2/4) Apr 09 2013 foo1, of course, beg my pardon.
- Andrei Alexandrescu (4/32) Apr 09 2013 I think it's a great design, very useful and innovative.
- Dicebot (5/13) Apr 09 2013 Agree on it being great and innovative. But I fail to see
- deadalnix (5/19) Apr 09 2013 Strongly pure functions can call weakly pure function while
- Dicebot (5/12) Apr 10 2013 It does not answer my question. Why "pure" keyword is useful in D
- deadalnix (4/19) Apr 10 2013 It isn't beauty of concept. Strongly pure function exhibit from
- Dicebot (4/25) Apr 10 2013 Except you can't be sure that your function is strongly pure with
- Andrei Alexandrescu (4/28) Apr 10 2013 I would venture that you are being confused. This seems to indicate
- deadalnix (3/7) Apr 10 2013 pure + immutable and value parameters == strongly pure (as in
- Timon Gehr (7/13) Apr 10 2013 pure notEntirely(){
- Manu (2/40) Apr 09 2013 What is an immutable function? Why is const not sufficient?
- Simen Kjaeraas (7/8) Apr 09 2013 Immutable requires that the struct/class be immutable, const
- deadalnix (3/9) Apr 09 2013 Not in other thread (as it would require to be shared or is
- Walter Bright (3/17) Apr 10 2013 foo1 is weakly pure. It would be strongly pure if it were declared:
- Walter Bright (4/6) Apr 10 2013 I agree that the notions of strong/weak purity are awesome, I believe th...
- Walter Bright (14/31) Apr 10 2013 No, it is weakly or strongly pure based on the parameter types. bar(int ...
- Zach the Mystic (20/34) Apr 09 2013 deadalnix answered but too briefly it seems. I think the reason
- Joseph Rushton Wakeling (5/7) Apr 09 2013 Stepping outside from any controversy for now, I think I should say that...
- Zach the Mystic (6/18) Apr 09 2013 Thanks, man! The truth is, compared to some of the heavyweights
- Andrei Alexandrescu (3/13) Apr 09 2013 The values reachable from "this" are different in the two calls.
- Simen Kjaeraas (6/14) Apr 08 2013 What?!?
- Iain Buclaw (5/15) Apr 08 2013 It might be weakly pure. ;)
- Iain Buclaw (17/24) Apr 08 2013 Haven't looked, but it appears to have a general idea of this. D 'weak
- Johannes Pfau (5/34) Apr 08 2013 Can't a strong pure + nothrow + release mode function still throw
- Manu (2/26) Apr 09 2013 How does one specify that in their code? Is 'strong pure' a keyword?
- Dicebot (4/6) Apr 09 2013 You can't and this is the most stupid thing about pure in D.
- Joseph Rushton Wakeling (4/6) Apr 09 2013 This is surely not so terrible -- it leaves the door open for a new keyw...
- =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= (8/9) Apr 09 2013 It's not a keyword. It's inferred by the compiler when a function is
- Jacob Carlborg (4/7) Apr 08 2013 Multiple calls to pure functions could be cached.
- Manu (3/9) Apr 08 2013 Not if it can still make external assignments though. pure in D is
- David Nadlinger (6/9) Apr 08 2013 A lie? It's merely a different definition, and the stronger
- Jacob Carlborg (5/7) Apr 08 2013 I'm taking about strong pure, whatever the difference is. I thought the
- deadalnix (2/9) Apr 08 2013 As D have identity semantic, this isn't that simple.
- Iain Buclaw (45/53) Apr 08 2013 Not always, but in some circumstances, yes.
- Jacob Carlborg (4/33) Apr 08 2013 I though that wasn't possible. What's the point of pure if that's possib...
- Dicebot (3/5) Apr 08 2013 Looks like one of problems that exist because "weakly pure" and
- Timon Gehr (16/58) Apr 08 2013 Foo.bar can be used in a strongly pure computation. It is superficially
- Simen Kjaeraas (21/64) Apr 08 2013 Like others have stated, it's so you can do this:
- Jacob Carlborg (4/22) Apr 08 2013 I see.
- David Nadlinger (8/11) Apr 08 2013 Why should it?
- Dicebot (3/14) Apr 08 2013 What will you do if you want to make Foo.bar _strongly_ pure and
- deadalnix (3/50) Apr 08 2013 You have to think that this is an hidden parameter. The function
- Artur Skawina (21/25) Apr 09 2013 D's pure is horribly misnamed; nobody that's not already aware of the
- Timon Gehr (2/21) Apr 09 2013 I'd counter that it is pure by the D definition.
- kenji hara (7/11) Apr 09 2013 I completely agree with Timon. It's the definition in D.
- Artur Skawina (6/20) Apr 09 2013 A function that both directly depends on global mutable state (and
- =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= (10/14) Apr 09 2013 Functions that are pure may only mutate mutable state explicitly passed
- Timon Gehr (4/16) Apr 09 2013 pure notReferentiallyTransparent(){ // forall vacuously true
- Artur Skawina (14/23) Apr 09 2013 struct S;
- Tobias Pankrath (2/15) Apr 09 2013 Dunno, how this makes an example if you use at least 2, probably
- Timon Gehr (2/23) Apr 09 2013 No. What is the point?
- Artur Skawina (14/41) Apr 09 2013 I'm exploring the D purity definition given above, which is either
- Manu (2/46) Apr 09 2013 Precisely >_<
- Joseph Rushton Wakeling (3/17) Apr 09 2013 ... one clear application of this being pseudo-random number generation,...
- Manu (3/22) Apr 09 2013 There's nothing 'pure' about a function that has side effects. It's a
- David Nadlinger (9/12) Apr 09 2013 It's not totally different – the possible side effects are still
- Timon Gehr (7/11) Apr 09 2013 If it has the same side effects every time it is called with the same
- Manu (5/13) Apr 09 2013 But it doesn't. It could do anything when called a second time, same
- Timon Gehr (6/17) Apr 09 2013 Well, no. That's the point.
- David Nadlinger (3/6) Apr 09 2013 Can it?
- Joseph Rushton Wakeling (14/16) Apr 09 2013 But a natural way to define a pseudo-random number generator is a combin...
- Walter Bright (3/5) Apr 10 2013 Sure there is. Declare the function as pure, and the function's paramete...
- Joseph Rushton Wakeling (7/9) Apr 11 2013 Sure, I accept that. What I was meaning, though, was an up-front declar...
- deadalnix (3/17) Apr 11 2013 Both are strongly pure.
- =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= (7/26) Apr 11 2013 That's not the point. The point is, if he'd written this:
- Jacob Carlborg (5/9) Apr 11 2013 What's the point of that. Just have "strong" mean const/immutable
- Joseph Rushton Wakeling (4/5) Apr 11 2013 The point is to have a way for me, the programmer, to say to the compile...
- Jacob Carlborg (5/8) Apr 11 2013 Why should I have to explicitly specify "immutable" when that could be
- Joseph Rushton Wakeling (4/6) Apr 11 2013 Oh, sorry, I misunderstood your meaning. I thought you were saying that...
- Iain Buclaw (10/18) Apr 11 2013 I think that giving the user choice of purity is about as useful as give...
- Jacob Carlborg (6/11) Apr 11 2013 Beside from optimizations, it could good to be able to mark functions as...
- Joseph Rushton Wakeling (8/12) Apr 11 2013 Well, I don't mean the compiler should guarantee that my code will be op...
- John Colvin (6/27) Apr 11 2013 is foo strongly pure because of n being a value type that cannot
- kenji hara (13/43) Apr 11 2013 It is same for structs that has no *mutable* indirections. In below, all
- John Colvin (2/60) Apr 11 2013 right, gotcha!
- deadalnix (3/32) Apr 11 2013 I don't know what the current implementation says, but it should
- Joseph Rushton Wakeling (5/6) Apr 11 2013 Perhaps the fact that I can have this misunderstanding is itself an argu...
- Iain Buclaw (9/38) Apr 11 2013 e:
- Joseph Rushton Wakeling (2/4) Apr 11 2013 "Compiler says no ..."
- Iain Buclaw (8/16) Apr 08 2013 Or a better example that could also be pure in the 'C' sense.
- bearophile (35/35) May 02 2013 To: NG D
I remember Walter saying two or more times that the semantics of D offers some optimization opportunities that probably are not yet used to try to reduce the run-time of D programs. Is Walter willing to write down a list of such opportunities? (Ideas from other persons are welcome). Maybe some LDC/GDC developer will make the GCC/LLVM back-ends use them. The implementation of those ideas will require some time, so later it's better to put the list in the D wiki. Bye, bearophile
Apr 06 2013
On 6 April 2013 12:09, bearophile <bearophileHUGS lycos.com> wrote:I remember Walter saying two or more times that the semantics of D offers some optimization opportunities that probably are not yet used to try to reduce the run-time of D programs. Is Walter willing to write down a list of such opportunities? (Ideas from other persons are welcome). Maybe some LDC/GDC developer will make the GCC/LLVM back-ends use them. The implementation of those ideas will require some time, so later it's better to put the list in the D wiki. Bye, bearophileThis information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Apr 08 2013
On 04/08/2013 10:29 AM, Iain Buclaw wrote:On 6 April 2013 12:09, bearophile <bearophileHUGS lycos.com <mailto:bearophileHUGS lycos.com>> wrote: I remember Walter saying two or more times that the semantics of D offers some optimization opportunities that probably are not yet used to try to reduce the run-time of D programs. Is Walter willing to write down a list of such opportunities? (Ideas from other persons are welcome). Maybe some LDC/GDC developer will make the GCC/LLVM back-ends use them. The implementation of those ideas will require some time, so later it's better to put the list in the D wiki. Bye, bearophile This information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';Does GDC use the additional type information for optimization? Eg. if something is immutable, then aliasing issues do not have to be considered for it when reading and writing through multiple pointers repeatedly.
Apr 08 2013
On 8 April 2013 10:06, Timon Gehr <timon.gehr gmx.ch> wrote:On 04/08/2013 10:29 AM, Iain Buclaw wrote:It uses some type information, eg: const/immutable/wild -> qualified const. shared -> qualified volatile. shared + const/wild -> qualified const/volatile. Done nothing in regards to C 'restrict' optimisations. However the D array .ptr type could also be considered 'restrict' also. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';On 6 April 2013 12:09, bearophile <bearophileHUGS lycos.com <mailto:bearophileHUGS lycos.**com <bearophileHUGS lycos.com>>> wrote: I remember Walter saying two or more times that the semantics of D offers some optimization opportunities that probably are not yet used to try to reduce the run-time of D programs. Is Walter willing to write down a list of such opportunities? (Ideas from other persons are welcome). Maybe some LDC/GDC developer will make the GCC/LLVM back-ends use them. The implementation of those ideas will require some time, so later it's better to put the list in the D wiki. Bye, bearophile This information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';Does GDC use the additional type information for optimization? Eg. if something is immutable, then aliasing issues do not have to be considered for it when reading and writing through multiple pointers repeatedly.
Apr 08 2013
On Monday, 8 April 2013 at 09:41:52 UTC, Iain Buclaw wrote:It uses some type information, eg: const/immutable/wild -> qualified const. shared -> qualified volatile. shared + const/wild -> qualified const/volatile.const/wild can be muted via aliasing. I'm not sure how GCC's backend understand const, but this seems unclear to me if this is correct.Done nothing in regards to C 'restrict' optimisations. However the D array .ptr type could also be considered 'restrict' also.slices can alias each other. Same as above, is that correct ?
Apr 08 2013
On 8 April 2013 12:41, deadalnix <deadalnix gmail.com> wrote:On Monday, 8 April 2013 at 09:41:52 UTC, Iain Buclaw wrote:GCC's backend is pretty much C/C++ semantics. So the const qualifier is shallow, and does not guarantee that no mutations will occur. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';It uses some type information, eg: const/immutable/wild -> qualified const. shared -> qualified volatile. shared + const/wild -> qualified const/volatile.const/wild can be muted via aliasing. I'm not sure how GCC's backend understand const, but this seems unclear to me if this is correct.
Apr 08 2013
On 8 April 2013 21:53, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 8 April 2013 12:41, deadalnix <deadalnix gmail.com> wrote:But D makes no further guarantee. I don't see how const in D is any different than const in C++ in that sense? That's basically the concept of const, it's not a useful concept for optimisation, only immutable is.On Monday, 8 April 2013 at 09:41:52 UTC, Iain Buclaw wrote:GCC's backend is pretty much C/C++ semantics. So the const qualifier is shallow, and does not guarantee that no mutations will occur.It uses some type information, eg: const/immutable/wild -> qualified const. shared -> qualified volatile. shared + const/wild -> qualified const/volatile.const/wild can be muted via aliasing. I'm not sure how GCC's backend understand const, but this seems unclear to me if this is correct.
Apr 08 2013
On Monday, 8 April 2013 at 12:39:58 UTC, Manu wrote:On 8 April 2013 21:53, Iain Buclaw <ibuclaw ubuntu.com> wrote:D const is transitive, surely that makes a difference/presents an opportunity?On 8 April 2013 12:41, deadalnix <deadalnix gmail.com> wrote:But D makes no further guarantee. I don't see how const in D is any different than const in C++ in that sense? That's basically the concept of const, it's not a useful concept for optimisation, only immutable is.On Monday, 8 April 2013 at 09:41:52 UTC, Iain Buclaw wrote:GCC's backend is pretty much C/C++ semantics. So the const qualifier is shallow, and does not guarantee that no mutations will occur.It uses some type information, eg: const/immutable/wild -> qualified const. shared -> qualified volatile. shared + const/wild -> qualified const/volatile.const/wild can be muted via aliasing. I'm not sure how GCC's backend understand const, but this seems unclear to me if this is correct.
Apr 08 2013
On 8 April 2013 23:01, John Colvin <john.loughran.colvin gmail.com> wrote:On Monday, 8 April 2013 at 12:39:58 UTC, Manu wrote:No, I think that just makes it 'safer', or as many might say, "more annoying" ;)On 8 April 2013 21:53, Iain Buclaw <ibuclaw ubuntu.com> wrote: On 8 April 2013 12:41, deadalnix <deadalnix gmail.com> wrote:D const is transitive, surely that makes a difference/presents an opportunity?On Monday, 8 April 2013 at 09:41:52 UTC, Iain Buclaw wrote:But D makes no further guarantee. I don't see how const in D is any different than const in C++ in that sense? That's basically the concept of const, it's not a useful concept for optimisation, only immutable is.It uses some type information, eg:is shallow, and does not guarantee that no mutations will occur.const/immutable/wild -> qualified const. shared -> qualified volatile. shared + const/wild -> qualified const/volatile. const/wild can be muted via aliasing. I'm not sure how GCC's backendunderstand const, but this seems unclear to me if this is correct. GCC's backend is pretty much C/C++ semantics. So the const qualifier
Apr 08 2013
Casting away D const is undefined behavior. It is still not for single-threaded C++11 code AFAIK. That may make an important difference for optimization opportunities.
Apr 08 2013
On Monday, 8 April 2013 at 13:13:22 UTC, Dicebot wrote:Casting away D const is undefined behavior. It is still not for single-threaded C++11 code AFAIK. That may make an important difference for optimization opportunities.Minor fix: It is undefined in C++11 to cast away const from pointer to data immutable by definition (like string literals), but that can't be known from function that accepts const argument.
Apr 08 2013
On Monday, 8 April 2013 at 13:13:22 UTC, Dicebot wrote:Casting away D const is undefined behavior. It is still not for single-threaded C++11 code AFAIK. That may make an important difference for optimization opportunities.Minor correction, it is undefined to modify a const reference.
Apr 08 2013
On 4/8/2013 5:39 AM, Manu wrote:But D makes no further guarantee. I don't see how const in D is any different than const in C++ in that sense? That's basically the concept of const, it's not a useful concept for optimisation, only immutable is.In C++, it is legal to cast away const and mutate it. That is undefined behavior in D. A D compiler can assume, for example, that a const reference passed to a pure function will not mutate that reference, nor anything transitively referred to by that reference. No such assumption can be made like that in C++.
Apr 08 2013
On 2013-04-09 05:30, Walter Bright wrote:In C++, it is legal to cast away const and mutate it. That is undefined behavior in D.Didn't they change how const behaves in C++11, I'm thinking of this: http://channel9.msdn.com/posts/C-and-Beyond-2012-Herb-Sutter-You-dont-know-blank-and-blank -- /Jacob Carlborg
Apr 09 2013
On Tuesday, 9 April 2013 at 07:11:02 UTC, Jacob Carlborg wrote:On 2013-04-09 05:30, Walter Bright wrote:Yes, but it is changed only for multi-threaded code (because the very concept of concurrency is defined first in C++11). Single-thread semantics remain the same.In C++, it is legal to cast away const and mutate it. That is undefined behavior in D.Didn't they change how const behaves in C++11, I'm thinking of this: http://channel9.msdn.com/posts/C-and-Beyond-2012-Herb-Sutter-You-dont-know-blank-and-blank
Apr 09 2013
On 9 April 2013 13:30, Walter Bright <newshound2 digitalmars.com> wrote:On 4/8/2013 5:39 AM, 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.But D makes no further guarantee. I don't see how const in D is any different than const in C++ in that sense? That's basically the concept of const, it's not a useful concept for optimisation, only immutable is.In C++, it is legal to cast away const and mutate it. That is undefined behavior in D. A D compiler can assume, for example, that a const reference passed to a pure function will not mutate that reference, nor anything transitively referred to by that reference. No such assumption can be made like that in C++.
Apr 09 2013
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.
Apr 09 2013
On 9 April 2013 17:54, Dicebot <m.strashun gmail.com> wrote:On Tuesday, 9 April 2013 at 07:52:20 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.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.
Apr 09 2013
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? :)
Apr 09 2013
On 9 April 2013 18:03, Dicebot <m.strashun gmail.com> wrote:On Tuesday, 9 April 2013 at 08:00:38 UTC, Manu wrote: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 byErrrm, 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.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 inD now? :)It's almost a cruel joke. I try not to show that to people when I show them D ;)
Apr 09 2013
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.
Apr 09 2013
On 4/9/2013 1:00 AM, Manu wrote:Locals or allocated memory are not thread-local, can be passed wherever they want, including other threads.Not unless they are marked as "shared".
Apr 10 2013
On 4/9/2013 12:52 AM, 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?Sure: pure int bar(const int*); int foo(int* pt) { int t = *pt; // (1) int x = bar(&t); return t + // guaranteed to be same value as (1) x; } But the main purpose of const is so that you can have a single function that can operate on both mutable and immutable references. Otherwise, you'd have to do the copy/pasta two-step and write two functions.
Apr 10 2013
On 04/09/2013 05:30 AM, Walter Bright wrote:On 4/8/2013 5:39 AM, Manu wrote:The back end can assume this only if the DMD front end does its homework. It doesn't, probably because the spec does not formalize the type checking rules. There are plenty cases where a pure function can mutate something transitively referenced by some argument in safe code, even if all arguments are qualified const. eg. http://d.puremagic.com/issues/show_bug.cgi?id=9149But D makes no further guarantee. I don't see how const in D is any different than const in C++ in that sense? That's basically the concept of const, it's not a useful concept for optimisation, only immutable is.In C++, it is legal to cast away const and mutate it. That is undefined behavior in D. A D compiler can assume, for example, that a const reference passed to a pure function will not mutate that reference, nor anything transitively referred to by that reference. No such assumption can be made like that in C++.
Apr 09 2013
On Tuesday, 9 April 2013 at 03:36:28 UTC, Walter Bright wrote:On 4/8/2013 5:39 AM, Manu wrote:No, D have holes in its type system and so can't ensure anything. It has been show many many many times, especially by Timon and myself, and I'm kind of fed up to have to repeat that again and again, especiallt since fix proposal have recieved no attention at all. Stop claiming that such possibility exists, or take a serious look at how to really ensure it.But D makes no further guarantee. I don't see how const in D is any different than const in C++ in that sense? That's basically the concept of const, it's not a useful concept for optimisation, only immutable is.In C++, it is legal to cast away const and mutate it. That is undefined behavior in D. A D compiler can assume, for example, that a const reference passed to a pure function will not mutate that reference, nor anything transitively referred to by that reference. No such assumption can be made like that in C++.
Apr 09 2013
"deadalnix" <deadalnix gmail.com> wrote in message news:yhvwbephdechjxvrkyal forum.dlang.org...No, D have holes in its type system and so can't ensure anything. It has been show many many many times, especially by Timon and myself, and I'm kind of fed up to have to repeat that again and again, especiallt since fix proposal have recieved no attention at all. Stop claiming that such possibility exists, or take a serious look at how to really ensure it.The const/pure etc systems are based on certain guarantees, and places where they can be broken are bugs. These bugs DO NOT change what optimization opportunities are allowed by the original guarantees. Stop claiming they do.
Apr 09 2013
On Tuesday, 9 April 2013 at 10:57:20 UTC, Daniel Murphy wrote:"deadalnix" <deadalnix gmail.com> wrote in message news:yhvwbephdechjxvrkyal forum.dlang.org...Right now it isn't bugs as it is how thing are defined. And will be as long as no DIP solving this issue is accepted (at which point it will become a bug).No, D have holes in its type system and so can't ensure anything. It has been show many many many times, especially by Timon and myself, and I'm kind of fed up to have to repeat that again and again, especiallt since fix proposal have recieved no attention at all. Stop claiming that such possibility exists, or take a serious look at how to really ensure it.The const/pure etc systems are based on certain guarantees, and places where they can be broken are bugs. These bugs DO NOT change what optimization opportunities are allowed by the original guarantees. Stop claiming they do.
Apr 09 2013
On 04/09/2013 12:57 PM, Daniel Murphy wrote:"deadalnix" <deadalnix gmail.com> wrote in message news:yhvwbephdechjxvrkyal forum.dlang.org...That is certainly true, but mostly so because basically the only thing that appears to be documented in the case of const are the guarantees themselves. In this case, it is pretty clear that a type system that actually ensures that the guarantees in the spec hold could be created, but I guess deadalnix dislikes the general scheme of: A: I have developed an algorithm that solves 3-SAT in linear time. B: It does not work. A: Please report this to the bug tracker. A: I have developed an algorithm that solves 3-SAT in linear time.No, D have holes in its type system and so can't ensure anything. It has been show many many many times, especially by Timon and myself, and I'm kind of fed up to have to repeat that again and again, especiallt since fix proposal have recieved no attention at all. Stop claiming that such possibility exists, or take a serious look at how to really ensure it.The const/pure etc systems are based on certain guarantees, and places where they can be broken are bugs. These bugs DO NOT change what optimization opportunities are allowed by the original guarantees. Stop claiming they do.
Apr 09 2013
On 9 April 2013 20:57, Daniel Murphy <yebblies nospamgmail.com> wrote:"deadalnix" <deadalnix gmail.com> wrote in message news:yhvwbephdechjxvrkyal forum.dlang.org...The only optimisation possibility is for strong pure functions that are also nothrow, right? Was that the conditions for pure function refactoring?No, D have holes in its type system and so can't ensure anything. It has been show many many many times, especially by Timon and myself, and I'm kind of fed up to have to repeat that again and again, especiallt since fix proposal have recieved no attention at all. Stop claiming that such possibility exists, or take a serious look at how to really ensure it.The const/pure etc systems are based on certain guarantees, and places where they can be broken are bugs. These bugs DO NOT change what optimization opportunities are allowed by the original guarantees. Stop claiming they do.
Apr 09 2013
On 04/09/2013 01:27 PM, Manu wrote:... The only optimisation possibility is for strong pure functions that are also nothrow, right? Was that the conditions for pure function refactoring?No, strongly pure functions will always throw the same classes of exceptions when called with the same arguments. Therefore, with some flow-analysis, common subexpression elimination can apply to strongly pure functions which are not nothrow. Eg, given int foo(int)pure;, the transformation from a = foo(2); b = foo(2); to a = foo(2); b = a; is valid.
Apr 09 2013
On 04/09/2013 01:39 PM, Timon Gehr wrote:On 04/09/2013 01:27 PM, Manu wrote:and int a,b;,... The only optimisation possibility is for strong pure functions that are also nothrow, right? Was that the conditions for pure function refactoring?No, strongly pure functions will always throw the same classes of exceptions when called with the same arguments. Therefore, with some flow-analysis, common subexpression elimination can apply to strongly pure functions which are not nothrow. Eg, given int foo(int)pure;,the transformation from a = foo(2); b = foo(2); to a = foo(2); b = a; is valid.
Apr 09 2013
On Tuesday, 9 April 2013 at 11:27:57 UTC, Manu wrote:The only optimisation possibility is for strong pure functions that are also nothrow, right? Was that the conditions for pure function refactoring?No as no guarantee can exists as long as type qualifier transitivity isn't ensured.
Apr 09 2013
On 4/9/13 6:48 AM, deadalnix wrote:On Tuesday, 9 April 2013 at 03:36:28 UTC, Walter Bright wrote:Agreed. In parallel with work on improving quality, we also need to carefully address all holes in the type system. AndreiOn 4/8/2013 5:39 AM, Manu wrote:No, D have holes in its type system and so can't ensure anything. It has been show many many many times, especially by Timon and myself, and I'm kind of fed up to have to repeat that again and again, especiallt since fix proposal have recieved no attention at all. Stop claiming that such possibility exists, or take a serious look at how to really ensure it.But D makes no further guarantee. I don't see how const in D is any different than const in C++ in that sense? That's basically the concept of const, it's not a useful concept for optimisation, only immutable is.In C++, it is legal to cast away const and mutate it. That is undefined behavior in D. A D compiler can assume, for example, that a const reference passed to a pure function will not mutate that reference, nor anything transitively referred to by that reference. No such assumption can be made like that in C++.
Apr 09 2013
On 4/9/2013 3:48 AM, deadalnix wrote:No, D have holes in its type system and so can't ensure anything. It has been show many many many times, especially by Timon and myself, and I'm kind of fed up to have to repeat that again and again, especiallt since fix proposal have recieved no attention at all. Stop claiming that such possibility exists, or take a serious look at how to really ensure it.Having a bug in the compiler doesn't mean the language design is full of holes.
Apr 10 2013
On 4/10/13 2:54 PM, Walter Bright wrote:On 4/9/2013 3:48 AM, deadalnix wrote:Unfortunately we have holes in the language definition, too. We can't afford to be glib about them. AndreiNo, D have holes in its type system and so can't ensure anything. It has been show many many many times, especially by Timon and myself, and I'm kind of fed up to have to repeat that again and again, especiallt since fix proposal have recieved no attention at all. Stop claiming that such possibility exists, or take a serious look at how to really ensure it.Having a bug in the compiler doesn't mean the language design is full of holes.
Apr 10 2013
On 04/10/2013 08:54 PM, Walter Bright wrote:On 4/9/2013 3:48 AM, deadalnix wrote:Generally it does not, but is it actually not full of holes in this case? Can you give a short wrap-up of what the original language design is for type checking delegate context pointers? We can only guess, because it is not specified and much of what DMD does there is obviously buggy. In the end, we'll be left with three compiler front ends that implement three distinct competing designs.No, D have holes in its type system and so can't ensure anything. It has been show many many many times, especially by Timon and myself, and I'm kind of fed up to have to repeat that again and again, especiallt since fix proposal have recieved no attention at all. Stop claiming that such possibility exists, or take a serious look at how to really ensure it.Having a bug in the compiler doesn't mean the language design is full of holes.
Apr 10 2013
On 4/10/2013 12:43 PM, Timon Gehr wrote:Generally it does not, but is it actually not full of holes in this case? Can you give a short wrap-up of what the original language design is for type checking delegate context pointers? We can only guess, because it is not specified and much of what DMD does there is obviously buggy. In the end, we'll be left with three compiler front ends that implement three distinct competing designs.Clearly, delegates should not be able to break purity, const, shared, etc. Any setup that allows that is broken.
Apr 10 2013
On 4/10/13 5:25 PM, Walter Bright wrote:On 4/10/2013 12:43 PM, Timon Gehr wrote:Yah, hence the holes :o). I think it's important to acknowledge that problems in the language definition exist and problems in the language implementation also exist. Both are important, but the former are more so because fixing them makes it possible to fix many of the implementation issues. AndreiGenerally it does not, but is it actually not full of holes in this case? Can you give a short wrap-up of what the original language design is for type checking delegate context pointers? We can only guess, because it is not specified and much of what DMD does there is obviously buggy. In the end, we'll be left with three compiler front ends that implement three distinct competing designs.Clearly, delegates should not be able to break purity, const, shared, etc. Any setup that allows that is broken.
Apr 10 2013
On 4/10/2013 2:28 PM, Andrei Alexandrescu wrote:On 4/10/13 5:25 PM, Walter Bright wrote:My point was that competing designs are very probably not necessary. We just need to pull on the string on what must be.On 4/10/2013 12:43 PM, Timon Gehr wrote:Yah, hence the holes :o). I think it's important to acknowledge that problems in the language definition exist and problems in the language implementation also exist. Both are important, but the former are more so because fixing them makes it possible to fix many of the implementation issues.Generally it does not, but is it actually not full of holes in this case? Can you give a short wrap-up of what the original language design is for type checking delegate context pointers? We can only guess, because it is not specified and much of what DMD does there is obviously buggy. In the end, we'll be left with three compiler front ends that implement three distinct competing designs.Clearly, delegates should not be able to break purity, const, shared, etc. Any setup that allows that is broken.
Apr 10 2013
On 04/10/2013 11:50 PM, Walter Bright wrote:... My point was that competing designs are very probably not necessary. We just need to pull on the string on what must be.Yes, IMO it is quite obvious how to do it. (transfer the meaning of the modifiers from member functions to local functions, disallow conversion to const for delegates and disallow loading a mutable delegate from a const receiver.) However, I think there are other opinions. There will probably always be as long as nothing is specified as the official behaviour.
Apr 10 2013
On 4/10/2013 10:44 PM, Timon Gehr wrote:On 04/10/2013 11:50 PM, Walter Bright wrote:A delegate works exactly like a member function call. It has an implicit 'this' pointer, and how the 'this' pointer is qualified, just like for a member function, determines how it works.... My point was that competing designs are very probably not necessary. We just need to pull on the string on what must be.Yes, IMO it is quite obvious how to do it. (transfer the meaning of the modifiers from member functions to local functions, disallow conversion to const for delegates and disallow loading a mutable delegate from a const receiver.) However, I think there are other opinions. There will probably always be as long as nothing is specified as the official behaviour.
Apr 10 2013
On 04/11/2013 07:48 AM, Walter Bright wrote:On 4/10/2013 10:44 PM, Timon Gehr wrote:That's still not sufficient as a specification. A member function may be qualified differently from the 'this' pointer and calling said member function may even be disallowed because of this. For delegates, the same syntax element is used for qualifying the context pointer and the function. Therefore delegates and member functions need to behave differently.On 04/10/2013 11:50 PM, Walter Bright wrote:A delegate works exactly like a member function call. It has an implicit 'this' pointer, and how the 'this' pointer is qualified, just like for a member function, determines how it works.... My point was that competing designs are very probably not necessary. We just need to pull on the string on what must be.Yes, IMO it is quite obvious how to do it. (transfer the meaning of the modifiers from member functions to local functions, disallow conversion to const for delegates and disallow loading a mutable delegate from a const receiver.) However, I think there are other opinions. There will probably always be as long as nothing is specified as the official behaviour.
Apr 11 2013
On Wednesday, 10 April 2013 at 18:54:15 UTC, Walter Bright wrote:On 4/9/2013 3:48 AM, deadalnix wrote:It is not about compiler bugs, it is about language definition. The issue has been explained over and over again, and DIP has been made about it already.No, D have holes in its type system and so can't ensure anything. It has been show many many many times, especially by Timon and myself, and I'm kind of fed up to have to repeat that again and again, especiallt since fix proposal have recieved no attention at all. Stop claiming that such possibility exists, or take a serious look at how to really ensure it.Having a bug in the compiler doesn't mean the language design is full of holes.
Apr 10 2013
On 8 April 2013 19:41, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 8 April 2013 10:06, Timon Gehr <timon.gehr gmx.ch> wrote:Yes, I was just about to bring up __restrict, there is probably good opportunity for that. Why do you suppose .ptr is restrict? One problem with D's slicing is it's very hard to assume __restrict on basically any arrays. I feel like 'scope' might imply a __restrict input... although the relationship is kinda backwards, so maybe not... How about pure? Is GDC able to factor pure function calls with the same arguments outside of loops, or eliminate consecutive calls? It's really tedious to do this by hand, and breaks code continuity. Particularly important in a language that supports properties, since they'll be accessed consecutively all the time. What about immutable? You said it qualifies const, which in C++ is absolutely meaningless in terms of optimisation potential; just because something is const, the source of the pointer can certainly be non-const somewhere else, which means C++ can't possibly factor const loads outside of loops, and must respect consecutive dereferences of the same pointer. immutable in D should certainly be able to be factored outside loops, so it is more meaningful than const, and actually has real optimisation potential. Can GCC actually express an immutable value? I remember there was a problem a while back that I brought to you about GDC generating stack frames unnecessarily for leaf functions, is that resolved? I haven't checked in a while. Does GDC have access to a GDC-specific __restrict attribute to tag stuff manually? I'm struggling to think where it can be automated...On 04/08/2013 10:29 AM, Iain Buclaw wrote:It uses some type information, eg: const/immutable/wild -> qualified const. shared -> qualified volatile. shared + const/wild -> qualified const/volatile. Done nothing in regards to C 'restrict' optimisations. However the D array .ptr type could also be considered 'restrict' also.On 6 April 2013 12:09, bearophile <bearophileHUGS lycos.com <mailto:bearophileHUGS lycos.**com <bearophileHUGS lycos.com>>> wrote: I remember Walter saying two or more times that the semantics of D offers some optimization opportunities that probably are not yet used to try to reduce the run-time of D programs. Is Walter willing to write down a list of such opportunities? (Ideas from other persons are welcome). Maybe some LDC/GDC developer will make the GCC/LLVM back-ends use them. The implementation of those ideas will require some time, so later it's better to put the list in the D wiki. Bye, bearophile This information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';Does GDC use the additional type information for optimization? Eg. if something is immutable, then aliasing issues do not have to be considered for it when reading and writing through multiple pointers repeatedly.
Apr 08 2013
On 04/08/2013 12:59 PM, Manu wrote:... Does GDC have access to a GDC-specific __restrict attribute to tag stuff manually? I'm struggling to think where it can be automated...As far as I can see, restrict can easily be applied to immutable data.
Apr 08 2013
On 8 April 2013 20:59, Manu <turkeyman gmail.com> wrote:Does GDC have access to a GDC-specific __restrict attribute to tag stuff manually? I'm struggling to think where it can be automated...I guess immutable is a subset of __restrict. It should definitely leverage at least 50% of __restrict's value to to mark immutable stuff as such.
Apr 08 2013
On 8 April 2013 11:59, Manu <turkeyman gmail.com> wrote:On 8 April 2013 19:41, Iain Buclaw <ibuclaw ubuntu.com> wrote:At least, many array operations, eg: a[] += b[]. Require the arrays not to be overlapping, so could do some optimisations based around that knowledge.On 8 April 2013 10:06, Timon Gehr <timon.gehr gmx.ch> wrote:Yes, I was just about to bring up __restrict, there is probably good opportunity for that. Why do you suppose .ptr is restrict? One problem with D's slicing is it's very hard to assume __restrict on basically any arrays. I feel like 'scope' might imply a __restrict input... although the relationship is kinda backwards, so maybe not...On 04/08/2013 10:29 AM, Iain Buclaw wrote:It uses some type information, eg: const/immutable/wild -> qualified const. shared -> qualified volatile. shared + const/wild -> qualified const/volatile. Done nothing in regards to C 'restrict' optimisations. However the D array .ptr type could also be considered 'restrict' also.On 6 April 2013 12:09, bearophile <bearophileHUGS lycos.com <mailto:bearophileHUGS lycos.**com <bearophileHUGS lycos.com>>> wrote: I remember Walter saying two or more times that the semantics of D offers some optimization opportunities that probably are not yet used to try to reduce the run-time of D programs. Is Walter willing to write down a list of such opportunities? (Ideas from other persons are welcome). Maybe some LDC/GDC developer will make the GCC/LLVM back-ends use them. The implementation of those ideas will require some time, so later it's better to put the list in the D wiki. Bye, bearophile This information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';Does GDC use the additional type information for optimization? Eg. if something is immutable, then aliasing issues do not have to be considered for it when reading and writing through multiple pointers repeatedly.How about pure? Is GDC able to factor pure function calls with the same arguments outside of loops, or eliminate consecutive calls? It's really tedious to do this by hand, and breaks code continuity. Particularly important in a language that supports properties, since they'll be accessed consecutively all the time.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.What about immutable? You said it qualifies const, which in C++ is absolutely meaningless in terms of optimisation potential; just because something is const, the source of the pointer can certainly be non-const somewhere else, which means C++ can't possibly factor const loads outside of loops, and must respect consecutive dereferences of the same pointer. immutable in D should certainly be able to be factored outside loops, so it is more meaningful than const, and actually has real optimisation potential. Can GCC actually express an immutable value?Other than saying that the type is const-qualified, the decl is set read-only, which only means to the backend that 'this decl may not be the lhs of an assignment.'I remember there was a problem a while back that I brought to you about GDC generating stack frames unnecessarily for leaf functions, is that resolved? I haven't checked in a while.It probably is if you re referring to the thread I'm thinking of. Does GDC have access to a GDC-specific __restrict attribute to tag stuffmanually? I'm struggling to think where it can be automated...Nope, but that can be added in using our new attribute syntax. :~) Regards -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Apr 08 2013
On 8 April 2013 21:46, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 8 April 2013 11:59, Manu <turkeyman gmail.com> wrote:What reason is there that these may not be overlapping?On 8 April 2013 19:41, Iain Buclaw <ibuclaw ubuntu.com> wrote:At least, many array operations, eg: a[] += b[]. Require the arrays not to be overlapping, so could do some optimisations based around that knowledge.On 8 April 2013 10:06, Timon Gehr <timon.gehr gmx.ch> wrote:Yes, I was just about to bring up __restrict, there is probably good opportunity for that. Why do you suppose .ptr is restrict? One problem with D's slicing is it's very hard to assume __restrict on basically any arrays. I feel like 'scope' might imply a __restrict input... although the relationship is kinda backwards, so maybe not...On 04/08/2013 10:29 AM, Iain Buclaw wrote:It uses some type information, eg: const/immutable/wild -> qualified const. shared -> qualified volatile. shared + const/wild -> qualified const/volatile. Done nothing in regards to C 'restrict' optimisations. However the D array .ptr type could also be considered 'restrict' also.On 6 April 2013 12:09, bearophile <bearophileHUGS lycos.com <mailto:bearophileHUGS lycos.**com <bearophileHUGS lycos.com>>> wrote: I remember Walter saying two or more times that the semantics of D offers some optimization opportunities that probably are not yet used to try to reduce the run-time of D programs. Is Walter willing to write down a list of such opportunities? (Ideas from other persons are welcome). Maybe some LDC/GDC developer will make the GCC/LLVM back-ends use them. The implementation of those ideas will require some time, so later it's better to put the list in the D wiki. Bye, bearophile This information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';Does GDC use the additional type information for optimization? Eg. if something is immutable, then aliasing issues do not have to be considered for it when reading and writing through multiple pointers repeatedly.How about pure? Is GDC able to factor pure function calls with the sameOh 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! >_< Does the front end know if the function actually DOES assign to any state? The compiler could easily work that out, and in the event it doesn't actually perform any such assignment, it could be marked pure for reals... What about immutable? You said it qualifies const, which in C++ isarguments outside of loops, or eliminate consecutive calls? It's really tedious to do this by hand, and breaks code continuity. Particularly important in a language that supports properties, since they'll be accessed consecutively all the time.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.Well tell the backend that it's restrict aswell, that will give the backend more opportunities where aliasing is a potential problem.absolutely meaningless in terms of optimisation potential; just because something is const, the source of the pointer can certainly be non-const somewhere else, which means C++ can't possibly factor const loads outside of loops, and must respect consecutive dereferences of the same pointer. immutable in D should certainly be able to be factored outside loops, so it is more meaningful than const, and actually has real optimisation potential. Can GCC actually express an immutable value?Other than saying that the type is const-qualified, the decl is set read-only, which only means to the backend that 'this decl may not be the lhs of an assignment.'I remember there was a problem a while back that I brought to you aboutSo, the sad truth is, with all of D's numerous keywords and explicit qualifications, there are actually NO potential optimisations available that C could not equally make use of. I can't believe that pure thing, that's seriously depressing! I forgot you could assign to state within pure functions. Why is that? It's not actually pure at all! I guess there's a little bonus if you tag immutable as restrict, but that's a disappointing sum total...GDC generating stack frames unnecessarily for leaf functions, is that resolved? I haven't checked in a while.It probably is if you re referring to the thread I'm thinking of. Does GDC have access to a GDC-specific __restrict attribute to tag stuffmanually? I'm struggling to think where it can be automated...Nope, but that can be added in using our new attribute syntax. :~)
Apr 08 2013
On Monday, 8 April 2013 at 12:37:48 UTC, Manu wrote:On 8 April 2013 21:46, Iain Buclaw <ibuclaw ubuntu.com> wrote:Iain, are you sure about that? (No offense, but you have been wrong about what GCC can/can't do in the past. :P) Could you maybe elaborate a bit and present a counterexample? It might also be a question of how the »as-if« rule is really defined for pure function calls. In any case, if the source is available, the LLVM optimizer is usually very good at figuring out »pure for reals« (inferring the LLVM 'readnone' attribute). Obviously, this doesn't help you when you are doing separate compilation, though. DavidOnly 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! >_< Does the front end know if the function actually DOES assign to any state? The compiler could easily work that out, and in the event it doesn't actually perform any such assignment, it could be marked pure for reals...
Apr 08 2013
On Monday, 8 April 2013 at 13:32:36 UTC, David Nadlinger wrote:On Monday, 8 April 2013 at 12:37:48 UTC, Manu wrote:(you also need nothrow, of course) DavidOn 8 April 2013 21:46, Iain Buclaw <ibuclaw ubuntu.com> wrote:Iain, are you sure about that?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. […]
Apr 08 2013
On 8 April 2013 14:32, David Nadlinger <see klickverbot.at> wrote:On Monday, 8 April 2013 at 12:37:48 UTC, Manu wrote::(On 8 April 2013 21:46, Iain Buclaw <ibuclaw ubuntu.com> 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! =e?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! >_< Does the front end know if the function actually DOES assign to any stat=..The compiler could easily work that out, and in the event it doesn't actually perform any such assignment, it could be marked pure for reals.=dIain, are you sure about that? (No offense, but you have been wrong about what GCC can/can't do in the past. :P) Could you maybe elaborate a bit an=present a counterexample? It might also be a question of how the =BBas-if==ABrule is really defined for pure function calls. In any case, if the source is available, the LLVM optimizer is usually very good at figuring out =BBpure for reals=AB (inferring the LLVM 'readn=one'attribute). Obviously, this doesn't help you when you are doing separate compilation, though. DavidSure about what? I don't even know what you are talking about. :o) <sic> --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
Apr 08 2013
Am Mon, 08 Apr 2013 15:32:35 +0200 schrieb "David Nadlinger" <see klickverbot.at>:On Monday, 8 April 2013 at 12:37:48 UTC, Manu wrote:e=20On 8 April 2013 21:46, Iain Buclaw <ibuclaw ubuntu.com> wrote:=20 Iain, are you sure about that? (No offense, but you have been=20 wrong about what GCC can/can't do in the past. :P) Could you=20 maybe elaborate a bit and present a counterexample? It might also=20 be a question of how the =C2=BBas-if=C2=AB rule is really defined for pur=Only builtins are pure in the sense of 'C'. Even functions=20 considered PUREstrong by the frontend may update an internal state, so=20 the rules just don't apply. Except for maybe global functions... In any=20 case, the only benefit you can reap from 'D pure' functions are that they are=20 more likely to be const-folded / inlined.Oh my god... ..... this is the most upsetting thing I've heard=20 all day! :( No really, I have been SOOOO excited for so long about this=20 optimisation potential in D! There's gotta be something that can be done! >_< Does the front end know if the function actually DOES assign to=20 any state? The compiler could easily work that out, and in the event it=20 doesn't actually perform any such assignment, it could be marked pure=20 for reals...function calls. =20 In any case, if the source is available, the LLVM optimizer is=20 usually very good at figuring out =C2=BBpure for reals=C2=AB (inferring t=he=20LLVM 'readnone' attribute). Obviously, this doesn't help you when=20 you are doing separate compilation, though. =20 DavidI guess he only meant that the pure attribute doesn't help much, especially when compared to the GCC __pure__ C attribute. Of course the backend might still figure out that a function is really pure if the source code is known, but that probably also applies to functions not marked as pure so there's not much benefit for the backend if a function is marked pure or not.
Apr 08 2013
Am Mon, 8 Apr 2013 22:37:33 +1000 schrieb Manu <turkeyman gmail.com>:And to make it even worse AFAICT D's nothrow is also meaningless for optimization. As you can still throw errors/throwables the backend gains nothing from nothrow. It still has to analyze a function to know if it is actually __NOTHROW__ in the gcc sense. I think there was at least one gdc bug related to this which only showed on ARM, but I'd have to check that again. http://bugzilla.gdcproject.org/show_bug.cgi?id=10 (Though admittedly I'm not sure if there's any optimization potential with nothrow)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! >_<
Apr 08 2013
On 4/8/2013 11:20 AM, Johannes Pfau wrote:(Though admittedly I'm not sure if there's any optimization potential with nothrow)There is. The setting up of the exception handling frames can be omitted, and eh frames prevent enregistering of many variables.
Apr 08 2013
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.
Apr 08 2013
On 9 April 2013 14:39, Walter Bright <newshound2 digitalmars.com> wrote:On 4/8/2013 5:37 AM, 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?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.
Apr 09 2013
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.
Apr 09 2013
On 9 April 2013 18:04, Dicebot <m.strashun gmail.com> wrote:On Tuesday, 9 April 2013 at 07:57:37 UTC, Manu wrote: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.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.
Apr 09 2013
On Tuesday, 9 April 2013 at 08:33:53 UTC, Manu wrote: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.It is "weak pure" because it can be called by "strong pure" functions without violating "strong pure" guarantees (not-pure-at-all functions can't). It is confusing indeed and I remember some questions on StackOverflow on topic. I think having separate keywords/attributes would have helped.
Apr 09 2013
On 04/09/2013 10:33 AM, Manu wrote:... 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.(Actually this is not the definition of impure.) In D, 'pure' forbids reading or writing of mutable static variables.I suggest that no D language newbie would ever reasonably expect that behaviour.Sure. Many keyword choices in D are unhelpful for newbies, or technically wrong. enum -> const catch -> handle do -> repeat for -> (no suggestion) const -> readonly inout -> (no suggestion) lazy -> byname pure -> (no suggestion) static -> (no suggestion) struct -> (no suggestion) throw -> raise / signal union -> (no suggestion)
Apr 09 2013
On 2013-04-09 12:24, Timon Gehr wrote:static -> (no suggestion)"static" has quite a lot of overloads as well. -- /Jacob Carlborg
Apr 09 2013
On Tuesday, 9 April 2013 at 10:24:45 UTC, Timon Gehr wrote:On 04/09/2013 10:33 AM, Manu wrote:for -> loop?... 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.(Actually this is not the definition of impure.) In D, 'pure' forbids reading or writing of mutable static variables.I suggest that no D language newbie would ever reasonably expect that behaviour.Sure. Many keyword choices in D are unhelpful for newbies, or technically wrong. enum -> const catch -> handle do -> repeat for -> (no suggestion) const -> readonly inout -> (no suggestion) lazy -> byname pure -> (no suggestion) static -> (no suggestion) struct -> (no suggestion) throw -> raise / signal union -> (no suggestion)
Apr 09 2013
On Tuesday, 9 April 2013 at 08:33:53 UTC, Manu wrote:On 9 April 2013 18:04, Dicebot <m.strashun gmail.com> wrote:The returned results are different because the parameters you are calling it with are different. Note that for member functions 'this' is also passed implicitly as a ref parameter. On the second call it has different value than on the first call. If you don't want to allow mutating 'this' you should make the function const, thus making the implicit 'this' parameter const ref.On Tuesday, 9 April 2013 at 07:57:37 UTC, Manu wrote: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.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.
Apr 09 2013
On 9 April 2013 21:30, tn <no email.com> wrote:On Tuesday, 9 April 2013 at 08:33:53 UTC, Manu wrote:Ah, yes. Good point. I don't know how I missed that point prior! Okay sir, I buy your argument! :)On 9 April 2013 18:04, Dicebot <m.strashun gmail.com> wrote: On Tuesday, 9 April 2013 at 07:57:37 UTC, Manu wrote:The returned results are different because the parameters you are calling it with are different. Note that for member functions 'this' is also passed implicitly as a ref parameter. On the second call it has different value than on the first call. If you don't want to allow mutating 'this' you should make the function const, thus making the implicit 'this' parameter const ref.Are you saying the example above is not actually valid code?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.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.
Apr 09 2013
On 4/9/2013 1:33 AM, Manu wrote: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.I explained it in another reply here. I agree that it is initially confusing. I was myself confused about it until Don set me straight!
Apr 10 2013
On Wednesday, 10 April 2013 at 18:24:22 UTC, Walter Bright wrote:On 4/9/2013 1:33 AM, Manu wrote:For some reason I was never confused by this issue, even though I'm clearly in the minority. I always thought 'pure' set up an isolated set of instructions which only behaved according to what it was given. So if I found out it could modify by reference, it didn't shake my basic idea of what it was supposed to do. As long as it modified in exactly the same way, it still seemed like a separate and predictable box.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.I explained it in another reply here. I agree that it is initially confusing. I was myself confused about it until Don set me straight!
Apr 10 2013
On Tue, 09 Apr 2013 10:33:45 +0200, Manu <turkeyman gmail.com> wrote:On 9 April 2013 18:04, Dicebot <m.strashun gmail.com> wrote:It's pure in the sense that it can be used inside (strongly) pure functions.On Tuesday, 9 April 2013 at 07:57:37 UTC, Manu wrote:How can 'weak pure' reasonably be called any kind of 'pure'?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.I suggest that no D language newbie would ever reasonably expect that behaviour.And with that, I absolutely have to agree. -- Simen
Apr 09 2013
On 4/9/13 4:43 AM, Simen Kjærås wrote:On Tue, 09 Apr 2013 10:33:45 +0200, Manu <turkeyman gmail.com> wrote:Me too. But then any innovation by definition has an element of surprise. AndreiI suggest that no D language newbie would ever reasonably expect that behaviour.And with that, I absolutely have to agree.
Apr 09 2013
On 4/9/13 4:04 AM, Dicebot wrote:On Tuesday, 9 April 2013 at 07:57:37 UTC, Manu wrote:s/body/signature/ s/Crap/Awesome/ AndreiAre 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.
Apr 09 2013
On Tuesday, 9 April 2013 at 12:56:04 UTC, Andrei Alexandrescu wrote:Not gonna argue latter but former is just wrong. struct Test { int a; pure int foo1() // strong pure { return 42; } pure int foo2() // weak pure { return a++; } } Signature is the same for both functions.It is valid code. It is "weak pure". "pure' keyword means both "strong pure" or "weak pure" depending on function body. Crap.s/body/signature/ s/Crap/Awesome/
Apr 09 2013
On Tuesday, 9 April 2013 at 13:49:12 UTC, Dicebot wrote:On Tuesday, 9 April 2013 at 12:56:04 UTC, Andrei Alexandrescu wrote:Think of all your member functions as non-member functions taking the object as a ref parameter. pure int foo1(ref Test this) { return 42; } shouldn't be strongly pure (as it can access mutable non local state).Not gonna argue latter but former is just wrong. struct Test { int a; pure int foo1() // strong pure { return 42; } pure int foo2() // weak pure { return a++; } } Signature is the same for both functions.It is valid code. It is "weak pure". "pure' keyword means both "strong pure" or "weak pure" depending on function body. Crap.s/body/signature/ s/Crap/Awesome/
Apr 09 2013
On Tuesday, 9 April 2013 at 14:06:31 UTC, Pelle Månsson wrote:shouldn't be strongly pure (as it can access mutable non local state).I was under impression that pure is about verifying what function actually does, not what it probably can.
Apr 09 2013
On Tue, 09 Apr 2013 16:15:40 +0200, Dicebot <m.strashun gmail.com> wrote= :On Tuesday, 9 April 2013 at 14:06:31 UTC, Pelle M=C3=A5nsson wrote:.shouldn't be strongly pure (as it can access mutable non local state)=I was under impression that pure is about verifying what function =actually does, not what it probably can.It's based purely on function signature, so we're dealing with possibles= in many cases. -- = Simen
Apr 09 2013
On Tuesday, 9 April 2013 at 14:50:58 UTC, Simen Kjærås wrote:On Tue, 09 Apr 2013 16:15:40 +0200, Dicebot <m.strashun gmail.com> wrote:You got me lost here again. Definition of pure in dlang.org says: "To that end, a pure function: * does not read or write any global or static mutable state * cannot call functions that are not pure * can override an impure function, but an impure function cannot override a pure one * is covariant with an impure function * cannot perform I/O" It is all about behavior, not function signature. And function that takes ref parameter and does not read/write it is pure by this list.On Tuesday, 9 April 2013 at 14:06:31 UTC, Pelle Månsson wrote:It's based purely on function signature, so we're dealing with possibles in many cases.shouldn't be strongly pure (as it can access mutable non local state).I was under impression that pure is about verifying what function actually does, not what it probably can.
Apr 09 2013
On 2013-04-09, 17:11, Dicebot wrote:On Tuesday, 9 April 2013 at 14:50:58 UTC, Simen Kj=C3=A6r=C3=A5s wrote=:On Tue, 09 Apr 2013 16:15:40 +0200, Dicebot <m.strashun gmail.com> =e).wrote:On Tuesday, 9 April 2013 at 14:06:31 UTC, Pelle M=C3=A5nsson wrote:shouldn't be strongly pure (as it can access mutable non local stat=I was under impression that pure is about verifying what function =lesactually does, not what it probably can.It's based purely on function signature, so we're dealing with possib==in many cases.You got me lost here again. Definition of pure in dlang.org says: "To =that end, a pure function: * does not read or write any global or static mutable state * cannot call functions that are not pure * can override an impure function, but an impure function cannot =override a pure one * is covariant with an impure function * cannot perform I/O" It is all about behavior, not function signature. And function that =takes ref parameter and does not read/write it is pure by this list.Indeed. The definition should be updated then, because it's the signatur= e that counts. Consider: int[] foo(int* p) pure; Given only this prototype, we can know that the function is weakly pure.= If a function body was required, we would know nothing more, are we to assume it is strongly pure because no mutation is evident? Of course we are not. In the same way, because D supports 'header' files= (files with implementation stripped out), the function signature must convey all the necessary information to say if a function is strongly pure or not. -- = Simen
Apr 09 2013
On 4/9/2013 7:50 AM, Simen Kjærås wrote:It's based purely on function signatureCorrect. (I should point out that there are cases where the compiler infers purity from the function body: 1. lambdas 2. template functions 3. auto functions )
Apr 10 2013
2013/4/9 Dicebot <m.strashun gmail.com>On Tuesday, 9 April 2013 at 12:56:04 UTC, Andrei Alexandrescu wrote:Both have weak pure. Purity is always calculated only from the function signature. If you make member function "strong pure", _at least_ it should be qualified with "immutable". pure int foo3() immutable // strong pure { return 10; } Kenji HaraIt is valid code. It is "weak pure". "pure' keyword means bothNot gonna argue latter but former is just wrong. struct Test { int a; pure int foo1() // strong pure { return 42; } pure int foo2() // weak pure { return a++; } } Signature is the same for both functions."strong pure" or "weak pure" depending on function body. Crap.s/body/signature/ s/Crap/Awesome/
Apr 09 2013
On Tuesday, 9 April 2013 at 13:49:12 UTC, Dicebot wrote:struct Test { int a; pure int foo1() // strong pure { return 42; } pure int foo2() // weak pure { return a++; } }Isn't it pure int foo1() const // strong pure
Apr 09 2013
On Tue, 09 Apr 2013 16:09:40 +0200, Jesse Phillips <Jessekphillips+d gmail.com> wrote:On Tuesday, 9 April 2013 at 13:49:12 UTC, Dicebot wrote:const is not sufficient, as someone else might have a mutable reference. immutable is needed. -- Simenstruct Test { int a; pure int foo1() // strong pure { return 42; } pure int foo2() // weak pure { return a++; } }Isn't it pure int foo1() const // strong pure
Apr 09 2013
On 4/9/2013 7:12 AM, Simen Kjærås wrote:const is not sufficient, as someone else might have a mutable reference. immutable is needed.const is sufficient for strongly pure, because another reference is not available to the function body, and so the function cannot mutate it.
Apr 10 2013
On Wednesday, 10 April 2013 at 18:33:26 UTC, Walter Bright wrote:On 4/9/2013 7:12 AM, Simen Kjærås wrote:No ! A delegate reached via parameters and called can mute them. call with const parameter can be considered strongly pure if the argument is immutable (granted we fix delegate transitivity issues).const is not sufficient, as someone else might have a mutable reference. immutable is needed.const is sufficient for strongly pure, because another reference is not available to the function body, and so the function cannot mutate it.
Apr 10 2013
On 4/10/2013 5:33 PM, deadalnix wrote:call with const parameter can be considered strongly pure if the argument is immutableThe argument doesn't need to be immutable because nobody can change it while the function is running.
Apr 10 2013
On 04/11/2013 02:41 AM, Walter Bright wrote:On 4/10/2013 5:33 PM, deadalnix wrote:(He has written DIP30. Under DIP30 this would no longer be the case.)call with const parameter can be considered strongly pure if the argument is immutableThe argument doesn't need to be immutable because nobody can change it while the function is running.
Apr 10 2013
On Thursday, 11 April 2013 at 00:41:01 UTC, Walter Bright wrote:On 4/10/2013 5:33 PM, deadalnix wrote:I explained the sentence just above how it is possible. Ignoring issue rarely help when it come to solve them.call with const parameter can be considered strongly pure if the argument is immutableThe argument doesn't need to be immutable because nobody can change it while the function is running.
Apr 11 2013
On 4/11/2013 3:02 AM, deadalnix wrote:On Thursday, 11 April 2013 at 00:41:01 UTC, Walter Bright wrote:The delegate issue is a known one, and can be solved, and is not relevant to this point.On 4/10/2013 5:33 PM, deadalnix wrote:I explained the sentence just above how it is possible. Ignoring issue rarely help when it come to solve them.call with const parameter can be considered strongly pure if the argument is immutableThe argument doesn't need to be immutable because nobody can change it while the function is running.
Apr 11 2013
On Thursday, 11 April 2013 at 17:52:43 UTC, Walter Bright wrote:On 4/11/2013 3:02 AM, deadalnix wrote:See Timon's post. Both are deeply linked.On Thursday, 11 April 2013 at 00:41:01 UTC, Walter Bright wrote:The delegate issue is a known one, and can be solved, and is not relevant to this point.On 4/10/2013 5:33 PM, deadalnix wrote:I explained the sentence just above how it is possible. Ignoring issue rarely help when it come to solve them.call with const parameter can be considered strongly pure if the argument is immutableThe argument doesn't need to be immutable because nobody can change it while the function is running.
Apr 11 2013
On 4/9/13 9:49 AM, Dicebot wrote:On Tuesday, 9 April 2013 at 12:56:04 UTC, Andrei Alexandrescu wrote:Both are weakly pure. AndreiNot gonna argue latter but former is just wrong. struct Test { int a; pure int foo1() // strong pure { return 42; } pure int foo2() // weak pure { return a++; } } Signature is the same for both functions.It is valid code. It is "weak pure". "pure' keyword means both "strong pure" or "weak pure" depending on function body. Crap.s/body/signature/ s/Crap/Awesome/
Apr 09 2013
On Tuesday, 9 April 2013 at 15:20:48 UTC, Andrei Alexandrescu wrote:And that is even more surprising as foo2 perfectly matches concept of pure and can be applied all possible optimizations to. It is weird. "weak pure" is useful only to implement "strong pure". "strong pure" is useful only if it can be statically enforced to provide some guarantees. "strong pure" is useless because it shares same annotation with "weak pure".Not gonna argue latter but former is just wrong. struct Test { int a; pure int foo1() // strong pure { return 42; } pure int foo2() // weak pure { return a++; } } Signature is the same for both functions.Both are weakly pure. Andrei
Apr 09 2013
On Tuesday, 9 April 2013 at 15:42:38 UTC, Dicebot wrote:On Tuesday, 9 April 2013 at 15:20:48 UTC, Andrei Alexandrescu wrote:Don't you mean foo1? I have no idea what i'm talking about but foo1 looks a lot more pure than foo2 to me.And that is even more surprising as foo2 perfectly matches concept of pureNot gonna argue latter but former is just wrong. struct Test { int a; pure int foo1() // strong pure { return 42; } pure int foo2() // weak pure { return a++; } } Signature is the same for both functions.Both are weakly pure. Andrei
Apr 09 2013
On Tuesday, 9 April 2013 at 15:52:36 UTC, John Colvin wrote:Don't you mean foo1? I have no idea what i'm talking about but foo1 looks a lot more pure than foo2 to me.foo1, of course, beg my pardon.
Apr 09 2013
On 4/9/13 11:42 AM, Dicebot wrote:On Tuesday, 9 April 2013 at 15:20:48 UTC, Andrei Alexandrescu wrote:I disagree about it being weird.And that is even more surprising as foo2 perfectly matches concept of pure and can be applied all possible optimizations to. It is weird.Not gonna argue latter but former is just wrong. struct Test { int a; pure int foo1() // strong pure { return 42; } pure int foo2() // weak pure { return a++; } } Signature is the same for both functions.Both are weakly pure. Andrei"weak pure" is useful only to implement "strong pure". "strong pure" is useful only if it can be statically enforced to provide some guarantees. "strong pure" is useless because it shares same annotation with "weak pure".I think it's a great design, very useful and innovative. Andrei
Apr 09 2013
On Tuesday, 9 April 2013 at 16:15:38 UTC, Andrei Alexandrescu wrote:Agree on it being great and innovative. But I fail to see usefulness with current design. Can you provide examples how current pure design allows for better code / optimizations?"weak pure" is useful only to implement "strong pure". "strong pure" is useful only if it can be statically enforced to provide some guarantees. "strong pure" is useless because it shares same annotation with "weak pure".I think it's a great design, very useful and innovative.
Apr 09 2013
On Tuesday, 9 April 2013 at 17:39:47 UTC, Dicebot wrote:On Tuesday, 9 April 2013 at 16:15:38 UTC, Andrei Alexandrescu wrote:Strongly pure functions can call weakly pure function while keeping its properties. So it loosen the constraint on strongly pure function while keeping the benefit.Agree on it being great and innovative. But I fail to see usefulness with current design. Can you provide examples how current pure design allows for better code / optimizations?"weak pure" is useful only to implement "strong pure". "strong pure" is useful only if it can be statically enforced to provide some guarantees. "strong pure" is useless because it shares same annotation with "weak pure".I think it's a great design, very useful and innovative.
Apr 09 2013
On Wednesday, 10 April 2013 at 01:37:35 UTC, deadalnix wrote:It does not answer my question. Why "pure" keyword is useful in D if it does not guarantee that compiler will verify functional purity of you code and does not guarantee relevant optimizations? Beauty of concept is useless without practical application.Agree on it being great and innovative. But I fail to see usefulness with current design. Can you provide examples how current pure design allows for better code / optimizations?Strongly pure functions can call weakly pure function while keeping its properties. So it loosen the constraint on strongly pure function while keeping the benefit.
Apr 10 2013
On Wednesday, 10 April 2013 at 08:19:26 UTC, Dicebot wrote:On Wednesday, 10 April 2013 at 01:37:35 UTC, deadalnix wrote:It isn't beauty of concept. Strongly pure function exhibit from an external point of view the properties of pure as in functional programming.It does not answer my question. Why "pure" keyword is useful in D if it does not guarantee that compiler will verify functional purity of you code and does not guarantee relevant optimizations? Beauty of concept is useless without practical application.Agree on it being great and innovative. But I fail to see usefulness with current design. Can you provide examples how current pure design allows for better code / optimizations?Strongly pure functions can call weakly pure function while keeping its properties. So it loosen the constraint on strongly pure function while keeping the benefit.
Apr 10 2013
On Wednesday, 10 April 2013 at 11:22:41 UTC, deadalnix wrote:On Wednesday, 10 April 2013 at 08:19:26 UTC, Dicebot wrote:Except you can't be sure that your function is strongly pure with current design. Add ref parameter into the mix by accident and it will silently change to weak pure which is useless by its own.On Wednesday, 10 April 2013 at 01:37:35 UTC, deadalnix wrote:It isn't beauty of concept. Strongly pure function exhibit from an external point of view the properties of pure as in functional programming.It does not answer my question. Why "pure" keyword is useful in D if it does not guarantee that compiler will verify functional purity of you code and does not guarantee relevant optimizations? Beauty of concept is useless without practical application.Agree on it being great and innovative. But I fail to see usefulness with current design. Can you provide examples how current pure design allows for better code / optimizations?Strongly pure functions can call weakly pure function while keeping its properties. So it loosen the constraint on strongly pure function while keeping the benefit.
Apr 10 2013
On 4/10/13 7:29 AM, Dicebot wrote:On Wednesday, 10 April 2013 at 11:22:41 UTC, deadalnix wrote:I would venture that you are being confused. This seems to indicate insufficient documentation for 'pure'. AndreiOn Wednesday, 10 April 2013 at 08:19:26 UTC, Dicebot wrote:Except you can't be sure that your function is strongly pure with current design.On Wednesday, 10 April 2013 at 01:37:35 UTC, deadalnix wrote:It isn't beauty of concept. Strongly pure function exhibit from an external point of view the properties of pure as in functional programming.It does not answer my question. Why "pure" keyword is useful in D if it does not guarantee that compiler will verify functional purity of you code and does not guarantee relevant optimizations? Beauty of concept is useless without practical application.Agree on it being great and innovative. But I fail to see usefulness with current design. Can you provide examples how current pure design allows for better code / optimizations?Strongly pure functions can call weakly pure function while keeping its properties. So it loosen the constraint on strongly pure function while keeping the benefit.
Apr 10 2013
On Wednesday, 10 April 2013 at 11:29:42 UTC, Dicebot wrote:Except you can't be sure that your function is strongly pure with current design. Add ref parameter into the mix by accident and it will silently change to weak pure which is useless by its own.pure + immutable and value parameters == strongly pure (as in functional). It is really that simple.
Apr 10 2013
On 04/10/2013 05:43 PM, deadalnix wrote:On Wednesday, 10 April 2013 at 11:29:42 UTC, Dicebot wrote:pure notEntirely(){ return new Object(); } auto x = notEntirely(); assert(x is x); assert(notEntirely() !is notEntirely());Except you can't be sure that your function is strongly pure with current design. Add ref parameter into the mix by accident and it will silently change to weak pure which is useless by its own.pure + immutable and value parameters == strongly pure (as in functional). It is really that simple.
Apr 10 2013
On Wednesday, 10 April 2013 at 15:48:43 UTC, Timon Gehr wrote:On 04/10/2013 05:43 PM, deadalnix wrote:Yes, that is the entity vs value I discussed above n that thread. I should have said parameters AND return is a value.On Wednesday, 10 April 2013 at 11:29:42 UTC, Dicebot wrote:pure notEntirely(){ return new Object(); } auto x = notEntirely(); assert(x is x); assert(notEntirely() !is notEntirely());Except you can't be sure that your function is strongly pure with current design. Add ref parameter into the mix by accident and it will silently change to weak pure which is useless by its own.pure + immutable and value parameters == strongly pure (as in functional). It is really that simple.
Apr 10 2013
On Wednesday, 10 April 2013 at 15:52:23 UTC, deadalnix wrote:...And that is exactly what makes it useless. I need one keyword to automatically verify for me that parameters fine, that context is fine, return value is fine etc. This is the basic crucial concept and everything else should be built on top of it, not other way around. No one can say that my function is pure just by seeing keyword because I have probably forgot something. It is like saying that immutable is immutable only if you take care of some cases. Outstanding issue in my opinion.
Apr 10 2013
On Wednesday, 10 April 2013 at 17:12:27 UTC, Dicebot wrote:On Wednesday, 10 April 2013 at 15:52:23 UTC, deadalnix wrote:Then you'd need 2 keyword, and one would be completely redundant with information already present in the signature....And that is exactly what makes it useless. I need one keyword to automatically verify for me that parameters fine, that context is fine, return value is fine etc. This is the basic crucial concept and everything else should be built on top of it, not other way around. No one can say that my function is pure just by seeing keyword because I have probably forgot something. It is like saying that immutable is immutable only if you take care of some cases. Outstanding issue in my opinion.
Apr 10 2013
On 10 April 2013 00:07, kenji hara <k.hara.pg gmail.com> wrote:2013/4/9 Dicebot <m.strashun gmail.com>What is an immutable function? Why is const not sufficient?On Tuesday, 9 April 2013 at 12:56:04 UTC, Andrei Alexandrescu wrote:Both have weak pure. Purity is always calculated only from the function signature. If you make member function "strong pure", _at least_ it should be qualified with "immutable". pure int foo3() immutable // strong pure { return 10; } Kenji HaraIt is valid code. It is "weak pure". "pure' keyword means bothNot gonna argue latter but former is just wrong. struct Test { int a; pure int foo1() // strong pure { return 42; } pure int foo2() // weak pure { return a++; } } Signature is the same for both functions."strong pure" or "weak pure" depending on function body. Crap.s/body/signature/ s/Crap/Awesome/
Apr 09 2013
On 2013-04-09, 18:46, Manu wrote:What is an immutable function? Why is const not sufficient?Immutable requires that the struct/class be immutable, const may be called on mutable instances. Thus, the object may be changed in a different thread while the const function executes. Not so with immutable. -- Simen
Apr 09 2013
On Tuesday, 9 April 2013 at 16:55:07 UTC, Simen Kjaeraas wrote:On 2013-04-09, 18:46, Manu wrote:Not in other thread (as it would require to be shared or is undefined behavior) but vie delegate for instance.What is an immutable function? Why is const not sufficient?Immutable requires that the struct/class be immutable, const may be called on mutable instances. Thus, the object may be changed in a different thread while the const function executes. Not so with immutable.
Apr 09 2013
On 4/9/2013 6:49 AM, Dicebot wrote:Not gonna argue latter but former is just wrong. struct Test { int a; pure int foo1() // strong pure { return 42; } pure int foo2() // weak pure { return a++; } } Signature is the same for both functions.foo1 is weakly pure. It would be strongly pure if it were declared: const pure int foo1();
Apr 10 2013
On 4/9/2013 5:56 AM, Andrei Alexandrescu wrote:s/body/signature/ s/Crap/Awesome/I agree that the notions of strong/weak purity are awesome, I believe they are a D innovation, and if I recall correctly this innovation is thanks to Don Clugston, one of our most awesome contributors.
Apr 10 2013
On 4/9/2013 1:04 AM, Dicebot wrote:On Tuesday, 9 April 2013 at 07:57:37 UTC, Manu wrote:No, it is weakly or strongly pure based on the parameter types. bar(int n), for example, has an (implicit) mutable reference to 'this' in its parameter list. To be strongly pure, bar(int n) would have to be declared as: const pure int bar(int n); What the 'pure' keyword says is: "no reads/writes to mutable data from references that do not come through the parameters." Hence, if the parameters are all const or immutable, and it is marked pure, then the function is "strongly pure", meaning "no reads/writes to any externally visible mutable state". Notably, this is NOT determined by reading the function body, but by examining the parameter types. The reason for this behavior is so that strongly pure functions can call weakly pure struct/class methods, and yet remain strongly pure. Purity in D would be largely useless otherwise, as very very few functions could be strongly pure.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.
Apr 10 2013
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.
Apr 09 2013
On 04/09/2013 10:21 AM, Zach the Mystic wrote: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.Stepping outside from any controversy for now, I think I should say that these kind of in-depth discussions and explanations of the subtleties of language features (and programming theory in general) are one of the reasons I really, really enjoy being part of the D community. :-)
Apr 09 2013
On Tuesday, 9 April 2013 at 16:41:08 UTC, Joseph Rushton Wakeling wrote:On 04/09/2013 10:21 AM, Zach the Mystic wrote:Thanks, man! The truth is, compared to some of the heavyweights here, I'm very new to programming. That being said, I DO endeavor to really understand what's going on with the inner workings. I don't want anything to be mysterious which doesn't have to be!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.Stepping outside from any controversy for now, I think I should say that these kind of in-depth discussions and explanations of the subtleties of language features (and programming theory in general) are one of the reasons I really, really enjoy being part of the D community. :-)
Apr 09 2013
On 4/9/13 3:56 AM, 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.The values reachable from "this" are different in the two calls. Andrei
Apr 09 2013
On 2013-04-08, 13:46, Iain Buclaw 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.What?!? Please give an example of this. What sort of internal state are we talking about here? -- Simen
Apr 08 2013
On 8 April 2013 14:40, Simen Kjaeraas <simen.kjaras gmail.com> wrote:On 2013-04-08, 13:46, Iain Buclaw wrote: Only builtins are pure in the sense of 'C'. Even functions consideredIt might be weakly pure. ;) -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';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.What?!? Please give an example of this. What sort of internal state are we talking about here?
Apr 08 2013
On 8 April 2013 13:37, Manu <turkeyman gmail.com> wrote: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! >_< Does the front end know if the function actually DOES assign to any state? The compiler could easily work that out, and in the event it doesn't actually perform any such assignment, it could be marked pure for reals...Haven't looked, but it appears to have a general idea of this. D 'weak pure' and 'const pure' may update an internal state (had the latter bite me hard once). The only case where 'strong pure' might do this is by throwing an exception or an assert being thrown - this changes program state so can't be marked pure. So having identified this, we can safely say that functions could only be 'C pure' in the following case: - Compiled function is 'strong pure' - Compiled function is 'nothrow' - We are compiling in release mode. Only then we (the frontend) can safely say that 'this function has *absolutely* no side effects, so can be marked as pure'. Pure is never inferred. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Apr 08 2013
Am Mon, 8 Apr 2013 16:40:34 +0100 schrieb Iain Buclaw <ibuclaw ubuntu.com>:On 8 April 2013 13:37, Manu <turkeyman gmail.com> wrote:Can't a strong pure + nothrow + release mode function still throw errors? Or is this the "we don't guarantee anything regarding Errors" case and we just don't care?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! >_< Does the front end know if the function actually DOES assign to any state? The compiler could easily work that out, and in the event it doesn't actually perform any such assignment, it could be marked pure for reals...Haven't looked, but it appears to have a general idea of this. D 'weak pure' and 'const pure' may update an internal state (had the latter bite me hard once). The only case where 'strong pure' might do this is by throwing an exception or an assert being thrown - this changes program state so can't be marked pure. So having identified this, we can safely say that functions could only be 'C pure' in the following case: - Compiled function is 'strong pure' - Compiled function is 'nothrow' - We are compiling in release mode. Only then we (the frontend) can safely say that 'this function has *absolutely* no side effects, so can be marked as pure'. Pure is never inferred.
Apr 08 2013
On 9 April 2013 01:40, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 8 April 2013 13:37, Manu <turkeyman gmail.com> wrote:How does one specify that in their code? Is 'strong pure' a keyword?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! >_< Does the front end know if the function actually DOES assign to any state? The compiler could easily work that out, and in the event it doesn't actually perform any such assignment, it could be marked pure for reals...Haven't looked, but it appears to have a general idea of this. D 'weak pure' and 'const pure' may update an internal state (had the latter bite me hard once). The only case where 'strong pure' might do this is by throwing an exception or an assert being thrown - this changes program state so can't be marked pure. So having identified this, we can safely say that functions could only be 'C pure' in the following case: - Compiled function is 'strong pure' - Compiled function is 'nothrow' - We are compiling in release mode. Only then we (the frontend) can safely say that 'this function has *absolutely* no side effects, so can be marked as pure'. Pure is never inferred.
Apr 09 2013
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".
Apr 09 2013
On 04/09/2013 09:56 AM, Dicebot wrote: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".This is surely not so terrible -- it leaves the door open for a new keyword (strong pure actually seems quite good) which _does_ enforce that the function is strongly pure.
Apr 09 2013
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
Apr 09 2013
On 2013-04-08 10:29, Iain Buclaw wrote:This information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes.Multiple calls to pure functions could be cached. -- /Jacob Carlborg
Apr 08 2013
On 8 April 2013 22:25, Jacob Carlborg <doob me.com> wrote:On 2013-04-08 10:29, Iain Buclaw wrote: This information could possibly be helpful. Though given that most ofNot if it can still make external assignments though. pure in D is basically a lie! :,((gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes.Multiple calls to pure functions could be cached.
Apr 08 2013
On Monday, 8 April 2013 at 12:41:23 UTC, Manu wrote:Not if it can still make external assignments though. pure in D is basically a lie! :,(A lie? It's merely a different definition, and the stronger variant can easily – particularly be a compiler – be recovered by checking the argument types. But yes, 'pure' should probably be the default in D. David
Apr 08 2013
On 2013-04-08 14:41, Manu wrote:Not if it can still make external assignments though. pure in D is basically a lie! :,(I'm taking about strong pure, whatever the difference is. I thought the the definition of "pure" was that it cannot touch global/external scope. -- /Jacob Carlborg
Apr 08 2013
On Monday, 8 April 2013 at 12:25:01 UTC, Jacob Carlborg wrote:On 2013-04-08 10:29, Iain Buclaw wrote:As D have identity semantic, this isn't that simple.This information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes.Multiple calls to pure functions could be cached.
Apr 08 2013
On 8 April 2013 13:25, Jacob Carlborg <doob me.com> wrote:On 2013-04-08 10:29, Iain Buclaw wrote: This information could possibly be helpful. Though given that most ofNot always, but in some circumstances, yes. --- struct Foo { int a = 0; pure int bar (immutable int x) { ++a; return x * 2; } } void main() { Foo f; int i = f.bar(2) + f.bar(2); assert (i == 8); assert (f.a == 2); } --- Again, the characteristics of D pure functions mean that the backend can const-fold away the function entirely under normal optimisations. --- D main () { <bb 2>: return 0; } --- Possibly strongly-pure functions could be marked as pure in the 'C' sense, but only if they are also nothrow, eg to add to the above example: --- pure nothrow int baz (Foo f) { return f.bar(2) + f.bar(2); } --- Regards -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';(gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes.Multiple calls to pure functions could be cached. -- /Jacob Carlborg
Apr 08 2013
On 2013-04-08 14:52, Iain Buclaw wrote:On 8 April 2013 13:25, Jacob Carlborg <doob me.com <mailto:doob me.com>> wrote: On 2013-04-08 10:29, Iain Buclaw wrote: This information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes. Multiple calls to pure functions could be cached. -- /Jacob Carlborg Not always, but in some circumstances, yes. --- struct Foo { int a = 0; pure int bar (immutable int x) { ++a; return x * 2; } } void main() { Foo f; int i = f.bar(2) + f.bar(2); assert (i == 8); assert (f.a == 2); }I though that wasn't possible. What's the point of pure if that's possible? -- /Jacob Carlborg
Apr 08 2013
On Monday, 8 April 2013 at 15:07:31 UTC, Jacob Carlborg wrote:I though that wasn't possible. What's the point of pure if that's possible?Looks like one of problems that exist because "weakly pure" and "strongly pure" use the same keyword.
Apr 08 2013
On 04/08/2013 05:07 PM, Jacob Carlborg wrote:On 2013-04-08 14:52, Iain Buclaw wrote:Foo.bar can be used in a strongly pure computation. It is superficially similar to how state transformers allow mutable state in Haskell. If you want more guarantees, you could mark a member function const, inout or immutable pure. DIP30 removes some optimization potential for at least const pure. Furthermore, the exact meaning of inout will have to be determined. Unfortunately it is both useful to have a specifier that prevents mutation but allows to return a mutable part of the function input and to have a specifier that allows mutation in case the function input is in fact mutable. Unfortunately, DMD does not implement type checking for delegates in a meaningful way. The specifiers const/immutable/pure should have consistent meanings for member functions and functions nested inside functions. (http://d.puremagic.com/issues/show_bug.cgi?id=9148)On 8 April 2013 13:25, Jacob Carlborg <doob me.com <mailto:doob me.com>> wrote: On 2013-04-08 10:29, Iain Buclaw wrote: This information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes. Multiple calls to pure functions could be cached. -- /Jacob Carlborg Not always, but in some circumstances, yes. --- struct Foo { int a = 0; pure int bar (immutable int x) { ++a; return x * 2; } } void main() { Foo f; int i = f.bar(2) + f.bar(2); assert (i == 8); assert (f.a == 2); }I though that wasn't possible. What's the point of pure if that's possible?
Apr 08 2013
On 2013-04-08, 17:07, Jacob Carlborg wrote:On 2013-04-08 14:52, Iain Buclaw wrote:Like others have stated, it's so you can do this: struct Foo { int a = 0; pure int bar( int n ) { // Weakly pure a += n; return a; } } pure int Baz( int n ) { // Strongly pure Foo foo; return foo.bar( n ); } Foo.bar has only local mutability, so if the Foo originated in a (strongly) pure function, Foo.bar can be called inside that pure function without violating the purity requirement. The three levels (weakly pure/strongly pure/impure) are needed, but a redesign would perhaps use a different keyword for weakly pure. -- SimenOn 8 April 2013 13:25, Jacob Carlborg <doob me.com <mailto:doob me.com>> wrote: On 2013-04-08 10:29, Iain Buclaw wrote: This information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes. Multiple calls to pure functions could be cached. -- /Jacob Carlborg Not always, but in some circumstances, yes. --- struct Foo { int a = 0; pure int bar (immutable int x) { ++a; return x * 2; } } void main() { Foo f; int i = f.bar(2) + f.bar(2); assert (i == 8); assert (f.a == 2); }I though that wasn't possible. What's the point of pure if that's possible?
Apr 08 2013
On 2013-04-08 20:14, Simen Kjaeraas wrote:Like others have stated, it's so you can do this: struct Foo { int a = 0; pure int bar( int n ) { // Weakly pure a += n; return a; } } pure int Baz( int n ) { // Strongly pure Foo foo; return foo.bar( n ); } Foo.bar has only local mutability, so if the Foo originated in a (strongly) pure function, Foo.bar can be called inside that pure function without violating the purity requirement. The three levels (weakly pure/strongly pure/impure) are needed, but a redesign would perhaps use a different keyword for weakly pure.I see. -- /Jacob Carlborg
Apr 08 2013
On Monday, 8 April 2013 at 18:15:11 UTC, Simen Kjaeraas wrote:The three levels (weakly pure/strongly pure/impure) are needed, but a redesign would perhaps use a different keyword for weakly pure.Why should it? I mean, using another name for "pure" would arguably make sense, given the confusion it seems to have caused in the past. But if you are suggesting to differentiate between various "kinds of purity" on a keyword level, I'm not sure what benefits you are hoping to get. David
Apr 08 2013
On Monday, 8 April 2013 at 19:48:50 UTC, David Nadlinger wrote:On Monday, 8 April 2013 at 18:15:11 UTC, Simen Kjaeraas wrote:What will you do if you want to make Foo.bar _strongly_ pure and compiler to verify it?The three levels (weakly pure/strongly pure/impure) are needed, but a redesign would perhaps use a different keyword for weakly pure.Why should it? I mean, using another name for "pure" would arguably make sense, given the confusion it seems to have caused in the past. But if you are suggesting to differentiate between various "kinds of purity" on a keyword level, I'm not sure what benefits you are hoping to get. David
Apr 08 2013
On Monday, 8 April 2013 at 15:07:31 UTC, Jacob Carlborg wrote:On 2013-04-08 14:52, Iain Buclaw wrote:You have to think that this is an hidden parameter. The function touch that parameter, no global state.On 8 April 2013 13:25, Jacob Carlborg <doob me.com <mailto:doob me.com>> wrote: On 2013-04-08 10:29, Iain Buclaw wrote: This information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes. Multiple calls to pure functions could be cached. -- /Jacob Carlborg Not always, but in some circumstances, yes. --- struct Foo { int a = 0; pure int bar (immutable int x) { ++a; return x * 2; } } void main() { Foo f; int i = f.bar(2) + f.bar(2); assert (i == 8); assert (f.a == 2); }I though that wasn't possible. What's the point of pure if that's possible?
Apr 08 2013
On 04/09/13 02:44, deadalnix wrote:On Monday, 8 April 2013 at 15:07:31 UTC, Jacob Carlborg wrote:D's pure is horribly misnamed; nobody that's not already aware of the D re-definition expects "pure" to mean what it currently does. struct S { int* p; int f() pure safe nothrow { return ++*p; } } int i = 1; int main() { auto s = S(&i); assert(i==1); auto r = s.f(); assert(r==2); r = s.f(); assert(r==3); assert(i==3); return r; } That's not pure by any definition, and fixing it w/o impacting valid cases would be non-trivial (think array members). arturI though that wasn't possible. What's the point of pure if that's possible?You have to think that this is an hidden parameter. The function touch that parameter, no global state.
Apr 09 2013
On 04/09/2013 12:13 PM, Artur Skawina wrote:... D's pure is horribly misnamed; nobody that's not already aware of the D re-definition expects "pure" to mean what it currently does. struct S { int* p; int f() pure safe nothrow { return ++*p; } } int i = 1; int main() { auto s = S(&i); assert(i==1); auto r = s.f(); assert(r==2); r = s.f(); assert(r==3); assert(i==3); return r; } That's not pure by any definition,I'd counter that it is pure by the D definition.
Apr 09 2013
2013/4/9 Timon Gehr <timon.gehr gmx.ch>On 04/09/2013 12:13 PM, Artur Skawina wrote:[snip]I completely agree with Timon. It's the definition in D. The meaning of 'pure' keyword in D *contains* widely used "pure" meaning, rather than differ. The usefulness of the three purity (weak-const-strong) is still there, and the keyword choice for the concept is enough reasonable. Kenji HaraThat's not pure by any definition,I'd counter that it is pure by the D definition.
Apr 09 2013
On 04/09/13 12:51, kenji hara wrote:2013/4/9 Timon Gehr <timon.gehr gmx.ch <mailto:timon.gehr gmx.ch>> On 04/09/2013 12:13 PM, Artur Skawina wrote: [snip] That's not pure by any definition, I'd counter that it is pure by the D definition. I completely agree with Timon. It's the definition in D.A function that both directly depends on global mutable state (and modifies it) can hardly be called pure. Can you (anybody) give a D "pure" definition that allows for the program that I've posted and still makes "pure" useful? artur
Apr 09 2013
On Tue, 09 Apr 2013 13:10:16 +0200, Artur Skawina <art.08.09 gmail.com> wrote:A function that both directly depends on global mutable state (and modifies it) can hardly be called pure. Can you (anybody) give a D "pure" definition that allows for the program that I've posted and still makes "pure" useful?Functions that are pure may only mutate mutable state explicitly passed to them, or created within. There. That's basically all there is to D's pure. From this definition arise some useful properties, e.g. that a function whose parameters are all immutable or implicitly castable to immutable, is referentially transparent. -- Simen
Apr 09 2013
On 04/09/2013 01:47 PM, Simen Kjærås wrote:On Tue, 09 Apr 2013 13:10:16 +0200, Artur Skawina <art.08.09 gmail.com> wrote:pure notReferentiallyTransparent(){ // forall vacuously true return new Object(); }A function that both directly depends on global mutable state (and modifies it) can hardly be called pure. Can you (anybody) give a D "pure" definition that allows for the program that I've posted and still makes "pure" useful?Functions that are pure may only mutate mutable state explicitly passed to them, or created within. There. That's basically all there is to D's pure. From this definition arise some useful properties, e.g. that a function whose parameters are all immutable or implicitly castable to immutable, is referentially transparent.
Apr 09 2013
On 04/09/13 13:47, Simen Kjærås wrote:On Tue, 09 Apr 2013 13:10:16 +0200, Artur Skawina <art.08.09 gmail.com> wrote:struct S; int f(S* p) pure; S* n(); int g = 0; int main() { S* s = n(); f(s); return g; } Is main() guaranteed to return '0'? arturA function that both directly depends on global mutable state (and modifies it) can hardly be called pure. Can you (anybody) give a D "pure" definition that allows for the program that I've posted and still makes "pure" useful?Functions that are pure may only mutate mutable state explicitly passed to them, or created within.
Apr 09 2013
struct S; int f(S* p) pure; S* n(); int g = 0; int main() { S* s = n(); f(s); return g; } Is main() guaranteed to return '0'? arturDunno, how this makes an example if you use at least 2, probably 3 non pure functions (main, n, constructor of S).
Apr 09 2013
On 04/09/2013 03:18 PM, Artur Skawina wrote:On 04/09/13 13:47, Simen Kjærås wrote:No. What is the point?On Tue, 09 Apr 2013 13:10:16 +0200, Artur Skawina <art.08.09 gmail.com> wrote:struct S; int f(S* p) pure; S* n(); int g = 0; int main() { S* s = n(); f(s); return g; } Is main() guaranteed to return '0'? arturA function that both directly depends on global mutable state (and modifies it) can hardly be called pure. Can you (anybody) give a D "pure" definition that allows for the program that I've posted and still makes "pure" useful?Functions that are pure may only mutate mutable state explicitly passed to them, or created within.
Apr 09 2013
On 04/09/13 15:22, Timon Gehr wrote:On 04/09/2013 03:18 PM, Artur Skawina wrote:I'm exploring the D purity definition given above, which is either incorrect or extremely misleading. My example was bad though, as it had too many unstated assumptions. A better one would have been: struct S; int g; int f(S* p) pure; int h(S* s) { g = 0; f(s); return g; } // Is 'h' guaranteed to return '0'? Obviously, the answer is no. Yet this will be expected by anyone not aware of how "pure" works in D. Adding "const" would only change the R/W dep to a R/O one (IOW 'f' could still return different values depending on 'g'). arturOn 04/09/13 13:47, Simen Kjærås wrote:No. What is the point?On Tue, 09 Apr 2013 13:10:16 +0200, Artur Skawina <art.08.09 gmail.com> wrote:struct S; int f(S* p) pure; S* n(); int g = 0; int main() { S* s = n(); f(s); return g; } Is main() guaranteed to return '0'?A function that both directly depends on global mutable state (and modifies it) can hardly be called pure. Can you (anybody) give a D "pure" definition that allows for the program that I've posted and still makes "pure" useful?Functions that are pure may only mutate mutable state explicitly passed to them, or created within.
Apr 09 2013
On 9 April 2013 01:07, Jacob Carlborg <doob me.com> wrote:On 2013-04-08 14:52, Iain Buclaw wrote:Precisely >_<On 8 April 2013 13:25, Jacob Carlborg <doob me.com <mailto:doob me.com>> wrote: On 2013-04-08 10:29, Iain Buclaw wrote: This information could possibly be helpful. Though given that most of (gdc) codegen is on par with g++, there's probably not much on the list that isn't already detected by the backend optimisation passes. Multiple calls to pure functions could be cached. -- /Jacob Carlborg Not always, but in some circumstances, yes. --- struct Foo { int a = 0; pure int bar (immutable int x) { ++a; return x * 2; } } void main() { Foo f; int i = f.bar(2) + f.bar(2); assert (i == 8); assert (f.a == 2); }I though that wasn't possible. What's the point of pure if that's possible?
Apr 09 2013
On 04/08/2013 08:14 PM, Simen Kjaeraas wrote:Like others have stated, it's so you can do this: struct Foo { int a = 0; pure int bar( int n ) { // Weakly pure a += n; return a; } } pure int Baz( int n ) { // Strongly pure Foo foo; return foo.bar( n ); }... one clear application of this being pseudo-random number generation, where you have a state variable together with a (pure) update function.
Apr 09 2013
On 9 April 2013 19:43, Joseph Rushton Wakeling <joseph.wakeling webdrake.netwrote:On 04/08/2013 08:14 PM, Simen Kjaeraas wrote:There's nothing 'pure' about a function that has side effects. It's a totally different concept, and should be named appropriately.Like others have stated, it's so you can do this: struct Foo { int a = 0; pure int bar( int n ) { // Weakly pure a += n; return a; } } pure int Baz( int n ) { // Strongly pure Foo foo; return foo.bar( n ); }... one clear application of this being pseudo-random number generation, where you have a state variable together with a (pure) update function.
Apr 09 2013
On Tuesday, 9 April 2013 at 10:28:16 UTC, Manu wrote:There's nothing 'pure' about a function that has side effects. It's a totally different concept, and should be named appropriately.It's not totally different – the possible side effects are still very localized and controllable by the *caller* (not the callee). But yes, the name is a bit unfortunate, and has historical reasons. As to not repeat myself, I'll just link to an article I wrote a couple of months ago: http://klickverbot.at/blog/2012/05/purity-in-d/#weak_purity_allows_for_stronger_guarantees David
Apr 09 2013
On 04/09/2013 12:28 PM, Manu wrote:... There's nothing 'pure' about a function that has side effects.If it has the same side effects every time it is called with the same arguments, then there is something pure about it.It's a totally different concept,The concept of mutation can be expressed easily in a language not directly supporting side effects. Just pass around the store explicitly. The term you want to describe is presumably referential transparency.and should be named appropriately.I guess nobody will disagree with this.
Apr 09 2013
On 9 April 2013 20:50, Timon Gehr <timon.gehr gmx.ch> wrote:On 04/09/2013 12:28 PM, Manu wrote:But it doesn't. It could do anything when called a second time, same arguments or not. The only thing it can't do is escape a variable. That sounds more like 'scope' to me than 'pure'.... There's nothing 'pure' about a function that has side effects.If it has the same side effects every time it is called with the same arguments, then there is something pure about it.
Apr 09 2013
On 04/09/2013 01:26 PM, Manu wrote:On 9 April 2013 20:50, Timon Gehr <timon.gehr gmx.ch <mailto:timon.gehr gmx.ch>> wrote: On 04/09/2013 12:28 PM, Manu wrote: ... There's nothing 'pure' about a function that has side effects. If it has the same side effects every time it is called with the same arguments, then there is something pure about it. But it doesn't. It could do anything when called a second time, same arguments or not.Well, no. That's the point. Feel free to provide an example where you think this property is violated. (However, note that the concept of the 'same arguments', and the 'same side effects' is informal and would need a little clarification.)The only thing it can't do is escape a variable. That sounds more like 'scope' to me than 'pure'.That is not the only thing it can't do.
Apr 09 2013
On Tuesday, 9 April 2013 at 11:26:38 UTC, Manu wrote:But it doesn't. It could do anything when called a second time, same arguments or not.Can it? David
Apr 09 2013
On 04/09/2013 12:28 PM, Manu wrote:There's nothing 'pure' about a function that has side effects. It's a totally different concept, and should be named appropriately.But a natural way to define a pseudo-random number generator is a combination of a state variable together with a pure function that takes the current state variable and returns the next in the sequence -- see e.g.: http://www.cs.berkeley.edu/~mhoemmen/cs194/Tutorials/prng.pdf (Hope I'm not being condescending here, as I imagine you know the theory of this better than I do.) So, I'm not sure I see the disadvantage of allowing a slight relaxation in purity that allows one to combine the state variable and transition function together in a single struct -- which is pretty much analogous to what's happening in the given examples where a private variable is being incremented by a 'pure' function. I do agree that it's a great pity there is not a way to declare strong purity for D functions.
Apr 09 2013
On 4/9/2013 3:52 AM, Joseph Rushton Wakeling wrote:I do agree that it's a great pity there is not a way to declare strong purity for D functions.Sure there is. Declare the function as pure, and the function's parameters as const or immutable.
Apr 10 2013
On 04/10/2013 08:39 PM, Walter Bright wrote:Sure there is. Declare the function as pure, and the function's parameters as const or immutable.Sure, I accept that. What I was meaning, though, was an up-front declaration which would make the compiler shout if those necessary conditions were not met. i.e. pure foo(int n) { ... } // compiles strong pure bar(int n) { ... } // compiler instructs you to make // variables const or immutable
Apr 11 2013
On Thursday, 11 April 2013 at 08:36:13 UTC, Joseph Rushton Wakeling wrote:On 04/10/2013 08:39 PM, Walter Bright wrote:Both are strongly pure.Sure there is. Declare the function as pure, and the function's parameters as const or immutable.Sure, I accept that. What I was meaning, though, was an up-front declaration which would make the compiler shout if those necessary conditions were not met. i.e. pure foo(int n) { ... } // compiles strong pure bar(int n) { ... } // compiler instructs you to make // variables const or immutable
Apr 11 2013
On Thu, 11 Apr 2013 12:03:38 +0200, deadalnix <deadalnix gmail.com> wrote:On Thursday, 11 April 2013 at 08:36:13 UTC, Joseph Rushton Wakeling wrote:That's not the point. The point is, if he'd written this: strong pure bar(int* n) { ... } The compiler would have said 'Bad programmer! int* is not implicitly castable to immutable!' -- SimenOn 04/10/2013 08:39 PM, Walter Bright wrote:Both are strongly pure.Sure there is. Declare the function as pure, and the function's parameters as const or immutable.Sure, I accept that. What I was meaning, though, was an up-front declaration which would make the compiler shout if those necessary conditions were not met. i.e. pure foo(int n) { ... } // compiles strong pure bar(int n) { ... } // compiler instructs you to make // variables const or immutable
Apr 11 2013
On 2013-04-11 12:09, Simen Kjærås wrote:That's not the point. The point is, if he'd written this: strong pure bar(int* n) { ... } The compiler would have said 'Bad programmer! int* is not implicitly castable to immutable!'What's the point of that. Just have "strong" mean const/immutable parameters. -- /Jacob Carlborg
Apr 11 2013
On 04/11/2013 03:29 PM, Jacob Carlborg wrote:What's the point of that. Just have "strong" mean const/immutable parameters.The point is to have a way for me, the programmer, to say to the compiler: "I mean for this function to be strongly pure, can you confirm whether my choice of function inputs supports this please?"
Apr 11 2013
On 2013-04-11 15:38, Joseph Rushton Wakeling wrote:The point is to have a way for me, the programmer, to say to the compiler: "I mean for this function to be strongly pure, can you confirm whether my choice of function inputs supports this please?"Why should I have to explicitly specify "immutable" when that could be default for strongly pure functions? -- /Jacob Carlborg
Apr 11 2013
On 04/11/2013 08:16 PM, Jacob Carlborg wrote:Why should I have to explicitly specify "immutable" when that could be default for strongly pure functions?Oh, sorry, I misunderstood your meaning. I thought you were saying that a "strong pure" keyword wasn't necessary because it was sufficient to have pure with immutable/const input.
Apr 11 2013
On 11 April 2013 14:38, Joseph Rushton Wakeling < joseph.wakeling webdrake.net> wrote:On 04/11/2013 03:29 PM, Jacob Carlborg wrote:I think that giving the user choice of purity is about as useful as given user choice over what functions should be inlined, or what vars should go in registers. Such decisions are best left to the compiler devs judgement on doing the right thing for you. Even if they sometimes get it wrong. :o) -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';What's the point of that. Just have "strong" mean const/immutableparameters. The point is to have a way for me, the programmer, to say to the compiler: "I mean for this function to be strongly pure, can you confirm whether my choice of function inputs supports this please?"
Apr 11 2013
On 2013-04-11 15:53, Iain Buclaw wrote:I think that giving the user choice of purity is about as useful as given user choice over what functions should be inlined, or what vars should go in registers. Such decisions are best left to the compiler devs judgement on doing the right thing for you. Even if they sometimes get it wrong. :o)Beside from optimizations, it could good to be able to mark functions as pure, form a design point of view. I might be more easy to reason about a piece of code. -- /Jacob Carlborg
Apr 11 2013
On 04/11/2013 03:53 PM, Iain Buclaw wrote:I think that giving the user choice of purity is about as useful as given user choice over what functions should be inlined, or what vars should go in registers.Well, I don't mean the compiler should guarantee that my code will be optimized in a certain way, but it's handy to be able to verify that it _qualifies_ for those optimizations. That said, I think my suggestion is a minor convenience feature, and is much, much less important than ironing out the design/implementation issues that others have raised in this thread.Such decisions are best left to the compiler devs judgement on doing the right thing for you. Even if they sometimes get it wrong. :o)What??!! You guys get it wrong sometimes??!! :-O
Apr 11 2013
On Thursday, 11 April 2013 at 10:03:39 UTC, deadalnix wrote:On Thursday, 11 April 2013 at 08:36:13 UTC, Joseph Rushton Wakeling wrote:is foo strongly pure because of n being a value type that cannot contain any indirection? (i.e. as far as the outside world is concerned you don't get any side effects whatever you do with it). Is the same for structs that contain no indirection? Or do they have to be const/immutable?On 04/10/2013 08:39 PM, Walter Bright wrote:Both are strongly pure.Sure there is. Declare the function as pure, and the function's parameters as const or immutable.Sure, I accept that. What I was meaning, though, was an up-front declaration which would make the compiler shout if those necessary conditions were not met. i.e. pure foo(int n) { ... } // compiles strong pure bar(int n) { ... } // compiler instructs you to make // variables const or immutable
Apr 11 2013
2013/4/11 John Colvin <john.loughran.colvin gmail.com>On Thursday, 11 April 2013 at 10:03:39 UTC, deadalnix wrote:It is same for structs that has no *mutable* indirections. In below, all functions are strongly pure. module x; struct S1 { int n; } struct S2 { immutable int[] arr; } struct S3 { int[] arr; } pure int foo0(int n); pure int foo1(S1); // S1 has no indirections pure int foo2(S2); // S2 has no *mutable* indirections pure int foo3(immutable ref S3 x); // foo3 cannot access any mutable indirections Kenji HaraOn Thursday, 11 April 2013 at 08:36:13 UTC, Joseph Rushton Wakeling wrote:is foo strongly pure because of n being a value type that cannot contain any indirection? (i.e. as far as the outside world is concerned you don't get any side effects whatever you do with it). Is the same for structs that contain no indirection? Or do they have to be const/immutable?On 04/10/2013 08:39 PM, Walter Bright wrote:Both are strongly pure.Sure there is. Declare the function as pure, and the function's parameters as const or immutable.Sure, I accept that. What I was meaning, though, was an up-front declaration which would make the compiler shout if those necessary conditions were not met. i.e. pure foo(int n) { ... } // compiles strong pure bar(int n) { ... } // compiler instructs you to make // variables const or immutable
Apr 11 2013
On Thursday, 11 April 2013 at 10:27:55 UTC, kenji hara wrote:2013/4/11 John Colvin <john.loughran.colvin gmail.com>right, gotcha!On Thursday, 11 April 2013 at 10:03:39 UTC, deadalnix wrote:It is same for structs that has no *mutable* indirections. In below, all functions are strongly pure. module x; struct S1 { int n; } struct S2 { immutable int[] arr; } struct S3 { int[] arr; } pure int foo0(int n); pure int foo1(S1); // S1 has no indirections pure int foo2(S2); // S2 has no *mutable* indirections pure int foo3(immutable ref S3 x); // foo3 cannot access any mutable indirections Kenji HaraOn Thursday, 11 April 2013 at 08:36:13 UTC, Joseph Rushton Wakeling wrote:is foo strongly pure because of n being a value type that cannot contain any indirection? (i.e. as far as the outside world is concerned you don't get any side effects whatever you do with it). Is the same for structs that contain no indirection? Or do they have to be const/immutable?On 04/10/2013 08:39 PM, Walter Bright wrote:Both are strongly pure.Sure there is. Declare the function as pure, and the function's parameters as const or immutable.Sure, I accept that. What I was meaning, though, was an up-front declaration which would make the compiler shout if those necessary conditions were not met. i.e. pure foo(int n) { ... } // compiles strong pure bar(int n) { ... } // compiler instructs you to make // variables const or immutable
Apr 11 2013
On Thursday, 11 April 2013 at 10:16:39 UTC, John Colvin wrote:On Thursday, 11 April 2013 at 10:03:39 UTC, deadalnix wrote:I don't know what the current implementation says, but it should be.On Thursday, 11 April 2013 at 08:36:13 UTC, Joseph Rushton Wakeling wrote:is foo strongly pure because of n being a value type that cannot contain any indirection? (i.e. as far as the outside world is concerned you don't get any side effects whatever you do with it). Is the same for structs that contain no indirection? Or do they have to be const/immutable?On 04/10/2013 08:39 PM, Walter Bright wrote:Both are strongly pure.Sure there is. Declare the function as pure, and the function's parameters as const or immutable.Sure, I accept that. What I was meaning, though, was an up-front declaration which would make the compiler shout if those necessary conditions were not met. i.e. pure foo(int n) { ... } // compiles strong pure bar(int n) { ... } // compiler instructs you to make // variables const or immutable
Apr 11 2013
On 04/11/2013 12:03 PM, deadalnix wrote:Both are strongly pure.Perhaps the fact that I can have this misunderstanding is itself an argument for an explicit "strong pure" keyword, so that a daft bugger like me can really be sure he's getting what he thinks he's getting? :-) Apart from that, I think Simen replied better than I could ...
Apr 11 2013
On 11 April 2013 11:09, Simen Kj=E6r=E5s <simen.kjaras gmail.com> wrote:On Thu, 11 Apr 2013 12:03:38 +0200, deadalnix <deadalnix gmail.com> wrote=:On Thursday, 11 April 2013 at 08:36:13 UTC, Joseph Rushton Wakeling wrot=e:Great, just what we need. A compiler that barrages the user about how bad his code is, then dies... </sarcasm> --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';That's not the point. The point is, if he'd written this: strong pure bar(int* n) { ... } The compiler would have said 'Bad programmer! int* is not implicitly castable to immutable!'On 04/10/2013 08:39 PM, Walter Bright wrote:Both are strongly pure.Sure there is. Declare the function as pure, and the function's parameters as const or immutable.Sure, I accept that. What I was meaning, though, was an up-front declaration which would make the compiler shout if those necessary conditions were not met. i.e. pure foo(int n) { ... } // compiles strong pure bar(int n) { ... } // compiler instructs you to make // variables const or immutable
Apr 11 2013
On 04/11/2013 03:49 PM, Iain Buclaw wrote:Great, just what we need. A compiler that barrages the user about how bad his code is, then dies..."Compiler says no ..."
Apr 11 2013
Possibly strongly-pure functions could be marked as pure in the 'C' sense, but only if they are also nothrow, eg to add to the above example: --- pure nothrow int baz (Foo f) { return f.bar(2) + f.bar(2); } ---Or a better example that could also be pure in the 'C' sense. int baz (Foo f) pure nothrow { return f.bar(f.a) + f.bar(f.a); } -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Apr 08 2013
To: NG D Subject: Re: To help LDC/GDC This D code comes from a Haskell solution by tanakh of the Lawnmower problem of the Google Code Jam 2013 Qualification Round: import std.stdio, std.string, std.conv, std.range, std.algorithm; void main() { immutable n = stdin.readln.strip.to!int; foreach (immutable cn; 1 .. n + 1) { const hw = stdin.readln.split.to!(int[]); const bd = hw[0].iota.map!(i => stdin.readln.split.to!(int[])).array; const tbd = hw[1].iota.map!(i => bd.transversal(i).array).array; bool checkH(in int ch) { const okX = tbd.map!(xl => xl.all!(x => x <= ch)).array; foreach (oky, r; bd.map!(yl => yl.all!(y => y <= ch)).zip(bd)) //foreach (okx, c; tbd.map!(xl => xl.all!(x => x <= ch)).zip(r))//Slow. foreach (okx, c; okX.zip(r)) if (c <= ch && !(okx || oky)) return false; return true; } : "NO"); } } In the inner foreach I have had to compute okX before the loops otherwise the code gets several times slower. Is such optimization possible from a D compiler? Both "map" and "all" should be pure. The Haskell compiler uses library-defined "rewrite rules" to help in such cases. Bye, bearophile
May 02 2013