Thread overview
Bug or logic error in if with auto?
Dec 02, 2012
js.mdnq
Dec 02, 2012
Peter Alexander
Dec 02, 2012
Peter Alexander
Dec 03, 2012
Nick Treleaven
Dec 03, 2012
Rob T
Dec 04, 2012
Nick Treleaven
Dec 07, 2012
Nick Treleaven
Dec 07, 2012
deadalnix
December 02, 2012
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)
    {

    }




December 02, 2012
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

December 02, 2012
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.
December 03, 2012
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
December 03, 2012
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

}


December 04, 2012
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)
{
    ...
}
December 07, 2012
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
December 07, 2012
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.