Jump to page: 1 2 3
Thread overview
Why no (auto foo = bar) in while loops?
Aug 24, 2011
Andrej Mitrovic
Aug 24, 2011
Timon Gehr
Aug 24, 2011
Andrej Mitrovic
Aug 24, 2011
Timon Gehr
Aug 24, 2011
Jonathan M Davis
Aug 24, 2011
Timon Gehr
Aug 24, 2011
Andrej Mitrovic
Aug 24, 2011
Mafi
Aug 24, 2011
Timon Gehr
Aug 25, 2011
Timon Gehr
Aug 25, 2011
Jonathan M Davis
Aug 25, 2011
Jonathan M Davis
Aug 25, 2011
Timon Gehr
Aug 25, 2011
Timon Gehr
Aug 25, 2011
Timon Gehr
Aug 26, 2011
Ali Çehreli
Aug 26, 2011
Timon Gehr
August 24, 2011
Here's some code that iterates through "parents" of some class object until it finds an object with no parent (where parent is null):

import std.stdio;

class Foo
{
    Foo parent;
    int state;

    this (int state) { this.state = state; }
}

void main()
{
    auto foo          = new Foo(0);
    foo.parent        = new Foo(1);
    foo.parent.parent = new Foo(2);

    while (true)
    {
        if (auto par = foo.parent)
        {
            writeln(par.state);
            foo = par;
        }
        else
        {
            break;
        }
    }
}

(syntax-highlighted: http://codepad.org/8yHRmICh)

But I was hoping I could simplify this by doing:

    while (auto par = foo.parent)
    {
        writeln(par.state);
        foo = par;
    }

However that doesn't work, I get back:
expression expected, not 'auto'

Is there a limitation on why this couldn't work or can this be added to the language?
August 24, 2011
On 08/24/2011 08:04 PM, Andrej Mitrovic wrote:
> Here's some code that iterates through "parents" of some class object
> until it finds an object with no parent (where parent is null):
>
> import std.stdio;
>
> class Foo
> {
>      Foo parent;
>      int state;
>
>      this (int state) { this.state = state; }
> }
>
> void main()
> {
>      auto foo          = new Foo(0);
>      foo.parent        = new Foo(1);
>      foo.parent.parent = new Foo(2);
>
>      while (true)
>      {
>          if (auto par = foo.parent)
>          {
>              writeln(par.state);
>              foo = par;
>          }
>          else
>          {
>              break;
>          }
>      }
> }
>
> (syntax-highlighted: http://codepad.org/8yHRmICh)
>
> But I was hoping I could simplify this by doing:
>
>      while (auto par = foo.parent)
>      {
>          writeln(par.state);
>          foo = par;
>      }
>
> However that doesn't work, I get back:
> expression expected, not 'auto'
>
> Is there a limitation on why this couldn't work or can this be added
> to the language?

Afaics, this could be added just like it could be added for if. In fact the compiler should be able to simply rewrite it to your first example.
I think it is worth an enhancement request, because there are situations where this would be useful, and implementation should be trivial, if somebody has the time. (I also think it adds to the consistency of the language, but others may disagree.)


(btw, i always use for(;;) instead of while(true), it is usually faster in debug mode and faster to type :))
August 24, 2011
On 8/24/11, Timon Gehr <timon.gehr@gmx.ch> wrote:
> it is usually faster
> in debug mode

Huh.. How come?
August 24, 2011
On 08/24/2011 09:21 PM, Andrej Mitrovic wrote:
> On 8/24/11, Timon Gehr<timon.gehr@gmx.ch>  wrote:
>> it is usually faster
>> in debug mode
>
> Huh.. How come?

Well, not notably faster, but many compilers will emit something in the lines of

mov eax, 1
test eax
jnz beginning_of_loop

if no optimizer is run,

whereas most get

for(;;){}

as

jmp beginning_of_loop

even in debug mode.
August 24, 2011
On Wednesday, August 24, 2011 21:29:23 Timon Gehr wrote:
> On 08/24/2011 09:21 PM, Andrej Mitrovic wrote:
> > On 8/24/11, Timon Gehr<timon.gehr@gmx.ch>  wrote:
> >> it is usually faster
> >> in debug mode
> > 
> > Huh.. How come?
> 
> Well, not notably faster, but many compilers will emit something in the lines of
> 
> mov eax, 1
> test eax
> jnz beginning_of_loop
> 
> if no optimizer is run,
> 
> whereas most get
> 
> for(;;){}
> 
> as
> 
> jmp beginning_of_loop
> 
> even in debug mode.

Optimizations aside, I would always argue that while(true) should be used rather than for(;;). I find for(;;) to be ugly personally and would argue that while(true) better captures what you're actually doing. A loop with no condition at all is horrible IMHO. It seems completely inconsistent to me that the language would allow you to have a for loop without a condition.

Regardless of that, however, I would fully expect that if there is a difference in code between the two in debug mode (which there shouldn't be IMHO, but compilers don't always do what makes the most sense - especially in debug mode) that the difference would be drowned by the contents of the loop and wouldn't matter at all. But even if it did, I'd generally argue that coding in a certain way just because it was slightly faster in debug mode but had zero impact in release mode is not a good idea unless all of the considerations are equal. And I'd definitely argue that while(true) is better than for(;;) from an aesthetic point of view at minimum, so they definitely aren't equal.

In any case, that's my take on it.

- Jonathan M Davis
August 24, 2011
On 08/24/2011 09:36 PM, Jonathan M Davis wrote:
> On Wednesday, August 24, 2011 21:29:23 Timon Gehr wrote:
>> On 08/24/2011 09:21 PM, Andrej Mitrovic wrote:
>>> On 8/24/11, Timon Gehr<timon.gehr@gmx.ch>   wrote:
>>>> it is usually faster
>>>> in debug mode
>>>
>>> Huh.. How come?
>>
>> Well, not notably faster, but many compilers will emit something in the
>> lines of
>>
>> mov eax, 1
>> test eax
>> jnz beginning_of_loop
>>
>> if no optimizer is run,
>>
>> whereas most get
>>
>> for(;;){}
>>
>> as
>>
>> jmp beginning_of_loop
>>
>> even in debug mode.
>
> Optimizations aside, I would always argue that while(true) should be used
> rather than for(;;). I find for(;;) to be ugly personally and would argue that
> while(true) better captures what you're actually doing. A loop with no
> condition at all is horrible IMHO. It seems completely inconsistent to me that
> the language would allow you to have a for loop without a condition.
>
> Regardless of that, however, I would fully expect that if there is a difference
> in code between the two in debug mode (which there shouldn't be IMHO, but
> compilers don't always do what makes the most sense - especially in debug
> mode) that the difference would be drowned by the contents of the loop and
> wouldn't matter at all. But even if it did, I'd generally argue that coding in
> a certain way just because it was slightly faster in debug mode but had zero
> impact in release mode is not a good idea unless all of the considerations are
> equal. And I'd definitely argue that while(true) is better than for(;;) from an
> aesthetic point of view at minimum, so they definitely aren't equal.
>
> In any case, that's my take on it.
>
> - Jonathan M Davis

Well, it is consistent in that you can leave out the other parts in for too. (but those are statements, and you can almost everywhere write an empty statement, while there exist no empty expressions)

As to while(true) vs for(;;), in my point of view, it is the other way round, because how it is compiled in debug mode is really how the semantics of the language are: look at the condition, and if it is true, loop another time, if it is false, break. If you want an infinite loop, why bother having to write a condition to evaluate? Imho for(;;){} captures the meaning better than while(true){}. for(;;){} means, loop unconditionally (which proves insight in what it is actually doing), and while(true){} means 'loop until true is false', which is imo ugly for obvious reasons.

That is my way of thinking about aesthetics in programming.

August 24, 2011
Req'd: http://d.puremagic.com/issues/show_bug.cgi?id=6550
August 24, 2011
Am 24.08.2011 21:04, schrieb Timon Gehr:
> On 08/24/2011 08:04 PM, Andrej Mitrovic wrote:
>> Here's some code that iterates through "parents" of some class object
>> until it finds an object with no parent (where parent is null):
>>
>> import std.stdio;
>>
>> class Foo
>> {
>> Foo parent;
>> int state;
>>
>> this (int state) { this.state = state; }
>> }
>>
>> void main()
>> {
>> auto foo = new Foo(0);
>> foo.parent = new Foo(1);
>> foo.parent.parent = new Foo(2);
>>
>> while (true)
>> {
>> if (auto par = foo.parent)
>> {
>> writeln(par.state);
>> foo = par;
>> }
>> else
>> {
>> break;
>> }
>> }
>> }
>>
>> (syntax-highlighted: http://codepad.org/8yHRmICh)
>>
>> But I was hoping I could simplify this by doing:
>>
>> while (auto par = foo.parent)
>> {
>> writeln(par.state);
>> foo = par;
>> }
>>
>> However that doesn't work, I get back:
>> expression expected, not 'auto'
>>
>> Is there a limitation on why this couldn't work or can this be added
>> to the language?
>
> Afaics, this could be added just like it could be added for if. In fact
> the compiler should be able to simply rewrite it to your first example.
> I think it is worth an enhancement request, because there are situations
> where this would be useful, and implementation should be trivial, if
> somebody has the time. (I also think it adds to the consistency of the
> language, but others may disagree.)
>
>
> (btw, i always use for(;;) instead of while(true), it is usually faster
> in debug mode and faster to type :))

I just have to say that it already works for 'if'. It's a great feature because in the body of the 'if' you know the value is non-null and outside,  where there could be an segfault, the variable is not visible.
I'm not really sure if it's good for 'while'.
I'm unsure because there are two somewhat natural semantics for such a construct.

//example
//more to the nature of while
while(auto obj = init) { work(obj); }

//1 (your interpretation)
typeof(init) obj;
while(obj = init) { work(obj); }

//2
/*
seems more natural for me because init runs only once (like any other init and like in 'for' or 'if')
*/
auto obj = init;
while(obj) { work(obj); }

This could confuse many people, I think. What do you think?

Mafi

August 24, 2011
On 08/25/2011 12:47 AM, Mafi wrote:
> Am 24.08.2011 21:04, schrieb Timon Gehr:
>> On 08/24/2011 08:04 PM, Andrej Mitrovic wrote:
>>> Here's some code that iterates through "parents" of some class object
>>> until it finds an object with no parent (where parent is null):
>>>
>>> import std.stdio;
>>>
>>> class Foo
>>> {
>>> Foo parent;
>>> int state;
>>>
>>> this (int state) { this.state = state; }
>>> }
>>>
>>> void main()
>>> {
>>> auto foo = new Foo(0);
>>> foo.parent = new Foo(1);
>>> foo.parent.parent = new Foo(2);
>>>
>>> while (true)
>>> {
>>> if (auto par = foo.parent)
>>> {
>>> writeln(par.state);
>>> foo = par;
>>> }
>>> else
>>> {
>>> break;
>>> }
>>> }
>>> }
>>>
>>> (syntax-highlighted: http://codepad.org/8yHRmICh)
>>>
>>> But I was hoping I could simplify this by doing:
>>>
>>> while (auto par = foo.parent)
>>> {
>>> writeln(par.state);
>>> foo = par;
>>> }
>>>
>>> However that doesn't work, I get back:
>>> expression expected, not 'auto'
>>>
>>> Is there a limitation on why this couldn't work or can this be added
>>> to the language?
>>
>> Afaics, this could be added just like it could be added for if. In fact
>> the compiler should be able to simply rewrite it to your first example.
>> I think it is worth an enhancement request, because there are situations
>> where this would be useful, and implementation should be trivial, if
>> somebody has the time. (I also think it adds to the consistency of the
>> language, but others may disagree.)
>>
>>
>> (btw, i always use for(;;) instead of while(true), it is usually faster
>> in debug mode and faster to type :))
>
> I just have to say that it already works for 'if'. It's a great feature
> because in the body of the 'if' you know the value is non-null and
> outside, where there could be an segfault, the variable is not visible.
> I'm not really sure if it's good for 'while'.
> I'm unsure because there are two somewhat natural semantics for such a
> construct.
>
> //example
> //more to the nature of while
> while(auto obj = init) { work(obj); }
>
> //1 (your interpretation)
> typeof(init) obj;
> while(obj = init) { work(obj); }
>
> //2
> /*
> seems more natural for me because init runs only once (like any other
> init and like in 'for' or 'if')
> */

for(;;){int x=init;} // init runs infinitely many times


if(auto a=init){} is really more trying to solve

if(???){auto a=init;} // correct scoping but cannot refer to it in cond

than

{auto a=init; if(a){}} // correct scoping as long as there is no else

That is why there is the language construct. That it has not been adopted for while is because it is so much more useful for if, but I personally think while could/should get the possibility as well.



> auto obj = init;
> while(obj) { work(obj); }
>
> This could confuse many people, I think. What do you think?
>

I think that by the same argument, you could say that the fact that the body of a looping statement is executed multiple times could confuse many people.

1 is more natural imho. (and 2 would be rather useless)


August 25, 2011
On Wed, 24 Aug 2011 19:01:31 -0400, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 08/25/2011 12:47 AM, Mafi wrote:
>> Am 24.08.2011 21:04, schrieb Timon Gehr:
>>> On 08/24/2011 08:04 PM, Andrej Mitrovic wrote:
>>>> Here's some code that iterates through "parents" of some class object
>>>> until it finds an object with no parent (where parent is null):
>>>>
>>>> import std.stdio;
>>>>
>>>> class Foo
>>>> {
>>>> Foo parent;
>>>> int state;
>>>>
>>>> this (int state) { this.state = state; }
>>>> }
>>>>
>>>> void main()
>>>> {
>>>> auto foo = new Foo(0);
>>>> foo.parent = new Foo(1);
>>>> foo.parent.parent = new Foo(2);
>>>>
>>>> while (true)
>>>> {
>>>> if (auto par = foo.parent)
>>>> {
>>>> writeln(par.state);
>>>> foo = par;
>>>> }
>>>> else
>>>> {
>>>> break;
>>>> }
>>>> }
>>>> }
>>>>
>>>> (syntax-highlighted: http://codepad.org/8yHRmICh)
>>>>
>>>> But I was hoping I could simplify this by doing:
>>>>
>>>> while (auto par = foo.parent)
>>>> {
>>>> writeln(par.state);
>>>> foo = par;
>>>> }
>>>>
>>>> However that doesn't work, I get back:
>>>> expression expected, not 'auto'
>>>>
>>>> Is there a limitation on why this couldn't work or can this be added
>>>> to the language?
>>>
>>> Afaics, this could be added just like it could be added for if. In fact
>>> the compiler should be able to simply rewrite it to your first example.
>>> I think it is worth an enhancement request, because there are situations
>>> where this would be useful, and implementation should be trivial, if
>>> somebody has the time. (I also think it adds to the consistency of the
>>> language, but others may disagree.)
>>>
>>>
>>> (btw, i always use for(;;) instead of while(true), it is usually faster
>>> in debug mode and faster to type :))
>>
>> I just have to say that it already works for 'if'. It's a great feature
>> because in the body of the 'if' you know the value is non-null and
>> outside, where there could be an segfault, the variable is not visible.
>> I'm not really sure if it's good for 'while'.
>> I'm unsure because there are two somewhat natural semantics for such a
>> construct.
>>
>> //example
>> //more to the nature of while
>> while(auto obj = init) { work(obj); }
>>
>> //1 (your interpretation)
>> typeof(init) obj;
>> while(obj = init) { work(obj); }
>>
>> //2
>> /*
>> seems more natural for me because init runs only once (like any other
>> init and like in 'for' or 'if')
>> */
>
> for(;;){int x=init;} // init runs infinitely many times
>
>
> if(auto a=init){} is really more trying to solve
>
> if(???){auto a=init;} // correct scoping but cannot refer to it in cond
>
> than
>
> {auto a=init; if(a){}} // correct scoping as long as there is no else
>
> That is why there is the language construct. That it has not been adopted for while is because it is so much more useful for if, but I personally think while could/should get the possibility as well.
>
>
>
>> auto obj = init;
>> while(obj) { work(obj); }
>>
>> This could confuse many people, I think. What do you think?
>>
>
> I think that by the same argument, you could say that the fact that the body of a looping statement is executed multiple times could confuse many people.
>
> 1 is more natural imho. (and 2 would be rather useless)

I disagree -- I think the semantics are confusing.

I'd say just leave the auto x = y for if and for loops, where there is a clear "run once" section.

Also, what do you do with a do while loop if the while contains this construct?

I just find the whole thing confusing.

-Steve
« First   ‹ Prev
1 2 3