www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - static if enhancement

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Does anyone else find this annoying? 
https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
Jun 24 2016
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/24/16 11:24 AM, Andrei Alexandrescu wrote:
 Does anyone else find this annoying?
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
Maybe. That bug report does not identify any problems. What happens that's currently bad? -Steve
Jun 24 2016
next sibling parent reply Mathias Lang <mathias.lang sociomantic.com> writes:
On Friday, 24 June 2016 at 15:29:18 UTC, Steven Schveighoffer 
wrote:
 On 6/24/16 11:24 AM, Andrei Alexandrescu wrote:
 Does anyone else find this annoying?
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
Maybe. That bug report does not identify any problems. What happens that's currently bad? -Steve
Same question: What is the actual problem ? One issue that can arise is https://issues.dlang.org/show_bug.cgi?id=14835 . Is there any other ?
Jun 24 2016
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 06/24/2016 11:47 AM, Mathias Lang wrote:
 On Friday, 24 June 2016 at 15:29:18 UTC, Steven Schveighoffer wrote:
 On 6/24/16 11:24 AM, Andrei Alexandrescu wrote:
 Does anyone else find this annoying?
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
Maybe. That bug report does not identify any problems. What happens that's currently bad? -Steve
Same question: What is the actual problem ? One issue that can arise is https://issues.dlang.org/show_bug.cgi?id=14835 . Is there any other ?
The problem is excessive indentation. -- Andrei
Jun 24 2016
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/24/16 12:19 PM, Andrei Alexandrescu wrote:
 On 06/24/2016 11:47 AM, Mathias Lang wrote:
 On Friday, 24 June 2016 at 15:29:18 UTC, Steven Schveighoffer wrote:
 On 6/24/16 11:24 AM, Andrei Alexandrescu wrote:
 Does anyone else find this annoying?
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
Maybe. That bug report does not identify any problems. What happens that's currently bad?
Same question: What is the actual problem ? One issue that can arise is https://issues.dlang.org/show_bug.cgi?id=14835 . Is there any other ?
The problem is excessive indentation. -- Andrei
The problem that hasn't been made clear is, why can't you just write: static if(condition) { ... // some code return; } // some more code And the answer is, I'm guessing, bug 14835 -- misguided "unreachable statement" warnings. Should we mark your bug as a duplicate? -Steve
Jun 24 2016
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 6/24/16 1:15 PM, Steven Schveighoffer wrote:
 The problem that hasn't been made clear is, why can't you just write:

 static if(condition)
 {
     ... // some code
     return;
 }

 // some more code

 And the answer is, I'm guessing, bug 14835 -- misguided "unreachable
 statement" warnings.

 Should we mark your bug as a duplicate?
Sorry, the problem is that the code doesn't compile at all if the static if is false. So I need to insert the "else". The compiler should not attempt at all to compile the code after the static if. Andrei
Jun 24 2016
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/24/16 1:54 PM, Andrei Alexandrescu wrote:
 On 6/24/16 1:15 PM, Steven Schveighoffer wrote:
 The problem that hasn't been made clear is, why can't you just write:

 static if(condition)
 {
     ... // some code
     return;
 }

 // some more code

 And the answer is, I'm guessing, bug 14835 -- misguided "unreachable
 statement" warnings.

 Should we mark your bug as a duplicate?
Sorry, the problem is that the code doesn't compile at all if the static if is false. So I need to insert the "else".
Even with this, I still didn't understand. Now with your example in the bug report, it's clear. Reproducing here: void fun(T)(T obj) { static if (!hasMember(T, "gun")) throw new Exception("No gun"); obj.gun; } Call with something that doesn't have a gun member, and even without the reachability warnings (no -w switch), it doesn't compile. However, with an else clause, it would compile.
 The compiler should not attempt at all to compile the code after the
 static if.
Right. -Steve
Jun 24 2016
next sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Friday, 24 June 2016 at 18:27:07 UTC, Steven Schveighoffer 
wrote:
 Even with this, I still didn't understand. Now with your 
 example in the bug report, it's clear. Reproducing here:

 void fun(T)(T obj)
 {
     static if (!hasMember(T, "gun")) throw new Exception("No 
 gun");
     obj.gun;
 }

 Call with something that doesn't have a gun member, and even 
 without the reachability warnings (no -w switch), it doesn't 
 compile. However, with an else clause, it would compile.
It should be (!hasMember!(T, "gun")) But otherwise, yes, it seems unintuitive to require the else statement. Your point about types not having the gun member failing to compile is what I found confusing. By contrast, when the type has a gun member, it compiles fine. I changed it to return obj.gun and it was fine. So I wouldn't characterize this as a situation where the code below is ignored. I would characterize it as code that should be ignored is otherwise compiled.
Jun 24 2016
prev sibling parent reply Wyatt <wyatt.epp gmail.com> writes:
On Friday, 24 June 2016 at 18:27:07 UTC, Steven Schveighoffer 
wrote:
 void fun(T)(T obj)
 {
     static if (!hasMember(T, "gun")) throw new Exception("No 
 gun");
     obj.gun;
 }

 Call with something that doesn't have a gun member, and even 
 without the reachability warnings (no -w switch), it doesn't 
 compile. However, with an else clause, it would compile.
I might be stepping on a land mine by bringing it up, but isn't this sort of thing what contracts are for? -Wyatt
Jun 29 2016
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 6/29/16 11:40 AM, Wyatt wrote:
 On Friday, 24 June 2016 at 18:27:07 UTC, Steven Schveighoffer wrote:
 void fun(T)(T obj)
 {
     static if (!hasMember(T, "gun")) throw new Exception("No gun");
     obj.gun;
 }

 Call with something that doesn't have a gun member, and even without
 the reachability warnings (no -w switch), it doesn't compile. However,
 with an else clause, it would compile.
I might be stepping on a land mine by bringing it up, but isn't this sort of thing what contracts are for?
No landmines here, but no, that isn't what contracts are for. Perhaps you mean constraints? A constraint will prevent compilation vs. allowing compilation but emitting a failure at runtime. I agree this is a better mechanism, or just plain allow the compiler to make a proper error when you call gun. It's not so much that this example is meant be a justification, but more an explanation of what the enhancement will do. In any case, I've drifted back towards being against this change. It leaves the compilability of code up to the quality of the compiler's flow analysis. -Steve
Jun 30 2016
parent Wyatt <wyatt.epp gmail.com> writes:
On Thursday, 30 June 2016 at 11:06:56 UTC, Steven Schveighoffer 
wrote:
 On 6/29/16 11:40 AM, Wyatt wrote:
 I might be stepping on a land mine by bringing it up, but 
 isn't this
 sort of thing what contracts are for?
No landmines here, but no, that isn't what contracts are for. Perhaps you mean constraints?
Sure. IME, contracts are generally written as a series of constraints anyway.
 A constraint will prevent compilation vs. allowing compilation 
 but emitting a failure at runtime. I agree this is a better 
 mechanism, or just plain allow the compiler to make a proper 
 error when you call gun.
Isn't doing it at compile time as simple as using e.g. static assert(hasMember(T, "gun"))? I do feel like I've been in situations before where this kind of thing was better as a recoverable runtime exception, but I can't remember where. The more I think about this, though, the less the proposal makes sense for the problem. Like, I get that it might be a tiny bit annoying, but I see a lot more potential for human error; pulling a "goto FAIL" and running code that shouldn't be or such. -Wyatt
Jun 30 2016
prev sibling parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Friday, June 24, 2016 13:54:21 Andrei Alexandrescu via Digitalmars-d wrote:
 On 6/24/16 1:15 PM, Steven Schveighoffer wrote:
 The problem that hasn't been made clear is, why can't you just write:

 static if(condition)
 {

     ... // some code
     return;

 }

 // some more code

 And the answer is, I'm guessing, bug 14835 -- misguided "unreachable
 statement" warnings.

 Should we mark your bug as a duplicate?
Sorry, the problem is that the code doesn't compile at all if the static if is false. So I need to insert the "else". The compiler should not attempt at all to compile the code after the static if.
I would think that it's highly unintuitive to think that code outside of a static if would be treated as part of an else of a static if just because the static if happens to return at the end. Certainly, if the code after the static if couldn't compile if the static if code didn't return, I definitely think that the code following it needs to be in an else. Really, it seems to me that this comes down to a complaint about the compiler producing errors on unreachable code - which is the sort of thing that I tend to think should not be treated as an error - _especially_ with how badly it tends to interact with generic code. So, as long as the code following the static if is valid without being in an else for the static if, I'm all for having the compiler just optimize out everything after the return without complaining - but if we're going to do that, it really shouldn't be specific to static ifs. That would be unreasonably inconsistent IMHO. And I don't think that it's a good idea to treat code following a static if as if it were in an else just because of a return statement or break statement or some other control statement in the static if which would cause the code after it to be skipped. That would be confusing and inconsistent IMHO, much as it would be nice to avoid the extra braces and indentation. So, if we're going to change things here, I think that the approach is to stop having the compiler complain about unreachable code, which I think is very reasonable in light of how annoying that can get - particularly with generic code - though I'm sure that some folks will be unhappy about that just like some folks want the compiler to complain about unused variables (though we don't do that in part because of how badly it interacts with various D features - like highly templatized code - and that's pretty much the main reason that having the compiler complain about unreachable code is so problematic, which could be an argument to have it stop complaining about it). - Jonathan M Davis
Jun 26 2016
parent QAston <qaston gmail.com> writes:
On Monday, 27 June 2016 at 00:31:39 UTC, Jonathan M Davis wrote:
 On Friday, June 24, 2016 13:54:21 Andrei Alexandrescu via 
 Digitalmars-d wrote:

 I would think that it's highly unintuitive to think that code 
 outside of a static if would be treated as part of an else of a 
 static if just because the static if happens to return at the 
 end. Certainly, if the code after the static if couldn't 
 compile if the static if code didn't return, I definitely think 
 that the code following it needs to be in an else. Really, it 
 seems to me that this comes down to a complaint about the 
 compiler producing errors on unreachable code - which is the 
 sort of thing that I tend to think should not be treated as an 
 error - _especially_ with how badly it tends to interact with 
 generic code.
+1
 So, as long as the code following the static if is valid 
 without being in an else for the static if, I'm all for having 
 the compiler just optimize out everything after the return 
 without complaining - but if we're going to do that, it really 
 shouldn't be specific to static ifs. That would be unreasonably 
 inconsistent IMHO. And I don't think that it's a good idea to 
 treat code following a static if as if it were in an else just 
 because of a return statement or break statement or some other 
 control statement in the static if which would cause the code 
 after it to be skipped. That would be confusing and 
 inconsistent IMHO, much as it would be nice to avoid the extra 
 braces and indentation.

 So, if we're going to change things here, I think that the 
 approach is to stop having the compiler complain about 
 unreachable code, which I think is very reasonable in light of 
 how annoying that can get - particularly with generic code - 
 though I'm sure that some folks will be unhappy about that just 
 like some folks want the compiler to complain about unused 
 variables (though we don't do that in part because of how badly 
 it interacts with various D features - like highly templatized 
 code - and that's pretty much the main reason that having the 
 compiler complain about unreachable code is so problematic, 
 which could be an argument to have it stop complaining about 
 it).
I'm one of those folks who think that errors about unreachable code are important and I'm perfectly willing to pay the price of usually short changes to code to keep things clear. Especially in generic code, as for me not knowing what's going on is far more annoying than having to maintain a bit of structure. That said, when faced with choice between having unreachability error removed and having a change in the language making every static if more complex, I definitely prefer having errors removed and the code being optimized out. Errors can be always added by external tools. Inconsistencies in the language can't be fixed externally. The proposed language change brings an inconsistency for a trivial gain. Ignoring unreachable code is a consistent change, so in my opinion a much better solution.
Jun 27 2016
prev sibling parent reply JohnnyC <j j.com> writes:
On Friday, 24 June 2016 at 15:29:18 UTC, Steven Schveighoffer 
wrote:
 On 6/24/16 11:24 AM, Andrei Alexandrescu wrote:
 Does anyone else find this annoying?
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
Maybe. That bug report does not identify any problems. What happens that's currently bad? -Steve
Second that, can't see anything bad there!
Jun 24 2016
parent Dominikus Dittes Scherkl <Dominikus.Scherkl continental-corporation.com> writes:
On Friday, 24 June 2016 at 17:03:55 UTC, JohnnyC wrote:
 On Friday, 24 June 2016 at 15:29:18 UTC, Steven Schveighoffer 
 wrote:
 On 6/24/16 11:24 AM, Andrei Alexandrescu wrote:
 Does anyone else find this annoying?
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
Maybe. That bug report does not identify any problems. What happens that's currently bad? -Steve
Second that, can't see anything bad there!
The problem (that I see) is, that if you don't create the "else" path but the "static if" condition is true, you generate dead code behind the return statement (if the compiler doesn't optimize that away). In our company that would be a no-go. So you always have to explicitly write (and indent) the else path.
Jun 24 2016
prev sibling next sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 24 June 2016 at 15:24:48 UTC, Andrei Alexandrescu 
wrote:
 Does anyone else find this annoying? 
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
This would mean treating static if's differently if they alter control flow in a scope larger then themselves. Special casing a static if that returns would not be as bad. But with the current state of the compiler I would hold of on such complications.
Jun 24 2016
parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 24 June 2016 at 15:34:42 UTC, Stefan Koch wrote:
 On Friday, 24 June 2016 at 15:24:48 UTC, Andrei Alexandrescu 
 wrote:
 Does anyone else find this annoying? 
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
This would mean treating static if's differently if they alter control flow in a scope larger then themselves. Special casing a static if that returns would not be as bad. But with the current state of the compiler I would hold of on such complications.
To elaborate: This requires control-flow analysis over all static if branches, to find and very one special case which we treat specially. It would only be beneficial If we hit this case predominantly. However, I am not sure how much langauge complexity this adds.
Jun 24 2016
parent deadalnix <deadalnix gmail.com> writes:
On Friday, 24 June 2016 at 15:43:58 UTC, Stefan Koch wrote:
 To elaborate:
  This requires control-flow analysis over all static if 
 branches,
  to find and very one special case which we treat specially.
No. This require to put a maybe reachable flag in some position int the code (namely, after the static if). It is already done, for instance for switch statements.
Jun 24 2016
prev sibling next sibling parent deadalnix <deadalnix gmail.com> writes:
On Friday, 24 June 2016 at 15:24:48 UTC, Andrei Alexandrescu 
wrote:
 Does anyone else find this annoying? 
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
I made a proposal for this. Yes it is very annoying.
Jun 24 2016
prev sibling next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Friday, 24 June 2016 at 15:24:48 UTC, Andrei Alexandrescu 
wrote:
 Does anyone else find this annoying? 
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
please, no. introduce `final static if` or something, but don't do this with `static if` itself. it makes special case `static if` (one more special deviation to remember, oh, noes), and DMD interproc analysis is non-existing, so `static if (...) { functionThatAlwaysThrow(); }` would fail. and even if it wouldn't, it is still bad, as now i have to guess if that function "never return" or no.
Jun 24 2016
prev sibling next sibling parent Uranuz <neuranuz gmail.com> writes:
On Friday, 24 June 2016 at 15:24:48 UTC, Andrei Alexandrescu 
wrote:
 Does anyone else find this annoying? 
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
What I think about enchancement of static if is that it could be interesting to have `elif` keyword like in Python, so instead of static if (...) { } else static if(...) { } else static if(...) { } else { } I could write shorter: static if (...) { } elif (...) { } elif(...) { } else { } In other hand it maybe not got idea to have multiple syntax just for the same think. But we already have multiple syntax for template constraints template AA (T: int) {} or template AA(T) if ( is( T: int ) ) {} And also shorthand for template using *alias* was added recently: alias AA(T) = ... So my idea could survive too.. :) Bad thing here is adding the new keyword, but I don't think that people using word `elif` for names of their variables or functions, if they don't write Python parser of course :)
Jun 24 2016
prev sibling next sibling parent reply Claude <no no.no> writes:
On Friday, 24 June 2016 at 15:24:48 UTC, Andrei Alexandrescu 
wrote:
 Does anyone else find this annoying? 
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
My 2 cents. I don't find that annoying at all. It's perfectly normal IMHO. It may introduce an additional indentation level for the second part, but I reckon it is normal to have those 2 instruction blocks at the same level. If we were to introduce a new keyword for "static if else", why not do the same for the run-time "if else" (to be coherent)? And, if some code have too many indentation levels, than it probably means it should be better modularized, hence I'd suggest to split it in several sub-functions, it will be more readable/maintainable.
Jun 25 2016
next sibling parent reply cym13 <cpicard openmailbox.org> writes:
On Saturday, 25 June 2016 at 10:19:47 UTC, Claude wrote:
 And if some code have too many indentation levels, than it
 probably means it should be better modularized, hence I'd 
 suggest to split it in several sub-functions, it will be more 
 readable/maintainable.
We are talking about early returns (checking for something and returning as soon as possible) which are a well-known and efficient way to reduce indentation levels and increase modularity. You can't come and say "What? You want it to work? Man, you should have thought your code better!": the very reason this subject is discussed is to allow people to deal with indentation levels!
Jun 25 2016
next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Saturday, 25 June 2016 at 11:27:01 UTC, cym13 wrote:
 We are talking about early returns (checking for something and
 returning as soon as possible) which are a well-known and 
 efficient
 way to reduce indentation levels and increase modularity. You 
 can't
 come and say "What? You want it to work? Man, you should have 
 thought
 your code better!": the very reason this subject is discussed 
 is to
 allow people
...to think less. sorry.
Jun 25 2016
prev sibling parent reply Claude <no no.no> writes:
On Saturday, 25 June 2016 at 11:27:01 UTC, cym13 wrote:
 We are talking about early returns (checking for something and
 returning as soon as possible) which are a well-known and 
 efficient
 way to reduce indentation levels and increase modularity. You 
 can't
 come and say "What? You want it to work? Man, you should have 
 thought
 your code better!": the very reason this subject is discussed 
 is to
 allow people to deal with indentation levels!
I didn't want to sound like that. But my post was unclear. Though, in the example, it looks nice, and I understand one would want such a feature. I think it could be abused in some other cases and make the code less readable. I had in mind some cross-platform libraries written in C with #if #elif and #endif all other the place (used with compiler switches). And I reckon the current "static if" is a good tool that fits well with the rest of the language to properly mark different sections of code, and have different implementations. The fact it gives another indentation level could be seen as an opportunity to better modularize code (it's what I meant). So I find that special case (having code after a "static if() {return;}" treated like in the "else" block) a bit unintuitive, and could be prone to bad practice and confusion.
Jun 27 2016
parent reply cym13 <cpicard openmailbox.org> writes:
On Monday, 27 June 2016 at 08:16:18 UTC, Claude wrote:
 On Saturday, 25 June 2016 at 11:27:01 UTC, cym13 wrote:
 We are talking about early returns (checking for something and
 returning as soon as possible) which are a well-known and 
 efficient
 way to reduce indentation levels and increase modularity. You 
 can't
 come and say "What? You want it to work? Man, you should have 
 thought
 your code better!": the very reason this subject is discussed 
 is to
 allow people to deal with indentation levels!
I didn't want to sound like that. But my post was unclear. Though, in the example, it looks nice, and I understand one would want such a feature. I think it could be abused in some other cases and make the code less readable. I had in mind some cross-platform libraries written in C with #if #elif and #endif all other the place (used with compiler switches). And I reckon the current "static if" is a good tool that fits well with the rest of the language to properly mark different sections of code, and have different implementations. The fact it gives another indentation level could be seen as an opportunity to better modularize code (it's what I meant). So I find that special case (having code after a "static if() {return;}" treated like in the "else" block) a bit unintuitive, and could be prone to bad practice and confusion.
What's unintuitive about it (real question)? It would make it behave more like a standard if and early returns are very common, well understood and good practice: void func(int* somepointer) { if (somepointer == null) return; [rest of the code] } When seeing such code (which generally leads to cleaner functions) the meaning is quite obvious, I fail to see who would expect static if to behave otherwise. Of course knowing how it works it makes sense that making it work that way isn't easy but it sounds more like a leaky abstraction than something more intuitive to me.
Jun 27 2016
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 27.06.2016 13:05, cym13 wrote:
 On Monday, 27 June 2016 at 08:16:18 UTC, Claude wrote:
 On Saturday, 25 June 2016 at 11:27:01 UTC, cym13 wrote:
 We are talking about early returns (checking for something and
 returning as soon as possible) which are a well-known and efficient
 way to reduce indentation levels and increase modularity. You can't
 come and say "What? You want it to work? Man, you should have thought
 your code better!": the very reason this subject is discussed is to
 allow people to deal with indentation levels!
I didn't want to sound like that. But my post was unclear. Though, in the example, it looks nice, and I understand one would want such a feature. I think it could be abused in some other cases and make the code less readable. I had in mind some cross-platform libraries written in C with #if #elif and #endif all other the place (used with compiler switches). And I reckon the current "static if" is a good tool that fits well with the rest of the language to properly mark different sections of code, and have different implementations. The fact it gives another indentation level could be seen as an opportunity to better modularize code (it's what I meant). So I find that special case (having code after a "static if() {return;}" treated like in the "else" block) a bit unintuitive, and could be prone to bad practice and confusion.
What's unintuitive about it (real question)? It would make it behave more like a standard if and early returns are very common, well understood and good practice: void func(int* somepointer) { if (somepointer == null) return; [rest of the code] } When seeing such code (which generally leads to cleaner functions) the meaning is quite obvious, I fail to see who would expect static if to behave otherwise.
Me, because that's what it means to evaluate the condition at compile time and only compiling in the appropriate branch. This is additional and special behaviour and it destroys the orthogonality of 'static if' and 'return'. (I don't feel strongly about the change, but the idea that the new behavior should be expected anyway is flawed.)
 Of course knowing how it works it makes sense that
 making it work that way isn't easy
It's rather easy.
 but it sounds more like a leaky
 abstraction than something more intuitive to me.
My preferred option is to simply add 'static return' to avoid the context-dependence.
Jun 27 2016
parent reply deadalnix <deadalnix gmail.com> writes:
On Monday, 27 June 2016 at 18:14:26 UTC, Timon Gehr wrote:
 Me, because that's what it means to evaluate the condition at 
 compile time and only compiling in the appropriate branch. This 
 is additional and special behaviour and it destroys the 
 orthogonality of 'static if' and 'return'. (I don't feel 
 strongly about the change, but the idea that the new behavior 
 should be expected anyway is flawed.)
Alright, I have to range myself with most here. While I'm all for not warning about unreachable code, I'm opposed to not compiling the rest of the code. This create non orthogonality between static if and control flow analysis, the kind that clearly do not pay for itself.
Jun 27 2016
next sibling parent cym13 <cpicard openmailbox.org> writes:
On Monday, 27 June 2016 at 18:55:48 UTC, deadalnix wrote:
 On Monday, 27 June 2016 at 18:14:26 UTC, Timon Gehr wrote:
 Me, because that's what it means to evaluate the condition at 
 compile time and only compiling in the appropriate branch. 
 This is additional and special behaviour and it destroys the 
 orthogonality of 'static if' and 'return'. (I don't feel 
 strongly about the change, but the idea that the new behavior 
 should be expected anyway is flawed.)
Alright, I have to range myself with most here. While I'm all for not warning about unreachable code, I'm opposed to not compiling the rest of the code. This create non orthogonality between static if and control flow analysis, the kind that clearly do not pay for itself.
Okay, I'm convinced.
Jun 27 2016
prev sibling parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Monday, June 27, 2016 18:55:48 deadalnix via Digitalmars-d wrote:
 On Monday, 27 June 2016 at 18:14:26 UTC, Timon Gehr wrote:
 Me, because that's what it means to evaluate the condition at
 compile time and only compiling in the appropriate branch. This
 is additional and special behaviour and it destroys the
 orthogonality of 'static if' and 'return'. (I don't feel
 strongly about the change, but the idea that the new behavior
 should be expected anyway is flawed.)
Alright, I have to range myself with most here. While I'm all for not warning about unreachable code, I'm opposed to not compiling the rest of the code. This create non orthogonality between static if and control flow analysis, the kind that clearly do not pay for itselfr
Agreed. The code outside of the static if should be compiled regardless, because it's not part of the static if/else at all and therefore has not been marked as conditionally compilable. But if we don't warn about unreachable code, then the code after the static if can clearly be optimized out because it's unreachable. So, Andrei's code would become legal as long as the only problem with the code after the static if was that it was unreachable. - Jonathan M Davis
Jun 27 2016
next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Monday, 27 June 2016 at 22:56:41 UTC, Jonathan M Davis wrote:
 On Monday, June 27, 2016 18:55:48 deadalnix via Digitalmars-d 
 wrote:
 On Monday, 27 June 2016 at 18:14:26 UTC, Timon Gehr wrote:
 [...]
Alright, I have to range myself with most here. While I'm all for not warning about unreachable code, I'm opposed to not compiling the rest of the code. This create non orthogonality between static if and control flow analysis, the kind that clearly do not pay for itselfr
Agreed. The code outside of the static if should be compiled regardless, because it's not part of the static if/else at all and therefore has not been marked as conditionally compilable. But if we don't warn about unreachable code, then the code after the static if can clearly be optimized out because it's unreachable. So, Andrei's code would become legal as long as the only problem with the code after the static if was that it was unreachable. - Jonathan M Davis
It is true that that such unreachable warning can be annoying at times. However it catches bugs. Especially in generic code Those warnings can be a blessing rather then a curse. We should not swallow or gag errors!
Jun 27 2016
prev sibling parent reply QAston <qaston gmail.com> writes:
On Monday, 27 June 2016 at 22:56:41 UTC, Jonathan M Davis wrote:
 Agreed. The code outside of the static if should be compiled 
 regardless, because it's not part of the static if/else at all 
 and therefore has not been marked as conditionally compilable. 
 But if we don't warn about unreachable code, then the code 
 after the static if can clearly be optimized out because it's 
 unreachable. So, Andrei's code would become legal as long as 
 the only problem with the code after the static if was that it 
 was unreachable.

 - Jonathan M Davis
The "allow unreachable code" solution has it's own limitations compared to implicit-else-block. It doesn't allow varying return type and differing declarations in the two blocks. Allowing unreachable code also shares readibility problems (because the example code is exactly the same for both solutions), although it's conceptually easier to understand and more consistent, so it's prefered. I personally like present state of things.
Jun 28 2016
next sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Tuesday, 28 June 2016 at 13:34:48 UTC, QAston wrote:
 On Monday, 27 June 2016 at 22:56:41 UTC, Jonathan M Davis wrote:
 Agreed. The code outside of the static if should be compiled 
 regardless, because it's not part of the static if/else at all 
 and therefore has not been marked as conditionally compilable. 
 But if we don't warn about unreachable code, then the code 
 after the static if can clearly be optimized out because it's 
 unreachable. So, Andrei's code would become legal as long as 
 the only problem with the code after the static if was that it 
 was unreachable.

 - Jonathan M Davis
The "allow unreachable code" solution has it's own limitations compared to implicit-else-block. It doesn't allow varying return type and differing declarations in the two blocks.
"The solution doesn't solve all problems, therefore the solution do not make things any better" Nonsense.
 Allowing unreachable code also shares readibility problems 
 (because the example code is exactly the same for both 
 solutions), although it's conceptually easier to understand and 
 more consistent, so it's prefered.
We already allow unreachable code in various places for convenience reasons (or because the control flow analysis is fubared ?). Anyway, considered nobody complained about these cases ever, it is fair to assume that this is not a big deal.
Jun 28 2016
parent reply QAston <qaston gmail.com> writes:
On Tuesday, 28 June 2016 at 17:41:58 UTC, deadalnix wrote:
 "The solution doesn't solve all problems, therefore the 
 solution do not make things any better"

 Nonsense.
More like "this solution doesn't solve all problems solved by other solution and that's worth keeping in mind".
 We already allow unreachable code in various places for 
 convenience reasons (or because the control flow analysis is 
 fubared ?). Anyway, considered nobody complained about these 
 cases ever, it is fair to assume that this is not a big deal.
Ok, makes sense to me.
Jun 28 2016
parent deadalnix <deadalnix gmail.com> writes:
On Tuesday, 28 June 2016 at 21:06:18 UTC, QAston wrote:
 On Tuesday, 28 June 2016 at 17:41:58 UTC, deadalnix wrote:
 "The solution doesn't solve all problems, therefore the 
 solution do not make things any better"

 Nonsense.
More like "this solution doesn't solve all problems solved by other solution and that's worth keeping in mind".
Yes, but the whole thing is a balancing act. It is clear that all presented solutions here do not solve all problems, so the point is rather moot IMO.
Jun 28 2016
prev sibling parent Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Tuesday, June 28, 2016 13:34:48 QAston via Digitalmars-d wrote:
 On Monday, 27 June 2016 at 22:56:41 UTC, Jonathan M Davis wrote:
 Agreed. The code outside of the static if should be compiled
 regardless, because it's not part of the static if/else at all
 and therefore has not been marked as conditionally compilable.
 But if we don't warn about unreachable code, then the code
 after the static if can clearly be optimized out because it's
 unreachable. So, Andrei's code would become legal as long as
 the only problem with the code after the static if was that it
 was unreachable.

 - Jonathan M Davis
The "allow unreachable code" solution has it's own limitations compared to implicit-else-block. It doesn't allow varying return type and differing declarations in the two blocks.
And IMHO, it shouldn't, because that should only work if the code has been marked as conditionally compilable, which you do by putting the code within a branch of the static if. I _really_ don't agree with the idea that code that is not explicitly marked as conditionally compilable would be treated as conditionally compilable. And as long as we keep things so that only code which is explicitly marked as conditionally compilable is conditionally compilable, then this whole issue devolves to the issue of whether we should treat unreachable code as an error or not. If we do, then Andrei's code won't compile (and rightly so IMO), whereas if we decide that we'd be better off allowing unreachable code, then Andrei's code would happen to compile. But regardless, I think that the issue should be approached as a question of whether unreachable code should be allowed and that we should not treat code as conditionally compilable just because of a return statement in the conditionally compilable code before it. Such behavior would be inconsistent and confusing. So, the question is then whether we should allow unreachable code, and there are very good reasons for allowing it and very good reasons for not allowing it. But that discussion is much wider than the case where a static if happens to return and involves pros and cons which do not necessarily apply to that particular case.
 I personally like present state of things.
I can certainly live with it, but I'd definitely prefer that we not warn about unreachable code. There are times when having the compiler complain about unreachable code can be useful, but in my experience, it just isn't an issue. If I have unreachable code, I know that it's unreachable, and I don't need the compiler to tell me about it - and odds are that I'd _like_ for it to still compile in spite of it being unreachable. I'm frequently forced to comment out code when debugging when I'd just as soon just throw a return statement in there and not bother with commenting anything, but the compiler won't let me. So, personally, I see little value in having the compiler warn about unreachable code, but I can see why someone would think that it would be of benefit. A similar case is unused variables, which we can't treat as warnings or errors because of stuff like traits, since they declare variables without using them all the time. Some folks would still like a warning or error though. It's just that in that case, we decided to let the compiler ignore them, whereas with unreachable code, we went the other way. - Jonathan M Davis
Jun 28 2016
prev sibling next sibling parent Claude <no no.no> writes:
On Monday, 27 June 2016 at 11:05:49 UTC, cym13 wrote:
 What's unintuitive about it (real question)? It would make it 
 behave more like a standard if and early returns are very 
 common, well understood and good practice:

 void func(int* somepointer) {
     if (somepointer == null)
         return;
     [rest of the code]
 }
From this perspective, you are right. But mixing "return" or "throw" which belong to the "run-time world", and "static if" which is "compile-time" feels wrong somehow to me. But maybe I'm biased by my C experience. It's like mixing "return" and "#if". Some other negative responses in this thread may also give a better explanation of what I mean. The other thing is that, introducing that will not break any code (a priori). But if the change is made, and it turns out to not pay enough or lead to some abuse (more on the readability part), going backward shall introduce code-breakage. Also, I agree with QAston comments about errors on unreachable code. Maybe "static return" is a good compromise?...
Jun 27 2016
prev sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Monday, 27 June 2016 at 11:05:49 UTC, cym13 wrote:
 What's unintuitive about it (real question)? It would make it 
 behave more like a standard if and early returns are very 
 common, well understood and good practice:

 void func(int* somepointer) {
     if (somepointer == null)
         return;
     [rest of the code]
 }

 When seeing such code (which generally leads to cleaner 
 functions) the meaning is quite obvious, I fail to see who 
 would expect static if to behave otherwise.
here i am!
Jun 27 2016
prev sibling parent Uranuz <neuranuz gmail.com> writes:
On Saturday, 25 June 2016 at 10:19:47 UTC, Claude wrote:
 On Friday, 24 June 2016 at 15:24:48 UTC, Andrei Alexandrescu 
 wrote:
 Does anyone else find this annoying? 
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
My 2 cents. I don't find that annoying at all. It's perfectly normal IMHO. It may introduce an additional indentation level for the second part, but I reckon it is normal to have those 2 instruction blocks at the same level. If we were to introduce a new keyword for "static if else", why not do the same for the run-time "if else" (to be coherent)? And, if some code have too many indentation levels, than it probably means it should be better modularized, hence I'd suggest to split it in several sub-functions, it will be more readable/maintainable.
I think if we want we could also add `if else` for run-time if too. In D we have wide usage of CT features and particularly `static if`. It becomes annoying and too verbose to write `else static if` when I have multiple branches, so I was thinking for some time to have `elif` keyword. In this case it would be enough to write static just one time at the beginning of `static if`. Compiler could understand that `elif` belongs to this exact `if` or `static if` that was before it.
Jun 25 2016
prev sibling parent reply QAston <qaston gmail.com> writes:
On Friday, 24 June 2016 at 15:24:48 UTC, Andrei Alexandrescu 
wrote:
 Does anyone else find this annoying? 
 https://issues.dlang.org/show_bug.cgi?id=16201 -- Andrei
Please no. I'd argue that this brings more confusion than readibility. Imagine reading more complicated code with this. You have to do control flow analysis on if-block to determine whether code outside of if block is included in compilation. Doesn't sound good for reading, does it. Imagine explaining static if block rules to new people. "Well static if works this way, except it doesn't create scope. Also, we have this another special rule, where we create else blocks implicitly if all paths in static-if block return early. This saves you writing six characters and an intendation level." Also - metaprogramming. You don't know the control flow of whatever you may be printing in a mixin, or having as a parameter in a template. Making such code even more difficult to analyze.
Jun 26 2016
parent QAston <qaston gmail.com> writes:
On Sunday, 26 June 2016 at 21:14:16 UTC, QAston wrote:
 Also - metaprogramming. You don't know the control flow of 
 whatever you may be printing in a mixin, or having as a 
 parameter in a template. Making such code even more difficult 
 to analyze.
Also, this couples runtime control flow with conditional compilation. Those are orthogonal and imo should be kept that way. For me, that's least surprising behavior.
Jun 26 2016