View mode: basic / threaded / horizontal-split · Log in · Help
October 05, 2012
Re: Feature request: extending comma operator's functionality
On Friday, 5 October 2012 at 00:22:04 UTC, Jonathan M Davis wrote:
> On Friday, October 05, 2012 02:08:14 bearophile wrote:
>> [SNIP]
>> Regarding definition of variables in D language constructs, 
>> there
>> is one situation where sometimes I find D not handy. This code
>> can't work:
>> 
>> do {
>> const x = ...;
>> } while (predicate(x));
>> 
>> 
>> You need to use:
>>
>> T x;
>> do {
>> x = ...;
>> } while (predicate(x));
>
> Yeah. That comes from C/C++ (and is the same in Java and C#, I 
> believe). I
> don't know why it works that way. It's definitely annoying.
> 
> [SNIP]
>
> - Jonathan M Davis

Because it's the only way to guarantee that x exits when you 
reach the end of the loop.

do {
  if(true) continue; //Yawn... skip.
  const x = ... ;
} while (predicate(x)); //What's x?

Basic goto limitations. Unlike goto though, inserting a 
"continue" should never create a compile error, so the compiler 
*has* to guarantee that the if condition references nothing 
inside its own block.

It is annoying, but nothing that can't be fixed with a scope bloc.
October 05, 2012
Re: Feature request: extending comma operator's functionality
On 05/10/12 15:35, monarch_dodra wrote:
> On Friday, 5 October 2012 at 00:22:04 UTC, Jonathan M Davis wrote:
>> On Friday, October 05, 2012 02:08:14 bearophile wrote:
>>> [SNIP]
>>> Regarding definition of variables in D language constructs, there
>>> is one situation where sometimes I find D not handy. This code
>>> can't work:
>>>
>>> do {
>>> const x = ...;
>>> } while (predicate(x));
>>>
>>>
>>> You need to use:
>>>
>>> T x;
>>> do {
>>> x = ...;
>>> } while (predicate(x));
>>
>> Yeah. That comes from C/C++ (and is the same in Java and C#, I
>> believe). I
>> don't know why it works that way. It's definitely annoying.
>>
>> [SNIP]
>>
>> - Jonathan M Davis
>
> Because it's the only way to guarantee that x exits when you reach the
> end of the loop.
>
> do {
>    if(true) continue; //Yawn... skip.
>    const x = ... ;
> } while (predicate(x)); //What's x?
>
> Basic goto limitations. Unlike goto though, inserting a "continue"
> should never create a compile error, so the compiler *has* to guarantee
> that the if condition references nothing inside its own block.
>
> It is annoying, but nothing that can't be fixed with a scope bloc.

My feeling is that  do{}while() is a fairly useless concept, and this is 
part of the reason.
In my experience genuine do-while loops are extremely rare, and it only 
takes a slight change to the loop to force a different structure to be used.
Conditional loops which don't follow the while(){...} pattern normally 
follow the loop-and-a-half pattern, also known as begin-while-repeat (I 
think that's the name Knuth used). I'll call it 'super do':

super do {
   foo();
   while(cond);
   bar();
}

which in D is better modelled by:

for (;;)
{
   foo();
   if (!cond) break;
   bar();
}

rather than by a do-while loop. But it's a bit ugly, and doesn't enforce 
a single break. IMHO it's a shame we've gone with the fairly useless 
do-while, rather than cleaning up the syntax for loop-and-a-half.

I don't think the proposed changes bring us much closer to a useful 
language construct.
October 05, 2012
Re: Feature request: extending comma operator's functionality
On Friday, 5 October 2012 at 15:35:31 UTC, Don Clugston wrote:
>
> My feeling is that  do{}while() is a fairly useless concept...
> [SNIP]

The most frequent use I have for do while is to hack it to 
construct break-able blocks actually ^^ :

//----
do
{
    if(!condition1) break;
    if(!condition2) break;
    if(!condition3) break;
    if(!condition4) break;
    //DO SOMETHING
}while(false);
//----

It is a nice way to avoid the dreaded 
"if(if(if(if(if(if())))))))" triangle.

Related:
http://d.puremagic.com/issues/show_bug.cgi?id=8622
October 05, 2012
Re: Feature request: extending comma operator's functionality
> Because it's the only way to guarantee that x exits when you 
> reach the end of the loop.
>
> do {
>   if(true) continue; //Yawn... skip.
>   const x = ... ;
> } while (predicate(x)); //What's x?

But the compiler could tell that there is a 'continue' before x 
was declared, and issue an error when it is used in while(...)
October 05, 2012
Re: Feature request: extending comma operator's functionality
On Fri, Oct 05, 2012 at 05:23:40PM +0200, Don Clugston wrote:
[...]
> My feeling is that  do{}while() is a fairly useless concept, and
> this is part of the reason.
> In my experience genuine do-while loops are extremely rare, and it
> only takes a slight change to the loop to force a different
> structure to be used.
> Conditional loops which don't follow the while(){...} pattern
> normally follow the loop-and-a-half pattern, also known as
> begin-while-repeat (I think that's the name Knuth used). I'll call
> it 'super do':
> 
> super do {
>    foo();
>    while(cond);
>    bar();
> }
> 
> which in D is better modelled by:
> 
> for (;;)
> {
>    foo();
>    if (!cond) break;
>    bar();
> }

This isn't "super do", it's just "loop", the way nature intended. ;-)
I've always been an advocate of this construct:

	loop {
		// initial part of loop body
	} while(cond) {	// exit point
		// trailing part of loop body
	}

To some extent, D (and C/C++)'s for-loops exhibit a similar structure:

	for (X; Y; Z) {}

The trailing part of the loop body corresponds with Z; the condition
corresponds with Y.

To avoid the introduction of a new keyword, we may fuse the do-loop and
the while-loop together:

	do {
		...
	} while (cond) {
		...
	}

The current do-loop is simply a special case of this construct where the
second {...} is replaced with a ;, and the while-loop is a special case
of this construct where the initial part of the loop is elided.

I argue that this generalized construct is much more useful than the
do-loop or while-loop individually, plus it doesn't break any existing
code.


T

-- 
Без труда не выловишь и рыбку из пруда.
October 05, 2012
Re: Feature request: extending comma operator's functionality
On Friday, 5 October 2012 at 00:39:40 UTC, timotheecour wrote:
> Is the plan to deprecate comma operator for chaining 
> expressions?
> I would love to see more syntactic sugar to support tuples, and 
> comma operator would be the best fit for that purpose.
>
> eg:
> ----
> import std.typecons;
> auto fun(){
>     return tuple(1,"abc");
>     //1) ideally, we should be able to write:
>     //return (1,"abc");
>     //with same semantics (and no need to import std.typecons)
> }
>
> //at the call site: currently:
> auto t=fun();
> auto a=t[0];
> auto b=t[1];
>
> //2) ideally, we should be able to write:
> auto (a,b,c)=fun();
>
> //3) or even:
> (a,b,c)=fun();
> ----
>
> Will it be difficult to implement 2)? (by far the most 
> important of 1,2,3)
> Is 1) and 3) a good idea?

Surely the ideal is what you're written but also allowing the 
omission of parens where it's unambiguous? Just to keep this idea 
in people's minds:

return 1, "abc";

That would seem like the ideal to me as would:

double, string fun(double, double n) {
    return n[0] * n[1], "abc";
}

Should these uses require parens like this?

(double, string) fun((double, double) n) {
    return (n[0] * n[1], "abc");
}

As discussed before the parens are unavoidable for assignment 
given the need to avoid breaking vast quantities of code.
October 07, 2012
Re: Feature request: extending comma operator's functionality
On Friday, 5 October 2012 at 13:47:00 UTC, monarch_dodra wrote:
> On Friday, 5 October 2012 at 00:22:04 UTC, Jonathan M Davis 
> wrote:
>> On Friday, October 05, 2012 02:08:14 bearophile wrote:
>>> [SNIP]
>>> Regarding definition of variables in D language constructs, 
>>> there
>>> is one situation where sometimes I find D not handy. This code
>>> can't work:
>>> 
>>> do {
>>> const x = ...;
>>> } while (predicate(x));
>>> 
>>> 
>>> You need to use:
>>>
>>> T x;
>>> do {
>>> x = ...;
>>> } while (predicate(x));
>>
>> Yeah. That comes from C/C++ (and is the same in Java and C#, I 
>> believe). I
>> don't know why it works that way. It's definitely annoying.
>> 
>> [SNIP]
>>
>> - Jonathan M Davis
>
> Because it's the only way to guarantee that x exits when you 
> reach the end of the loop.
>
> do {
>   if(true) continue; //Yawn... skip.
>   const x = ... ;
> } while (predicate(x)); //What's x?
>
> Basic goto limitations. Unlike goto though, inserting a 
> "continue" should never create a compile error, so the compiler 
> *has* to guarantee that the if condition references nothing 
> inside its own block.
>
> It is annoying, but nothing that can't be fixed with a scope 
> bloc.

There is a simple way around this... which addresses both 
concerns raised...
1. Semantics of old code is unchanged.
2. no issue with 'continue'

do(const x = ...)
{
}
while(predicate(x));
October 07, 2012
Re: Feature request: extending comma operator's functionality
On 10/05/2012 03:35 PM, monarch_dodra wrote:
> On Friday, 5 October 2012 at 00:22:04 UTC, Jonathan M Davis wrote:
>> On Friday, October 05, 2012 02:08:14 bearophile wrote:
>>> [SNIP]
>>> Regarding definition of variables in D language constructs, there
>>> is one situation where sometimes I find D not handy. This code
>>> can't work:
>>>
>>> do {
>>> const x = ...;
>>> } while (predicate(x));
>>>
>>>
>>> You need to use:
>>>
>>> T x;
>>> do {
>>> x = ...;
>>> } while (predicate(x));
>>
>> Yeah. That comes from C/C++ (and is the same in Java and C#, I
>> believe). I
>> don't know why it works that way. It's definitely annoying.
>>
>> [SNIP]
>>
>> - Jonathan M Davis
>
> Because it's the only way to guarantee that x exits when you reach the
> end of the loop.
>


s/only/simplest/

> do {
>    if(true) continue; //Yawn... skip.
>    const x = ... ;
> } while (predicate(x)); //What's x?
>
> Basic goto limitations. Unlike goto though, inserting a "continue"
> should never create a compile error, so the compiler *has* to guarantee
> that the if condition references nothing inside its own block.
>
> It is annoying, but nothing that can't be fixed with a scope bloc.
October 08, 2012
Re: Feature request: extending comma operator's functionality
On 05/10/12 18:58, H. S. Teoh wrote:
> On Fri, Oct 05, 2012 at 05:23:40PM +0200, Don Clugston wrote:
> [...]
>> My feeling is that  do{}while() is a fairly useless concept, and
>> this is part of the reason.
>> In my experience genuine do-while loops are extremely rare, and it
>> only takes a slight change to the loop to force a different
>> structure to be used.
>> Conditional loops which don't follow the while(){...} pattern
>> normally follow the loop-and-a-half pattern, also known as
>> begin-while-repeat (I think that's the name Knuth used). I'll call
>> it 'super do':
>>
>> super do {
>>     foo();
>>     while(cond);
>>     bar();
>> }
>>
>> which in D is better modelled by:
>>
>> for (;;)
>> {
>>     foo();
>>     if (!cond) break;
>>     bar();
>> }
>
> This isn't "super do", it's just "loop", the way nature intended. ;-)
> I've always been an advocate of this construct:
>
> 	loop {
> 		// initial part of loop body
> 	} while(cond) {	// exit point
> 		// trailing part of loop body
> 	}
>

Looks OK, except that the scopes look wrong. I would hope than a 
variable declared in the initial part of the body is also visible in the 
trailing part. The {} don't work properly.
Regardless of the syntax, I think it is _the_ fundamental loop 
construct, and I've always found it odd that most languages don't 
include it. I first found encountered it in Forth, and have missed it 
ever since.

> To some extent, D (and C/C++)'s for-loops exhibit a similar structure:
>
> 	for (X; Y; Z) {}
>
> The trailing part of the loop body corresponds with Z; the condition
> corresponds with Y.

Yes. C got 'for' loops right.

> To avoid the introduction of a new keyword, we may fuse the do-loop and
> the while-loop together:
>
> 	do {
> 		...
> 	} while (cond) {
> 		...
> 	}
>
> The current do-loop is simply a special case of this construct where the
> second {...} is replaced with a ;, and the while-loop is a special case
> of this construct where the initial part of the loop is elided.
>
> I argue that this generalized construct is much more useful than the
> do-loop or while-loop individually, plus it doesn't break any existing
> code.

I agree that it's more useful. But that code was legal until a couple of 
releases ago, because a trailing ; was not required on do-while loops.

do { xxx; } while(cond) { yyy; }

means:
do {
  xxx;
}
while(cond);
yyy;

Even without that, it puts a huge significance on that semicolon. So I 
don't think that works. How about:

do {  ...  do while (cond);  ... }

?
This is technically already legal too, although 'do while(cond);' is 
currently either a no-op, or an infinite loop.
Next ›   Last »
1 2 3
Top | Discussion index | About this forum | D home