www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - If Statement with Declaration

reply Jerry <hurricane hereiam.com> writes:
So I was thinking of a way of extending if statements that have 
declarations. The following being as example of the current use 
of if statements with declarations:

     if(int* weDontPollute = someFunc())
     {
          // use weDontPollute
     }

That's great and all, but it only works by checking if the 
variable evaluates to true or false. Which is fine for a pointer 
but otherwise useless for anything else, like integers where zero 
is usually valid input (index for array). So currently the only 
way to do something like this in the language, that i've found, 
is to use a for statement.

     for(int i = someFunc(); i >= 0;)
     {
         // use i

         break;
     }

Not that ideal to use a for statement. It makes it hard to read 
and if the break condition isn't there it might very well be an 
infinite loop. So I was thinking of some sort of syntax like this:

     if(int i = someFunc(); i >= 0)
     {
         // use i
     }
Thoughts on this sort of feature?
Nov 03 2016
next sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Thursday, 3 November 2016 at 22:29:34 UTC, Jerry wrote:
 So I was thinking of a way of extending if statements that have 
 declarations. The following being as example of the current use 
 of if statements with declarations:

 [...]
Just Introduce another block { int i = someFunc(); if (i >= 0) { ... } } // i is not visible here
Nov 03 2016
next sibling parent reply mogu <mogucpp 163.com> writes:
On Thursday, 3 November 2016 at 22:32:17 UTC, Stefan Koch wrote:
 On Thursday, 3 November 2016 at 22:29:34 UTC, Jerry wrote:
 So I was thinking of a way of extending if statements that 
 have declarations. The following being as example of the 
 current use of if statements with declarations:

 [...]
Just Introduce another block { int i = someFunc(); if (i >= 0) { ... } } // i is not visible here
Introducing a block is not intuitive and cause an identation. As a reference, C++17 has adopted a proposal about this, and extended to switch: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r1.html
Nov 03 2016
parent ixid <adamsibson hotmail.com> writes:
On Friday, 4 November 2016 at 00:04:28 UTC, mogu wrote:
 Introducing a block is not intuitive and cause an identation.
How is using a block to produce a sub-scope not intuitive? That's using a standard feature to do exactly what it is supposed to do.
Nov 04 2016
prev sibling parent reply Superstar64 <Hexagonalstar64 gmail.com> writes:
On Thursday, 3 November 2016 at 22:32:17 UTC, Stefan Koch wrote:
 Just Introduce another block
 {
   int i = someFunc();
   if (i >= 0) { ... }
 }
 // i is not visible here
That adds 2 indention levels after formatting. Unfortunately this doesn't work: --- { int i = someFunc(); if (i >= 0): //your code here } // i is not visible here ---
Nov 04 2016
parent reply Andrea Fontana <nospam example.com> writes:
On Friday, 4 November 2016 at 13:38:30 UTC, Superstar64 wrote:
 On Thursday, 3 November 2016 at 22:32:17 UTC, Stefan Koch wrote:
 Just Introduce another block
 {
   int i = someFunc();
   if (i >= 0) { ... }
 }
 // i is not visible here
That adds 2 indention levels after formatting. Unfortunately this doesn't work: --- { int i = someFunc(); if (i >= 0): //your code here } // i is not visible here ---
If you don't like indentation you can simply ignore it or you can use old goto :) { int i = someFunc(); if (i < 0) goto outer; // your code here } outer: // i is not visibe here
Nov 04 2016
parent Nick Treleaven <nick geany.org> writes:
On Friday, 4 November 2016 at 13:56:57 UTC, Andrea Fontana wrote:
 If you don't like indentation you can simply ignore it or you 
 can use old goto :)

 {
    int i = someFunc();
    if (i < 0) goto outer;
    // your code here
 }
 outer:
BTW there is a trick to avoid goto+label: switch (true) { default: int i = someFunc(); if (i < 0) break; ... } If code after goto is long, the reader has to search for the label. With switch/break, the reader knows the current scope is just skipped, no need to interrupt reading of lines. We could allow omitting the condition and default label: switch { int i = someFunc(); if (i < 0) break; ... } That would encourage the pattern to be used instead of the 'triangle if' pattern - the rationale for breakable blocks: https://issues.dlang.org/show_bug.cgi?id=8622
Nov 04 2016
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/3/16 6:29 PM, Jerry wrote:
 So I was thinking of a way of extending if statements that have
 declarations. The following being as example of the current use of if
 statements with declarations:

     if(int* weDontPollute = someFunc())
     {
          // use weDontPollute
     }

 That's great and all, but it only works by checking if the variable
 evaluates to true or false. Which is fine for a pointer but otherwise
 useless for anything else, like integers where zero is usually valid
 input (index for array). So currently the only way to do something like
 this in the language, that i've found, is to use a for statement.

     for(int i = someFunc(); i >= 0;)
     {
         // use i

         break;
     }

 Not that ideal to use a for statement. It makes it hard to read and if
 the break condition isn't there it might very well be an infinite loop.
 So I was thinking of some sort of syntax like this:

     if(int i = someFunc(); i >= 0)
     {
         // use i
     }
 Thoughts on this sort of feature?
Hm... what about something like: struct BoolCond(T, string cond) { T val; bool opCast(B)() if(is(B == bool)) { return mixin("val " ~ cond); } } auto boolcond(string cond, T)(T val) { return BoolCond!(T, cond)(val); } if(auto i = someFunc.boolcond!(">= 0")) { ... // use i } -Steve
Nov 04 2016
next sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/4/16 10:10 AM, Steven Schveighoffer wrote:
 On 11/3/16 6:29 PM, Jerry wrote:
 So I was thinking of a way of extending if statements that have
 declarations. The following being as example of the current use of if
 statements with declarations:

     if(int* weDontPollute = someFunc())
     {
          // use weDontPollute
     }

 That's great and all, but it only works by checking if the variable
 evaluates to true or false. Which is fine for a pointer but otherwise
 useless for anything else, like integers where zero is usually valid
 input (index for array). So currently the only way to do something like
 this in the language, that i've found, is to use a for statement.

     for(int i = someFunc(); i >= 0;)
     {
         // use i

         break;
     }

 Not that ideal to use a for statement. It makes it hard to read and if
 the break condition isn't there it might very well be an infinite loop.
 So I was thinking of some sort of syntax like this:

     if(int i = someFunc(); i >= 0)
     {
         // use i
     }
 Thoughts on this sort of feature?
Hm... what about something like: struct BoolCond(T, string cond) { T val; bool opCast(B)() if(is(B == bool)) { return mixin("val " ~ cond); }
Of course, I missed this: alias val this; -Steve
Nov 04 2016
prev sibling parent reply Jerry <hurricane hereiam.com> writes:
On Friday, 4 November 2016 at 14:10:51 UTC, Steven Schveighoffer 
wrote:
 On 11/3/16 6:29 PM, Jerry wrote:
 So I was thinking of a way of extending if statements that have
 declarations. The following being as example of the current 
 use of if
 statements with declarations:

     if(int* weDontPollute = someFunc())
     {
          // use weDontPollute
     }

 That's great and all, but it only works by checking if the 
 variable
 evaluates to true or false. Which is fine for a pointer but 
 otherwise
 useless for anything else, like integers where zero is usually 
 valid
 input (index for array). So currently the only way to do 
 something like
 this in the language, that i've found, is to use a for 
 statement.

     for(int i = someFunc(); i >= 0;)
     {
         // use i

         break;
     }

 Not that ideal to use a for statement. It makes it hard to 
 read and if
 the break condition isn't there it might very well be an 
 infinite loop.
 So I was thinking of some sort of syntax like this:

     if(int i = someFunc(); i >= 0)
     {
         // use i
     }
 Thoughts on this sort of feature?
Hm... what about something like: struct BoolCond(T, string cond) { T val; bool opCast(B)() if(is(B == bool)) { return mixin("val " ~ cond); } } auto boolcond(string cond, T)(T val) { return BoolCond!(T, cond)(val); } if(auto i = someFunc.boolcond!(">= 0")) { ... // use i } -Steve
Well that's just a basic case, what if you want more than one condition. Using "&&" for example, or a condition along with another value that's in the scope. void otherFunc(int input) { if(auto i = someFunc.boolcond!(">= input")) // --- error { ... // use i } } Then you need another work around for something like this: if(int value; auto i = someFunc(&value)) { // ... }
Nov 04 2016
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/4/16 11:27 AM, Jerry wrote:
 On Friday, 4 November 2016 at 14:10:51 UTC, Steven Schveighoffer wrote:
 Hm... what about something like:

 struct BoolCond(T, string cond)
 {
    T val;
    bool opCast(B)() if(is(B == bool))
    {
      return mixin("val " ~ cond);
    }
 }

 auto boolcond(string cond, T)(T val)
 {
    return BoolCond!(T, cond)(val);
 }

 if(auto i = someFunc.boolcond!(">= 0"))
 {
    ... // use i
 }
Well that's just a basic case, what if you want more than one condition. Using "&&" for example, or a condition along with another value that's in the scope.
It's just a strawman type, I'm sure there's ways to handle these things, I just didn't put a lot of effort into all the cases. But really it's just syntax to separate the bool check from the value itself. You can get more elaborate if you want with the comparison. The difficult thing is having a type that you use normally, but that when you use in an if statement, it gives what you want. And declaring that type in the if clause itself (which is allowed in restricted circumstances). This also isn't exactly ideal for things like int, as if(i) would now be unexpected.
 Then you need another work around for something like this:

 if(int value; auto i = someFunc(&value))
 {
    // ...
 }
I thought you could only declare variables in the first clause? In any case, I think Stefan really has the best answer: {int value; if(auto i = someFunc(&value)) { // ... }} Sure, it doesn't look great. But my expectation is that your proposal doesn't pull enough weight to be integrated into the language. There are enough ways to solve this problem that don't involve language changes. -Steve
Nov 04 2016
parent reply Jerry <hurricane hereiam.com> writes:
On Friday, 4 November 2016 at 16:15:21 UTC, Steven Schveighoffer 
wrote:
 It's just a strawman type, I'm sure there's ways to handle 
 these things, I just didn't put a lot of effort into all the 
 cases.

 But really it's just syntax to separate the bool check from the 
 value itself. You can get more elaborate if you want with the 
 comparison. The difficult thing is having a type that you use 
 normally, but that when you use in an if statement, it gives 
 what you want. And declaring that type in the if clause itself 
 (which is allowed in restricted circumstances).

 This also isn't exactly ideal for things like int, as if(i) 
 would now be unexpected.
It is just a basic type but ultimately you will probably need more than one type with a different way of operating to get the same behavior. That and having part of the code as a string which makes it harder to read and no syntax highlighting for the code in text editors/ides. What do you mean if(i) would be unexpected?
 I thought you could only declare variables in the first clause?

 In any case, I think Stefan really has the best answer:

 {int value; if(auto i = someFunc(&value))
 {
     // ...
 }}

 Sure, it doesn't look great. But my expectation is that your 
 proposal doesn't pull enough weight to be integrated into the 
 language. There are enough ways to solve this problem that 
 don't involve language changes.

 -Steve
It follows the same rules for an if statement condition which an if statement allows "if(auto i = foo())". It's syntactic sugar, most of the existing language features don't serve a functional purpose. They simply serve to simplify another syntax. Every "foreach" statement could be written as a for-statement. Every for-statement could be written as a while-statement. And so on so forth. It doesn't add anything that new either. It follows the same syntax as a for-statement. It's not that big of a language feature, it's just a small syntactic change, which comes down to. Is this easier to read compared to this. {int value; if(auto i = someFunc(&value)) { // ... }} vs. if(int value; auto i = someFunc(&value)) { // ... } I think it makes it easier to read and it fits with how the for-statement operates. I write code everyday that could utilize this if-statement syntax, so I thought I might as well bring it up. But if there isn't that much interest in it then I won't bother with a DIP.
Nov 04 2016
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/4/16 1:46 PM, Jerry wrote:
 On Friday, 4 November 2016 at 16:15:21 UTC, Steven Schveighoffer wrote:
 It's just a strawman type, I'm sure there's ways to handle these
 things, I just didn't put a lot of effort into all the cases.

 But really it's just syntax to separate the bool check from the value
 itself. You can get more elaborate if you want with the comparison.
 The difficult thing is having a type that you use normally, but that
 when you use in an if statement, it gives what you want. And declaring
 that type in the if clause itself (which is allowed in restricted
 circumstances).

 This also isn't exactly ideal for things like int, as if(i) would now
 be unexpected.
It is just a basic type but ultimately you will probably need more than one type with a different way of operating to get the same behavior. That and having part of the code as a string which makes it harder to read and no syntax highlighting for the code in text editors/ides. What do you mean if(i) would be unexpected?
I mean something like: if(auto i = func.cond("==0")) { assert(i == 0); if(i) { writeln("oops!"); } }
 Sure, it doesn't look great. But my expectation is that your proposal
 doesn't pull enough weight to be integrated into the language. There
 are enough ways to solve this problem that don't involve language
 changes.
It follows the same rules for an if statement condition which an if statement allows "if(auto i = foo())".
Right, I'm just saying syntax changes like this generally need a high motivation and perceived improvement to justify the undertaking. For instance, we have trusted escapes via this construct: auto foo = (() trusted => systemFunc(x))(); It's ugly, verbose, confusing. But it works, and it works today. I'd much rather have this look like: auto foo = trusted(systemFunc(x)); or something similar, but how much benefit are we going to get from this? Is it going to change productivity? Is it going to make code so much easier to write that the time taken to implement was worth it? I don't know the answer to that. Often the answer to requests for such improvements is "yeah, but you can just do it this way, and that's good enough". That's all I'm trying to say.
 It's syntactic sugar, most of the existing language features don't serve
 a functional purpose. They simply serve to simplify another syntax.
 Every "foreach" statement could be written as a for-statement. Every
 for-statement could be written as a while-statement. And so on so forth.
 It doesn't add anything that new either. It follows the same syntax as a
 for-statement.
Existence of current sugar is not justification of adding more. Those already exist (and BTW have existed for a long long time), there is no cost to continuing to have them. There is a cost to adding new features, that we must weigh against the benefits. One thing that could work in your favor is if the change is easy to implement in the compiler. That I definitely don't know the answer to.
 I think it makes it easier to read and it fits with how the
 for-statement operates. I write code everyday that could utilize this
 if-statement syntax, so I thought I might as well bring it up. But if
 there isn't that much interest in it then I won't bother with a DIP.
Please bear in mind that I'm not the gatekeeper, so what I say may not be what the actual ones in control think. It's possible that Walter and Andrei like the idea and would implement if someone fleshed out the proposal. In my experience, I have not encountered too many cases (definitely not zero though) where I needed such a feature. I can see the utility, and I wouldn't be opposed to it. -Steve
Nov 04 2016
parent Jerry <hurricane hereiam.com> writes:
On Friday, 4 November 2016 at 19:26:23 UTC, Steven Schveighoffer 
wrote:
 I think it makes it easier to read and it fits with how the
 for-statement operates. I write code everyday that could 
 utilize this
 if-statement syntax, so I thought I might as well bring it up. 
 But if
 there isn't that much interest in it then I won't bother with 
 a DIP.
Please bear in mind that I'm not the gatekeeper, so what I say may not be what the actual ones in control think. It's possible that Walter and Andrei like the idea and would implement if someone fleshed out the proposal. In my experience, I have not encountered too many cases (definitely not zero though) where I needed such a feature. I can see the utility, and I wouldn't be opposed to it. -Steve
No but you do make a compelling case. Having the scope structured the way you did removed the extra indention and it isn't as error prone as the other methods. You could also have multiple declarations which I don't think work (at least in the C++ implementation) for the new if-statement. {int a; double b; if(func(&a, &b) >= 0) { }}
Nov 04 2016
prev sibling next sibling parent reply Matthias Bentrup <matthias.bentrup googlemail.com> writes:
On Thursday, 3 November 2016 at 22:29:34 UTC, Jerry wrote:
     if(int i = someFunc(); i >= 0)
     {
         // use i
     }
 Thoughts on this sort of feature?
I would prefer the syntax if( (int i = someFunc()) >= 0 ) { // use i } as this matches the already existing assignment expression syntax if you pull the declaration out of the if expression.
Nov 04 2016
parent reply Jerry <hurricane hereiam.com> writes:
On Friday, 4 November 2016 at 14:16:44 UTC, Matthias Bentrup 
wrote:
 On Thursday, 3 November 2016 at 22:29:34 UTC, Jerry wrote:
     if(int i = someFunc(); i >= 0)
     {
         // use i
     }
 Thoughts on this sort of feature?
I would prefer the syntax if( (int i = someFunc()) >= 0 ) { // use i } as this matches the already existing assignment expression syntax if you pull the declaration out of the if expression.
Well you can argue the "if( init ; condition )" syntax matches "for( init ; condition ; update)", minus the "update" section. It's cleaner as well as you don't need an extra set of parenthesizes. As well that sort of syntax would allow multiple declaration. Which I'm not sure that's desired, it becomes increasingly messy. if((int i = someFunc()) >= 0 && (int j = otherFunc()) >= 0) { } You also can't use the declaration as input for someFunc(): if(int i; someFunc(&i) >= 0) { }
Nov 04 2016
parent reply Adrian Matoga <dlang.spam matoga.info> writes:
On Friday, 4 November 2016 at 15:34:00 UTC, Jerry wrote:
 On Friday, 4 November 2016 at 14:16:44 UTC, Matthias Bentrup 
 wrote:
 On Thursday, 3 November 2016 at 22:29:34 UTC, Jerry wrote:
     if(int i = someFunc(); i >= 0)
     {
         // use i
     }
 Thoughts on this sort of feature?
I would prefer the syntax if( (int i = someFunc()) >= 0 ) { // use i } as this matches the already existing assignment expression syntax if you pull the declaration out of the if expression.
Well you can argue the "if( init ; condition )" syntax matches "for( init ; condition ; update)", minus the "update" section.
You've just answered your own question: for (int i = someFunc(); i >= 0; ) { // use i break; }
Nov 04 2016
parent Jerry <hurricane hereiam.com> writes:
On Friday, 4 November 2016 at 18:05:51 UTC, Adrian Matoga wrote:
 On Friday, 4 November 2016 at 15:34:00 UTC, Jerry wrote:
 On Friday, 4 November 2016 at 14:16:44 UTC, Matthias Bentrup 
 wrote:
 On Thursday, 3 November 2016 at 22:29:34 UTC, Jerry wrote:
     if(int i = someFunc(); i >= 0)
     {
         // use i
     }
 Thoughts on this sort of feature?
I would prefer the syntax if( (int i = someFunc()) >= 0 ) { // use i } as this matches the already existing assignment expression syntax if you pull the declaration out of the if expression.
Well you can argue the "if( init ; condition )" syntax matches "for( init ; condition ; update)", minus the "update" section.
You've just answered your own question: for (int i = someFunc(); i >= 0; ) { // use i break; }
Yes, it was one of the examples I gave in the first post. Reason not to use that is, if you forget "break" you are probably going to have an infinite loop. As well you can't use "else" with a for statement.
Nov 04 2016
prev sibling next sibling parent Jerry <Kickupx gmail.com> writes:
On Thursday, 3 November 2016 at 22:29:34 UTC, Jerry wrote:
 Thoughts on this sort of feature?
Love your name, Jerry ;) Maybe something like this psuedo code: struct Condition(T) { Condition(T val, bool cond) { m_val = val; m_cond = cond; } bool opCast(T)() if(is(T == bool)) { return m_cond; } alias m_val this; private: T m_val; bool m_cond; } auto cond(T v, bool cond) { return Condition!T(v, cond); } Usage: int v = 5; if(v = cond(v, v > 4) { writeln("Happy coding"); } Just notice I am not proud of that T.init.
Nov 04 2016
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On Thursday, 3 November 2016 at 22:29:34 UTC, Jerry wrote:
 So I was thinking of a way of extending if statements that have 
 declarations. The following being as example of the current use 
 of if statements with declarations:

     if(int* weDontPollute = someFunc())
     {
          // use weDontPollute
     }

 That's great and all, but it only works by checking if the 
 variable evaluates to true or false. Which is fine for a 
 pointer but otherwise useless for anything else, like integers 
 where zero is usually valid input (index for array).
This is already possible in library code. See here: https://github.com/AndrejMitrovic/minilib/blob/510460ff1381f765a66aa3b8f8f6d7e95b4597b9/src/minilib/core/types.d#L88-L137 One could come up with a helper function that encodes the condition which is moved into the opCast method. This should be trivial to implement.
Nov 04 2016
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 04.11.2016 21:03, Andrej Mitrovic wrote:
 On Thursday, 3 November 2016 at 22:29:34 UTC, Jerry wrote:
 So I was thinking of a way of extending if statements that have
 declarations. The following being as example of the current use of if
 statements with declarations:

     if(int* weDontPollute = someFunc())
     {
          // use weDontPollute
     }

 That's great and all, but it only works by checking if the variable
 evaluates to true or false. Which is fine for a pointer but otherwise
 useless for anything else, like integers where zero is usually valid
 input (index for array).
This is already possible in library code. See here: https://github.com/AndrejMitrovic/minilib/blob/510460ff1381f765a66aa3b8f8f6d7e95b4597b9/src/minilib/core/types.d#L88-L137
Not worth the IFTI-induced template bloat IMHO.
Nov 04 2016
prev sibling next sibling parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Thursday, November 03, 2016 22:29:34 Jerry via Digitalmars-d wrote:
      if(int i = someFunc(); i >= 0)
      {
          // use i
      }
 Thoughts on this sort of feature?
Personally, I'd love to have it, and I think that it's been suggested before (though I don't remember how that discussion went). I think that it would be a nice syntactic improvement over what Stefan suggested with an additional set of braces. It also would work with the else if case, whereas adding an extra scope would not. And I think that any chance of it actually being added to the language would hinge on its ability to either make stuff possible which is not currently possible or on its ability to make stuff that's really awkward easy to do in a non-awkward way. And there's a better case to be made that if(cond) { } else if(auto result = foo(); cond2) { } else if(cond3) { } is harder to emulate with the current language than doing it with the first if - though even with the first if branch, if you have something like if(auto result = foo(); cond1) { } else if(cond2) { } else if(cond3) { } the variable created in the first if branch would presumably leave scope immediately after the condition failed, which would also be much more difficult to emulate by adding additional braces. So, maybe it could be argued successfully with a DIP, but in general at this point, I think that Walter and Andrei are very resistant to making changes to the language - especially when it's simply for aesthetic benefit. So, any proposing a feature needs to be able to show that it brings real value. And while I, personally, think that this brings real value for certain use cases, I don't know if it brings enough value in general to be worth the addition, and more importantly, I don't know if Walter or Andrei would think that it's worth it, and they're the ones who need to be convinced. Ultimately though, the biggest hurdle is that someone needs to create a DIP for it that strongly argues its case with real world examples of how it would improve code (preferably with code from Phobos and code.dlang.org), and without a really well-written DIP it's going to be dead in the water unless Walter or Andrei already happened to have wished for something like that often enough that they didn't take much convincing (which I wouldn't bet on). Right now, the bar to get a new feature in is pretty high even simply from the standpoint of the amount of work required to successfully propose it. - Jonathan M Davis
Nov 05 2016
next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Saturday, 5 November 2016 at 19:52:05 UTC, Jonathan M Davis 
wrote:
 and more importantly, I don't know if Walter or Andrei would 
 think that it's worth it, and they're the ones who need to be 
 convinced.
this addition looks like needless overcomplication even for me. and i'm usually collecting feature for aliced without any formalities. ;-)
Nov 05 2016
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/5/16 3:52 PM, Jonathan M Davis via Digitalmars-d wrote:
 Ultimately though, the biggest hurdle is that someone needs to create a DIP
 for it that strongly argues its case with real world examples of how it
 would improve code (preferably with code from Phobos and code.dlang.org),
 and without a really well-written DIP it's going to be dead in the water
The declaration with "if" seems to be a recent fashion. I've first seen it in Go and now C++17 took a shine to it - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r0.html. A DIP would do good to cite that related work. It seems a low impact feature. Also, the Go/C++ syntaxes seem suboptimal to me because they are stuttering: if variable := fun(); variable != 42 { ... } or (C++): if (auto variable = fun(); variable != 42) { ... } Why does the word "variable" need to appear twice? It seems simpler to allow punctuation around existing syntax: // possible future D if ((auto variable = fun()) != 42) { ... } Defining a variable in an expression wouldn't be allowed everywhere (but might be contemplated later as an possibility, which is a nice thing about this syntax). A more approachable thing to do is allow variable definitions in switch statements: switch (auto x = fun() { ... } It is surprising that doesn't work, which is a good argument in favor of the feature (removal of an undue limitation, rule of least astonishment etc). Andrei
Nov 05 2016
next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Sunday, 6 November 2016 at 05:07:10 UTC, Andrei Alexandrescu 
wrote:
 A more approachable thing to do is allow variable definitions 
 in switch statements:

 switch (auto x = fun() { ... }

 It is surprising that doesn't work, which is a good argument in 
 favor of the feature (removal of an undue limitation, rule of 
 least astonishment etc).
https://issues.dlang.org/show_bug.cgi?id=11070 lol
Nov 05 2016
prev sibling next sibling parent Enamex <enamex+d outlook.com> writes:
On Sunday, 6 November 2016 at 05:07:10 UTC, Andrei Alexandrescu 
wrote:
 The declaration with "if" seems to be a recent fashion. I've 
 first seen it in Go and now C++17 took a shine to it - 
 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0305r0.html. A DIP
would do good to cite that related work.

 It seems a low impact feature. Also, the Go/C++ syntaxes seem 
 suboptimal to me because they are stuttering:

 if variable := fun(); variable != 42 {
   ...
 }

 or (C++):

 if (auto variable = fun(); variable != 42) {
   ...
 }

 Why does the word "variable" need to appear twice? It seems 
 simpler to allow punctuation around existing syntax:

 // possible future D
 if ((auto variable = fun()) != 42) {
   ...
 }

 Defining a variable in an expression wouldn't be allowed 
 everywhere (but might be contemplated later as an possibility, 
 which is a nice thing about this syntax).

 Andrei
I remember an old suggestion/DIP allowing 'with' statements to introduce/declare symbols/variables. Might be a cleaner extension to existing language: with(auto x = f()) if(foo(x)) {} else with(auto r = root(t)) if(leaf(r) || blah < bar) {}
Nov 06 2016
prev sibling next sibling parent Nick Treleaven <nick geany.org> writes:
On Sunday, 6 November 2016 at 05:07:10 UTC, Andrei Alexandrescu 
wrote:
 if (auto variable = fun(); variable != 42) {
   ...
 }

 Why does the word "variable" need to appear twice? It seems 
 simpler to allow punctuation around existing syntax:

 // possible future D
 if ((auto variable = fun()) != 42) {
   ...
 }
Avoiding stuttering is nice, but maybe it could be made a bit clearer if declarations were allowed for ref arguments and we used a named function: alias let = (ref v) => v; if (let(auto variable = fun()) != 42) {...} The same feature allows tuple unpacking: produceTuple.unpack(auto str, int i); C++ syntax too as local variable names are usually short and it avoids brackets.
Nov 07 2016
prev sibling parent Anonymouse <asdf asdf.net> writes:
On Sunday, 6 November 2016 at 05:07:10 UTC, Andrei Alexandrescu 
wrote:
 // possible future D
 if ((auto variable = fun()) != 42) {
   ...
 }

 Defining a variable in an expression wouldn't be allowed 
 everywhere (but might be contemplated later as an possibility, 
 which is a nice thing about this syntax).
I like it but it would have to require the parantheses, or you could get ambiguities like: if (auto variable = noParensGetSomeT == true) { // is variable of type T or bool, if T can be implicitly cast? }
 A more approachable thing to do is allow variable definitions 
 in switch statements:

 switch (auto x = fun() { ... }

 It is surprising that doesn't work, which is a good argument in 
 favor of the feature (removal of an undue limitation, rule of 
 least astonishment etc).
This I can get behind, would start using it right away.
 Andrei
Nov 07 2016
prev sibling parent ArturG <var.spool.mail700 gmail.com> writes:
On Thursday, 3 November 2016 at 22:29:34 UTC, Jerry wrote:
 So I was thinking of a way of extending if statements that have 
 declarations. The following being as example of the current use 
 of if statements with declarations:

     if(int* weDontPollute = someFunc())
     {
          // use weDontPollute
     }

 That's great and all, but it only works by checking if the 
 variable evaluates to true or false. Which is fine for a 
 pointer but otherwise useless for anything else, like integers 
 where zero is usually valid input (index for array). So 
 currently the only way to do something like this in the 
 language, that i've found, is to use a for statement.

     for(int i = someFunc(); i >= 0;)
     {
         // use i

         break;
     }

 Not that ideal to use a for statement. It makes it hard to read 
 and if the break condition isn't there it might very well be an 
 infinite loop. So I was thinking of some sort of syntax like 
 this:

     if(int i = someFunc(); i >= 0)
     {
         // use i
     }
 Thoughts on this sort of feature?
Hi, i refactored some templates[1] i had, so that you can provide your own predicate functions. Variant 1 eager version: auto when(alias pred, alias fun, T)(T type = T.init) Variant 2 a lazy version, uses two templates: auto when(alias pred, T)(T type = T.init) auto call(alias fun, T)(T type) check/modify the examples found here [1] http://melpon.org/wandbox/permlink/g7V0gj4V7SGPjwqL *OT is dpaste broken (cant seem to create new pastes) or is it just me?
Nov 07 2016