www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Bug or logic error in if with auto?

reply "js.mdnq" <js_adddot+mdng gmail.com> writes:
Can this be made to work in D?

Error in D, x not found:

if (auto x = "thing" in arr && x == 45)
{

}

Works:

if (auto x = "thing" in arr)
     if (x == 45)
     {

     }
Dec 02 2012
next sibling parent "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Sunday, 2 December 2012 at 15:09:17 UTC, js.mdnq wrote:
 Can this be made to work in D?

 Error in D, x not found:

 if (auto x = "thing" in arr && x == 45)
 {

 }

You can't have both a declaration and expression in an if-statement. http://dlang.org/statement.html#IfStatement IfStatement: if ( IfCondition ) ThenStatement if ( IfCondition ) ThenStatement else ElseStatement IfCondition: Expression auto Identifier = Expression BasicType Declarator = Expression
Dec 02 2012
prev sibling next sibling parent "Peter Alexander" <peter.alexander.au gmail.com> writes:
And no, it cannot be made to work, because the grammar would be 
ambiguous:

if (auto x = y && z)

Does this mean?

if (auto x = (y && z))

or

if (auto x = y)
     if (x && z)


You could make it work with new syntax, but given you can just 
use two if-statements, I don't see any point.
Dec 02 2012
prev sibling next sibling parent reply Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 02/12/2012 15:09, js.mdnq wrote:
 Can this be made to work in D?

 Error in D, x not found:

 if (auto x = "thing" in arr && x == 45)
 {

 }

 Works:

 if (auto x = "thing" in arr)
      if (x == 45)
      {

      }

Most programmers would probably just pollute the existing scope: auto x = "thing" in arr; if (x && *x == 45) { ... } I expect this is because wrapping the above in {} for a new scope is just too ugly, introducing more nesting and indentation. It would be nice if there was a way of introducing a new scope just for a declaration and the next statement, something like: with auto x = "thing" in arr: if (x && *x == 45) { // x is still visible here } That would overload 'with' with a different meaning, but would be clear enough IMO. It would be useful with other constructs like while, do, foreach, etc. I think it would be more elegant than allowing a declaration clause in all constructs (like the 'for' statement has). As you have shown, D's 'if' statement declaration form is perhaps not very useful. About while declaration syntax, see: http://d.puremagic.com/issues/show_bug.cgi?id=5432
Dec 03 2012
next sibling parent Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 03/12/2012 20:17, Rob T wrote:
 On Monday, 3 December 2012 at 14:22:28 UTC, Nick Treleaven wrote:

 Most programmers would probably just pollute the existing scope:

 auto x = "thing" in arr;
 if (x && *x == 45)
 {
     ...
 }

You can always wrap it inside its own scope

Yes, that's why I wrote:
 I expect this is because wrapping the above in {} for a new scope is
 just too ugly, introducing more nesting and indentation.

;-)
    // temp scope
    {
      auto x = "thing" in arr;
      if (x && *x == 45)
      {
         ...
      }
    }

I would much prefer this: with (auto x = "thing" in arr) if (x && *x == 45) { ... }
Dec 04 2012
prev sibling parent Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 03/12/2012 14:22, Nick Treleaven wrote:
 Most programmers would probably just pollute the existing scope:

 auto x = "thing" in arr;
 if (x && *x == 45)
 {
      ...
 }

 I expect this is because wrapping the above in {} for a new scope is
 just too ugly, introducing more nesting and indentation.

 It would be nice if there was a way of introducing a new scope just for
 a declaration and the next statement, something like:

 with auto x = "thing" in arr:
 if (x && *x == 45)
 {
      // x is still visible here
 }

 That would overload 'with' with a different meaning, but would be clear
 enough IMO. It would be useful with other constructs like while, do,
 foreach, etc. I think it would be more elegant than allowing a
 declaration clause in all constructs (like the 'for' statement has).

The above syntax was inspired from Tove and Tommi's existing solution (I couldn't find the link earlier): http://forum.dlang.org/post/nyhpuaoxkeunwqongfyk forum.dlang.org The idea was to use a Tuple to wrap the new variable: with (Tuple!(int, "a")(getInt())) if (a > 9) ... I've now improved on this syntax using opDispatch and opAssign so we can write: with (wrap.a = getInt()) if (a > 9) ... Whether using this in real code is good practice or not may be debatable ;-) Code: http://dpaste.dzfl.pl/4dbefd84
Dec 07 2012
prev sibling next sibling parent "Rob T" <rob ucora.com> writes:
On Monday, 3 December 2012 at 14:22:28 UTC, Nick Treleaven wrote:

 Most programmers would probably just pollute the existing scope:

 auto x = "thing" in arr;
 if (x && *x == 45)
 {
     ...
 }

You can always wrap it inside its own scope main() { // temp scope { auto x = "thing" in arr; if (x && *x == 45) { ... } } writeln(x); // <- error x is undefined }
Dec 03 2012
prev sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Friday, 7 December 2012 at 14:21:51 UTC, Nick Treleaven wrote:
 On 03/12/2012 14:22, Nick Treleaven wrote:
 Most programmers would probably just pollute the existing 
 scope:

 auto x = "thing" in arr;
 if (x && *x == 45)
 {
     ...
 }

 I expect this is because wrapping the above in {} for a new 
 scope is
 just too ugly, introducing more nesting and indentation.

 It would be nice if there was a way of introducing a new scope 
 just for
 a declaration and the next statement, something like:

 with auto x = "thing" in arr:
 if (x && *x == 45)
 {
     // x is still visible here
 }

 That would overload 'with' with a different meaning, but would 
 be clear
 enough IMO. It would be useful with other constructs like 
 while, do,
 foreach, etc. I think it would be more elegant than allowing a
 declaration clause in all constructs (like the 'for' statement 
 has).

The above syntax was inspired from Tove and Tommi's existing solution (I couldn't find the link earlier): http://forum.dlang.org/post/nyhpuaoxkeunwqongfyk forum.dlang.org The idea was to use a Tuple to wrap the new variable: with (Tuple!(int, "a")(getInt())) if (a > 9) ... I've now improved on this syntax using opDispatch and opAssign so we can write: with (wrap.a = getInt()) if (a > 9) ... Whether using this in real code is good practice or not may be debatable ;-) Code: http://dpaste.dzfl.pl/4dbefd84

That is really an interesting idea.
Dec 07 2012