Re: Comma operator = broken design

2011-12-12 Thread Regan Heath

On Fri, 09 Dec 2011 15:39:09 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 04:37 PM, Regan Heath wrote:
On Fri, 09 Dec 2011 14:54:16 -, Timon Gehr timon.g...@gmx.ch  
wrote:

What you might be missing is that assert(false) is not compiled out in
release mode. It emits a 'hlt' instruction which kills your program.
However, your assert(c = 0x10); will be removed in release mode.


I was indeed missing that. I couldn't find anything about it on the
website. :)

R



http://d-programming-language.org/expression.html#AssertExpression


I found that :p  .. but nothing about behaviour in release/debug/etc.

R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Comma operator = broken design

2011-12-12 Thread bearophile
Regan Heath:

  http://d-programming-language.org/expression.html#AssertExpression
 
 I found that :p  .. but nothing about behaviour in release/debug/etc.

It's a known little wart of D2. We discussed about it some time ago. I have 
asked for a specific and clean way to do it, but D designers have said it's not 
a big enough wart to deserve an improvement. And as I have predicted, it comes 
around to bite people in the butt. This is the opposite of perfectionism...

Bye,
bearophile


Re: Comma operator = broken design

2011-12-11 Thread Alex Rønne Petersen

On 10-12-2011 02:39, Jonathan M Davis wrote:

On Friday, December 09, 2011 20:18:36 Robert Jacques wrote:

On Fri, 09 Dec 2011 01:20:45 -0500, Kagamins...@here.lot  wrote:

On Thursday, 8 December 2011 at 17:18:57 UTC, Joshua Reusch wrote:

Ahem. So are you suggesting that (a,b) means a tuple
everywhere but in a
for loop, where it is used to separate two statements?


If we use the comma operator only for tuples, there needn't to
be a special case for loops:

for(x, y = 0 , 100; x  y ; x, y += 1,-1) { ... }


for(int x, y = 0 , 100; x  y ; x, y += 1,-1) { ... }

?


Here's how I understood it:

int x,y; // Defined somewhere in the code above

for( (x,y) = (0,100); x  y ; (x,y) += (1,-1) ) { ... }

So you have variable capture, assignment and add-assign happening.


I'd _hate_ to be restricted to doing the same operation in the 3rd portion of
a for loop for all of its parts. The comma operator is _perfect_ for there,
and I wouldn't want to see its behavior changed there regardless. e.g. things
like this should continue to be perfectly possible and legal

for(; cond; ++x, y *= 2) {}

Tuples do _not_ have the proper semantics for a for loop. It would be one
thing for the comma operator were to go away in the general case, but it would
be horrible IMHO for its behavior to be changed in for loops - be it in an
effort to make it act like it's using tuples or any other reason.

- Jonathan M Davis


Indeed, having the comma operator in for loops is perfectly normal; even 
C# has this.


- Alex


Re: Comma operator = broken design

2011-12-11 Thread Robert Jacques

On Sun, 11 Dec 2011 06:21:51 -0500, Alex Rønne Petersen xtzgzo...@gmail.com 
wrote:


On 10-12-2011 02:39, Jonathan M Davis wrote:

On Friday, December 09, 2011 20:18:36 Robert Jacques wrote:

On Fri, 09 Dec 2011 01:20:45 -0500, Kagamins...@here.lot  wrote:

On Thursday, 8 December 2011 at 17:18:57 UTC, Joshua Reusch wrote:

Ahem. So are you suggesting that (a,b) means a tuple
everywhere but in a
for loop, where it is used to separate two statements?


If we use the comma operator only for tuples, there needn't to
be a special case for loops:

for(x, y = 0 , 100; x  y ; x, y += 1,-1) { ... }


for(int x, y = 0 , 100; x  y ; x, y += 1,-1) { ... }

?


Here's how I understood it:

int x,y; // Defined somewhere in the code above

for( (x,y) = (0,100); x  y ; (x,y) += (1,-1) ) { ... }

So you have variable capture, assignment and add-assign happening.


I'd _hate_ to be restricted to doing the same operation in the 3rd portion of
a for loop for all of its parts. The comma operator is _perfect_ for there,
and I wouldn't want to see its behavior changed there regardless. e.g. things
like this should continue to be perfectly possible and legal

for(; cond; ++x, y *= 2) {}

Tuples do _not_ have the proper semantics for a for loop. It would be one
thing for the comma operator were to go away in the general case, but it would
be horrible IMHO for its behavior to be changed in for loops - be it in an
effort to make it act like it's using tuples or any other reason.

- Jonathan M Davis


Indeed, having the comma operator in for loops is perfectly normal; even
C# has this.

- Alex



A lot (all?) of for loop use cases seem to actually work in tuple form. For 
instance,

for(; cond; tuple(++x, y *= 2) ) {}

Will behave as expected, although there might be a performance issue.


Re: Comma operator = broken design

2011-12-11 Thread Jonathan M Davis
On Sunday, December 11, 2011 20:19:11 Robert Jacques wrote:
 A lot (all?) of for loop use cases seem to actually work in tuple form. For
 instance,
 
 for(; cond; tuple(++x, y *= 2) ) {}
 
 Will behave as expected, although there might be a performance issue.

What if one of the expression's result is void?

All in all, I think that it's ludicrous to consider changing the semantics of 
for loops to use a tuple instead of the comma operator. It's one thing to 
consider eliminating the comma operator outside of for loops. It's yet another 
to consider adding built-in templates beyond that, and it's going _way_ too 
far to change the semantics of the for loop as part of that IMHO.

for loops should be left exactly as they are, regardless of what happens with 
the comma operator outside of for loops.

- Jonathan M Davis


Re: Comma operator = broken design

2011-12-09 Thread Don

On 08.12.2011 20:22, Timon Gehr wrote:

On 12/08/2011 05:02 PM, Regan Heath wrote:

On Thu, 08 Dec 2011 12:17:20 -, so s...@so.so wrote:


On Thu, 08 Dec 2011 11:17:48 +0200, Dejan Lekic
dejan.le...@gmail.com wrote:





Why is this operator still kept around?


No offense, but I find it strange/funny that you even ask why! :)

Have you never used comma in for loops???



Not sure if it is that relevant for D, but good point.

for(auto i=beg(), e=end(); i!=e; ++i)
for(auto i, j, k;; ++i, ++k)
...


It's kinda amusing that this thread appeared just as we had a case of
this here at work. The developer accidentally coded something like...

if (function(..), FALSE)
{
}

Accidentally adding the , FALSE /after/ the ) instead of as a new
parameter to the function.

(note; This was in C++ with default parameter values so the function can
in fact take 1-4 args).

When I pointed this out, he said how does that even compile and was
completely unaware of the existence of the comma operator, nor (once I
explained it) did he realise it was in any way related to the comma used
in for loops. People simply don't think of them as being the same thing
at all. Instead, people learn the comma syntax as a special
characteristic of the for loop, and use it nowhere else.

I think the comma operator is of little benefit (except where used in a
for loop) and it is a source of bugs and we'd be better off without it.
Even if it means porting C/C++ requires modification, or existing D (I
doubt very much of it) breaks.



Phobos would break, for example. And some of my code too.


Are there any cases where you're using comma outside of for loops?
I wonder how much would break if were made illegal everywhere else.


Re: Comma operator = broken design

2011-12-09 Thread Jonathan M Davis
On Friday, December 09, 2011 10:19:18 Don wrote:
 Are there any cases where you're using comma outside of for loops?
 I wonder how much would break if were made illegal everywhere else.

I'm sure that it would break code, but most people consider it bad practice to 
use the comma operator for much outside of for loops. Occasionally, it's 
useful to use one in an expression, but on the whole, it's just confusing and 
error-prone. And while it might break code to make the comma operator illegal 
outside of for loops, I would expect that fixing the broken code would 
generally be rather trivial. The resulting code may not be as compact, but it 
wouldn't be hard to write. And unless you're dealing with a programmer who 
uses it uncommonly often, not much code is going to break.

- Jonathan M Davis


Re: Comma operator = broken design

2011-12-09 Thread Timon Gehr

On 12/09/2011 10:19 AM, Don wrote:

On 08.12.2011 20:22, Timon Gehr wrote:

On 12/08/2011 05:02 PM, Regan Heath wrote:

On Thu, 08 Dec 2011 12:17:20 -, so s...@so.so wrote:


On Thu, 08 Dec 2011 11:17:48 +0200, Dejan Lekic
dejan.le...@gmail.com wrote:





Why is this operator still kept around?


No offense, but I find it strange/funny that you even ask why! :)

Have you never used comma in for loops???



Not sure if it is that relevant for D, but good point.

for(auto i=beg(), e=end(); i!=e; ++i)
for(auto i, j, k;; ++i, ++k)
...


It's kinda amusing that this thread appeared just as we had a case of
this here at work. The developer accidentally coded something like...

if (function(..), FALSE)
{
}

Accidentally adding the , FALSE /after/ the ) instead of as a new
parameter to the function.

(note; This was in C++ with default parameter values so the function can
in fact take 1-4 args).

When I pointed this out, he said how does that even compile and was
completely unaware of the existence of the comma operator, nor (once I
explained it) did he realise it was in any way related to the comma used
in for loops. People simply don't think of them as being the same thing
at all. Instead, people learn the comma syntax as a special
characteristic of the for loop, and use it nowhere else.

I think the comma operator is of little benefit (except where used in a
for loop) and it is a source of bugs and we'd be better off without it.
Even if it means porting C/C++ requires modification, or existing D (I
doubt very much of it) breaks.



Phobos would break, for example. And some of my code too.


Are there any cases where you're using comma outside of for loops?


Yes, one for every 65 LOC.


I wonder how much would break if were made illegal everywhere else.


These are the occurences of the comma operator in directory 'std':

return r2.empty ? (r1 = r, true) : false;
return binaryFun!pred(r.front, e) ? (r.popFront(), true) : false;

if (f.flPlus)
signChar = '+', ++minw;
else if (f.flSpace)
signChar = ' ', ++minw;

if (std.ascii.toLower(p.front) == 'n' 
   (p.popFront(), std.ascii.toLower(p.front) == 'f') 
   (p.popFront(), p.empty))

enforce((p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'A')
 (p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'N'),
   new ConvException(error converting input to floating point));

if (indexStart != 0)
formatValue(w, indexStart, f), put(w, '$');

if (c == '\' || c == '\\')
put(w, '\\'), put(w, c);
else
put(w, c);

return (++mi.m_cRefs, cast(HXModule)mi);
return (++mi.m_cRefs, hModule);

return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: (assert(false), 6);







Re: Comma operator = broken design

2011-12-09 Thread Timon Gehr

On 12/09/2011 10:26 AM, Jonathan M Davis wrote:

On Friday, December 09, 2011 10:19:18 Don wrote:

Are there any cases where you're using comma outside of for loops?
I wonder how much would break if were made illegal everywhere else.


I'm sure that it would break code, but most people consider it bad practice to
use the comma operator for much outside of for loops.


'most people'?


Occasionally, it's
useful to use one in an expression, but on the whole, it's just confusing and
error-prone.


It is confusing to people who don't know the language. It is a simple 
construct. In my experience, it is certainly not error prone. If you are 
aware that such an operator exists.



And while it might break code to make the comma operator illegal
outside of for loops, I would expect that fixing the broken code would
generally be rather trivial.


Sure.


The resulting code may not be as compact, but it
wouldn't be hard to write.


It would be a PITA in some cases.


And unless you're dealing with a programmer who
uses it uncommonly often, not much code is going to break.



I _am_ such a programmer.



Re: Comma operator = broken design

2011-12-09 Thread Regan Heath

On Fri, 09 Dec 2011 11:39:55 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 10:19 AM, Don wrote:

On 08.12.2011 20:22, Timon Gehr wrote:

Phobos would break, for example. And some of my code too.


Are there any cases where you're using comma outside of for loops?


Yes, one for every 65 LOC.


I wonder how much would break if were made illegal everywhere else.


These are the occurences of the comma operator in directory 'std':

return r2.empty ? (r1 = r, true) : false;
return binaryFun!pred(r.front, e) ? (r.popFront(), true) : false;

if (f.flPlus)
 signChar = '+', ++minw;
else if (f.flSpace)
 signChar = ' ', ++minw;

if (std.ascii.toLower(p.front) == 'n' 
(p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))

enforce((p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'A')
  (p.popFront(), !p.empty  std.ascii.toUpper(p.front) ==  
'N'),

new ConvException(error converting input to floating point));

if (indexStart != 0)
 formatValue(w, indexStart, f), put(w, '$');

if (c == '\' || c == '\\')
 put(w, '\\'), put(w, c);
else
 put(w, c);

return (++mi.m_cRefs, cast(HXModule)mi);
return (++mi.m_cRefs, hModule);

return
 c = 0x7F ? 1
 : c = 0x7FF ? 2
 : c = 0x ? 3
 : c = 0x10 ? 4
 : (assert(false), 6);


All of the above could be improved with the removal of the comma operator,  
IMO.  They are needlessly complicated/confusing with it.


R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Comma operator = broken design

2011-12-09 Thread bearophile
Timon Gehr:

 These are the occurences of the comma operator in directory 'std':
 
 return r2.empty ? (r1 = r, true) : false;
 return binaryFun!pred(r.front, e) ? (r.popFront(), true) : false;
 
 if (f.flPlus)
  signChar = '+', ++minw;
 else if (f.flSpace)
  signChar = ' ', ++minw;
 
 if (std.ascii.toLower(p.front) == 'n' 
 (p.popFront(), std.ascii.toLower(p.front) == 'f') 
 (p.popFront(), p.empty))
 
 enforce((p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'A')
   (p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'N'),
 new ConvException(error converting input to floating point));
 
 if (indexStart != 0)
  formatValue(w, indexStart, f), put(w, '$');
 
 if (c == '\' || c == '\\')
  put(w, '\\'), put(w, c);
 else
  put(w, c);
 
 return (++mi.m_cRefs, cast(HXModule)mi);
 return (++mi.m_cRefs, hModule);
 
 return
  c = 0x7F ? 1
  : c = 0x7FF ? 2
  : c = 0x ? 3
  : c = 0x10 ? 4
  : (assert(false), 6);

It's ugly code worth fixing/rewriting. If I see something like that in 
production code, I always burn it with fire and rewrite it.
Turning such usages of comma operator into syntax errors looks like a general 
improvement for D.

Bye,
bearophile


Re: Comma operator = broken design

2011-12-09 Thread Regan Heath

On Fri, 09 Dec 2011 12:00:57 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 10:26 AM, Jonathan M Davis wrote:

On Friday, December 09, 2011 10:19:18 Don wrote:

Are there any cases where you're using comma outside of for loops?
I wonder how much would break if were made illegal everywhere else.


I'm sure that it would break code, but most people consider it bad  
practice to

use the comma operator for much outside of for loops.


'most people'?


Yes, I would guess that you're in the minority here.


Occasionally, it's
useful to use one in an expression, but on the whole, it's just  
confusing and

error-prone.


It is confusing to people who don't know the language. It is a simple  
construct. In my experience, it is certainly not error prone. If you are  
aware that such an operator exists.


It's error prone in cases where you use it without realising, as in the  
example I posted.



The resulting code may not be as compact, but it
wouldn't be hard to write.


It would be a PITA in some cases.


Really?  Give us an example where not having comma makes things  
significantly difficult.



And unless you're dealing with a programmer who
uses it uncommonly often, not much code is going to break.


I _am_ such a programmer.


So it seems :)  I don't want to make your life harder but I think this  
change would make life easier for a large number of people, a small amount  
of the time.  The equation is unbalanced in favour of it's removal, IMO.


--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Comma operator = broken design

2011-12-09 Thread Regan Heath

On Fri, 09 Dec 2011 11:39:55 -, Timon Gehr timon.g...@gmx.ch wrote:

These are the occurences of the comma operator in directory 'std':


Here is my /very/ quick re-write of each without looking at the context of  
each snippet.  There may be much better re-writes in context.  Re-writing  
this was problematic /because/ the comma operator makes things that much  
more confusing to me.  Especially example #5 below where the last ,  
actually separates enforce parameters!


1)


return r2.empty ? (r1 = r, true) : false;


if (!r2.empty) return false;
r1 = r;
return true;


2)


return binaryFun!pred(r.front, e) ? (r.popFront(), true) : false;


if (!binaryFun!pred(r.front, e)) return false;  
r.popFront();
return true;


3)


if (f.flPlus)
 signChar = '+', ++minw;
else if (f.flSpace)
 signChar = ' ', ++minw;


This is purely {}; avoidance it seems..

if (f.flPlus)
{
  signChar = '+';
  ++minw;
}
else if (f.flSpace)
{
  signChar = ' ';
  ++minw;
}


4)


if (std.ascii.toLower(p.front) == 'n' 
(p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))


'if' statements with side effects are yuck.  I prefer the check for error  
and bail style but you could use multiple layers of 'if' instead..


if (std.ascii.toLower(p.front) != 'n') //error handling
p.popFront();
if (std.ascii.toLower(p.front) != 'f') //error handling
p.popFront();
if (!p.empty) //error handling


5)


enforce((p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'A')
  (p.popFront(), !p.empty  std.ascii.toUpper(p.front) ==   
'N'),

new ConvException(error converting input to floating point));


This is blatant enforce abuse IMO..

p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'A'))
  throw new ConvException(error converting input to floating point));
p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'N'))
  throw new ConvException(error converting input to floating point));


6)


if (indexStart != 0)
 formatValue(w, indexStart, f), put(w, '$');


More {}; avoidance..

if (indexStart != 0)
{
formatValue(w, indexStart, f);
put(w, '$');
}


7)


if (c == '\' || c == '\\')
 put(w, '\\'), put(w, c);
else
 put(w, c);


More {}; avoidance..

if (c == '\' || c == '\\')
{
  put(w, '\\');
  put(w, c);
}
else
{
  put(w, c);
}


8)


return (++mi.m_cRefs, cast(HXModule)mi);


less (), one more ; and enter..

++mi.m_cRefs;
return cast(HXModule)mi;


9)


return (++mi.m_cRefs, hModule);


as above..

++mi.m_cRefs;
return hModule;


10)


return
 c = 0x7F ? 1
 : c = 0x7FF ? 2
 : c = 0x ? 3
 : c = 0x10 ? 4
 : (assert(false), 6);


*Much* clearer with the rewrite..

assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: 6;

None of the above look significantly harder without the comma operator and  
quite a few are far clearer (to me) without it.


R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Comma operator = broken design

2011-12-09 Thread Timon Gehr

On 12/09/2011 01:11 PM, Regan Heath wrote:

On Fri, 09 Dec 2011 12:00:57 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 10:26 AM, Jonathan M Davis wrote:

On Friday, December 09, 2011 10:19:18 Don wrote:

Are there any cases where you're using comma outside of for loops?
I wonder how much would break if were made illegal everywhere else.


I'm sure that it would break code, but most people consider it bad
practice to
use the comma operator for much outside of for loops.


'most people'?


Yes, I would guess that you're in the minority here.



'most people' do not care about this discussion, so lets stop it. :o)

What I wanted to say is just that throwing in 'most people' does not 
help an argument, because a) there is no evidence and b) 'most people' 
are in general just as often (or even more) wrong than 'a few people'.



Occasionally, it's
useful to use one in an expression, but on the whole, it's just
confusing and
error-prone.


It is confusing to people who don't know the language. It is a simple
construct. In my experience, it is certainly not error prone. If you
are aware that such an operator exists.


It's error prone in cases where you use it without realising, as in the
example I posted.



That is true for every language construct.


The resulting code may not be as compact, but it
wouldn't be hard to write.


It would be a PITA in some cases.


Really? Give us an example where not having comma makes things
significantly difficult.


I already agreed that rewriting the code is trivial. It is just that I 
usually do not want to spend lots of my time on trivial stuff.





And unless you're dealing with a programmer who
uses it uncommonly often, not much code is going to break.


I _am_ such a programmer.


So it seems :)


If you carefully read my posts you will find that I did never say that I 
am against removing the comma operator.


I would like comma to have tuple semantics. Comma should keep
its precedence level and then work like this:

if(foo) bar, baz, qux; // the value of the tuple is unused, so no change 
in semantics


if(bar()||(foo(), *++p==(*++x)++)[1]){} // the value is used, so an 
explicit index is necessary


It would make the language more consistent because the comma in 
expressions would be the same comma as the one that is used elsewhere.


That is against the C compatibility rule though, and it would in some 
cases silently break code.



I don't want to make your life harder but I think this
change would make life easier for a large number of people, a small
amount of the time. The equation is unbalanced in favour of it's
removal, IMO.



This part of your post is somewhat contradictory.




Re: Comma operator = broken design

2011-12-09 Thread Timon Gehr

On 12/09/2011 01:36 PM, Regan Heath wrote:

4)


if (std.ascii.toLower(p.front) == 'n' 
(p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))


'if' statements with side effects are yuck. I prefer the check for error
and bail style but you could use multiple layers of 'if' instead..

if (std.ascii.toLower(p.front) != 'n') //error handling
p.popFront();
if (std.ascii.toLower(p.front) != 'f') //error handling
p.popFront();
if (!p.empty) //error handling



Your '//error handling' shortcut hides relevant information.



5)


enforce((p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'A')
 (p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'N'),
new ConvException(error converting input to floating point));


This is blatant enforce abuse IMO..

p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'A'))
throw new ConvException(error converting input to floating point));
p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'N'))
throw new ConvException(error converting input to floating point));



This is blatant code duplication.



7)


if (c == '\' || c == '\\')
put(w, '\\'), put(w, c);
else
put(w, c);


More {}; avoidance..

if (c == '\' || c == '\\')
{
put(w, '\\');
put(w, c);
}
else
{
put(w, c);
}



No comma operator necessary to avoid {}:

if(x == '' || c == '\\') put(w, '\\');
put(w, c);




8)


return (++mi.m_cRefs, cast(HXModule)mi);


less (), one more ; and enter..

++mi.m_cRefs;
return cast(HXModule)mi;



() would not be necessary.



9)


return (++mi.m_cRefs, hModule);


as above..

++mi.m_cRefs;
return hModule;


10)


return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: (assert(false), 6);


*Much* clearer with the rewrite..

assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: 6;



This is a *much* better rewrite:
assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: 4;



None of the above look significantly harder without the comma operator
and quite a few are far clearer (to me) without it.



Yah, many of those occurences in Phobos are mostly unnecessary.











Re: Comma operator = broken design

2011-12-09 Thread Piotr Szturmaj

Regan Heath wrote:

On Fri, 09 Dec 2011 12:00:57 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 10:26 AM, Jonathan M Davis wrote:

And unless you're dealing with a programmer who
uses it uncommonly often, not much code is going to break.


I _am_ such a programmer.


So it seems :) I don't want to make your life harder but I think this
change would make life easier for a large number of people [...]


What about just not using comma operator? Yes, I know about keyboard 
issue. There are many cases when 'typoed' code compiles but doesn't work 
as programmer would expect. This is not limited to comma op.


Some programmers do not like gotos, comma operator or other language 
constructs. Some like the opposites. I would suggest making a patch to 
the compiler to introduce a new pragma:


pragma(disable, commaOp);

and programmers will be able to place it in every source file they want to.


Re: Comma operator = broken design

2011-12-09 Thread Timon Gehr

On 12/09/2011 01:56 PM, Derek wrote:

On Fri, 09 Dec 2011 22:39:55 +1100, Timon Gehr timon.g...@gmx.ch wrote:


These are the occurences of the comma operator in directory 'std': ...


OMG! What ever happened to the idea that source code is meant to AID
reading programs and not making it obscured.

These are examples for a 'shame' file, or how not to write useful code.




You are exaggerating.

http://www.ioccc.org/


Re: Comma operator = broken design

2011-12-09 Thread Regan Heath

On Fri, 09 Dec 2011 13:15:47 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 01:36 PM, Regan Heath wrote:

4)


if (std.ascii.toLower(p.front) == 'n' 
(p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))


'if' statements with side effects are yuck. I prefer the check for error
and bail style but you could use multiple layers of 'if' instead..

if (std.ascii.toLower(p.front) != 'n') //error handling
p.popFront();
if (std.ascii.toLower(p.front) != 'f') //error handling
p.popFront();
if (!p.empty) //error handling



Your '//error handling' shortcut hides relevant information.


What information?  With context I could be more specific about what to do  
for each/all.



5)


enforce((p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'A')
 (p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'N'),
new ConvException(error converting input to floating point));


This is blatant enforce abuse IMO..

p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'A'))
throw new ConvException(error converting input to floating point));
p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'N'))
throw new ConvException(error converting input to floating point));



This is blatant code duplication.


Of the throw line?  Sure, and you can re-write with nested 'if' if you  
prefer.  I prefer the code duplication tho.



7)


if (c == '\' || c == '\\')
put(w, '\\'), put(w, c);
else
put(w, c);


More {}; avoidance..

if (c == '\' || c == '\\')
{
put(w, '\\');
put(w, c);
}
else
{
put(w, c);
}



No comma operator necessary to avoid {}:

if(x == '' || c == '\\') put(w, '\\');
put(w, c);


Yeah, it was a /quick/ re-write without additional re-factoring (aside  
from removal of the comma).



8)


return (++mi.m_cRefs, cast(HXModule)mi);


less (), one more ; and enter..

++mi.m_cRefs;
return cast(HXModule)mi;



() would not be necessary.


True, but if you're going to use the comma operator, enclosing it in () at  
makes it more obvious you've done so.  I tend to use extra () when using  
the ?: operator for this reason.



9)


return (++mi.m_cRefs, hModule);


as above..

++mi.m_cRefs;
return hModule;


10)


return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: (assert(false), 6);


*Much* clearer with the rewrite..

assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: 6;



This is a *much* better rewrite:
assert(c = 0x10);
return
 c = 0x7F ? 1
 : c = 0x7FF ? 2
 : c = 0x ? 3
 : 4;


Again, I was missing context.. is the return value of 6 not required in  
release mode?



None of the above look significantly harder without the comma operator
and quite a few are far clearer (to me) without it.



Yah, many of those occurences in Phobos are mostly unnecessary.


:)

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Comma operator = broken design

2011-12-09 Thread Regan Heath
On Fri, 09 Dec 2011 13:15:22 -, Piotr Szturmaj bncr...@jadamspam.pl  
wrote:



Regan Heath wrote:
On Fri, 09 Dec 2011 12:00:57 -, Timon Gehr timon.g...@gmx.ch  
wrote:

On 12/09/2011 10:26 AM, Jonathan M Davis wrote:

And unless you're dealing with a programmer who
uses it uncommonly often, not much code is going to break.


I _am_ such a programmer.


So it seems :) I don't want to make your life harder but I think this
change would make life easier for a large number of people [...]


What about just not using comma operator? Yes, I know about keyboard  
issue. There are many cases when 'typoed' code compiles but doesn't work  
as programmer would expect. This is not limited to comma op.


True, but D has already turned a good number of those into errors.  This  
is another example where it could for very little cost, IMO.


R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Comma operator = broken design

2011-12-09 Thread Regan Heath

On Fri, 09 Dec 2011 13:01:12 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 01:11 PM, Regan Heath wrote:
On Fri, 09 Dec 2011 12:00:57 -, Timon Gehr timon.g...@gmx.ch  
wrote:

On 12/09/2011 10:26 AM, Jonathan M Davis wrote:

On Friday, December 09, 2011 10:19:18 Don wrote:

Are there any cases where you're using comma outside of for loops?
I wonder how much would break if were made illegal everywhere else.


I'm sure that it would break code, but most people consider it bad
practice to
use the comma operator for much outside of for loops.


'most people'?


Yes, I would guess that you're in the minority here.



'most people' do not care about this discussion, so lets stop it. :o)


Sure.


So it seems :)


If you carefully read my posts you will find that I did never say that I  
am against removing the comma operator.


Excellent.


I don't want to make your life harder but I think this
change would make life easier for a large number of people, a small
amount of the time. The equation is unbalanced in favour of it's
removal, IMO.



This part of your post is somewhat contradictory.


How so?

R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Comma operator = broken design

2011-12-09 Thread Tobias Pankrath
Timon Gehr wrote:

 It is confusing to people who don't know the language. It is a simple
 construct. In my experience, it is certainly not error prone. If you are
 aware that such an operator exists.

It may not be error prone to write, but it is error prone to read, because
the comma-operator tends to hide in the language noise produced by all those
brackets, semicolons, commas, parenthesis and curly braces.

I don't like it, if I have to be uber careful when reading trivial code.


Re: Comma operator = broken design

2011-12-09 Thread Timon Gehr

On 12/09/2011 02:28 PM, Regan Heath wrote:

On Fri, 09 Dec 2011 13:15:47 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 01:36 PM, Regan Heath wrote:

4)


if (std.ascii.toLower(p.front) == 'n' 
(p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))


'if' statements with side effects are yuck. I prefer the check for error
and bail style but you could use multiple layers of 'if' instead..

if (std.ascii.toLower(p.front) != 'n') //error handling
p.popFront();
if (std.ascii.toLower(p.front) != 'f') //error handling
p.popFront();
if (!p.empty) //error handling



Your '//error handling' shortcut hides relevant information.


What information? With context I could be more specific about what to do
for each/all.


You can always grep the Phobos source to get context. Basically, you are 
suggesting to replace the comma operator with gotos:


case 'i': case 'I':
p.popFront();
if (std.ascii.toLower(p.front) == 'n' 
(p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))
{
// 'inf'
return sign ? -Target.infinity : Target.infinity;
}
goto default;
default: {}
}





5)


enforce((p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'A')
 (p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'N'),
new ConvException(error converting input to floating point));


This is blatant enforce abuse IMO..

p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'A'))
throw new ConvException(error converting input to floating point));
p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'N'))
throw new ConvException(error converting input to floating point));



This is blatant code duplication.


Of the throw line? Sure, and you can re-write with nested 'if' if you
prefer. I prefer the code duplication tho.



Code duplication is very error prone. Furthermore I never ever want to 
duplicate _error handling_ code. That just clutters up the generated 
machine code if the compiler does not manage to reverse engineer and 
generate the proper solution.



7)


if (c == '\' || c == '\\')
put(w, '\\'), put(w, c);
else
put(w, c);


More {}; avoidance..

if (c == '\' || c == '\\')
{
put(w, '\\');
put(w, c);
}
else
{
put(w, c);
}



No comma operator necessary to avoid {}:

if(x == '' || c == '\\') put(w, '\\');
put(w, c);


Yeah, it was a /quick/ re-write without additional re-factoring (aside
from removal of the comma).


8)


return (++mi.m_cRefs, cast(HXModule)mi);


less (), one more ; and enter..

++mi.m_cRefs;
return cast(HXModule)mi;



() would not be necessary.


True, but if you're going to use the comma operator, enclosing it in ()
at makes it more obvious you've done so. I tend to use extra () when
using the ?: operator for this reason.



You sort of made it look like the comma operator solution was more 
verbose. ;)



9)


return (++mi.m_cRefs, hModule);


as above..

++mi.m_cRefs;
return hModule;


10)


return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: (assert(false), 6);


*Much* clearer with the rewrite..

assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: 6;



This is a *much* better rewrite:
assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: 4;


Again, I was missing context.. is the return value of 6 not required in
release mode?


I was joking here. Your 'rewrite' of the original example changed its
release mode semantics, therefore I did the same thing.





None of the above look significantly harder without the comma operator
and quite a few are far clearer (to me) without it.



Yah, many of those occurences in Phobos are mostly unnecessary.


:)





Re: Comma operator = broken design

2011-12-09 Thread Timon Gehr

On 12/09/2011 02:33 PM, Regan Heath wrote:

On Fri, 09 Dec 2011 13:01:12 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 01:11 PM, Regan Heath wrote:

On Fri, 09 Dec 2011 12:00:57 -, Timon Gehr timon.g...@gmx.ch
wrote:

On 12/09/2011 10:26 AM, Jonathan M Davis wrote:

On Friday, December 09, 2011 10:19:18 Don wrote:

Are there any cases where you're using comma outside of for loops?
I wonder how much would break if were made illegal everywhere else.


I'm sure that it would break code, but most people consider it bad
practice to
use the comma operator for much outside of for loops.


'most people'?


Yes, I would guess that you're in the minority here.



'most people' do not care about this discussion, so lets stop it. :o)


Sure.


So it seems :)


If you carefully read my posts you will find that I did never say that
I am against removing the comma operator.


Excellent.


I don't want to make your life harder but I think this
change would make life easier for a large number of people, a small
amount of the time. The equation is unbalanced in favour of it's
removal, IMO.



This part of your post is somewhat contradictory.


How so?

R



Removing the comma operator makes my life harder. You don't want to do 
so. You want to remove the comma operator. Conclusion: Today is Monday.






Re: Comma operator = broken design

2011-12-09 Thread Timon Gehr

On 12/09/2011 02:38 PM, Tobias Pankrath wrote:

Timon Gehr wrote:


It is confusing to people who don't know the language. It is a simple
construct. In my experience, it is certainly not error prone. If you are
aware that such an operator exists.


It may not be error prone to write, but it is error prone to read, because
the comma-operator tends to hide in the language noise produced by all those
brackets, semicolons, commas, parenthesis and curly braces.

I don't like it, if I have to be uber careful when reading trivial code.


You always have to be careful when reading code.
I prefer when there is not a lot to read (dense code).


Re: Comma operator = broken design

2011-12-09 Thread Regan Heath

On Fri, 09 Dec 2011 13:47:14 -, Timon Gehr timon.g...@gmx.ch wrote:

I don't want to make your life harder but I think this
change would make life easier for a large number of people, a small
amount of the time. The equation is unbalanced in favour of it's
removal, IMO.



This part of your post is somewhat contradictory.


How so?

R



Removing the comma operator makes my life harder. You don't want to do  
so. You want to remove the comma operator. Conclusion: Today is Monday.


:p

1. I don't want to make your life harder, but (despite that)
2. I do want to remove the comma operator

Nothing contradictory there at all, simply cost/benefit.

R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Comma operator = broken design

2011-12-09 Thread Regan Heath

On Fri, 09 Dec 2011 13:42:34 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 02:28 PM, Regan Heath wrote:
On Fri, 09 Dec 2011 13:15:47 -, Timon Gehr timon.g...@gmx.ch  
wrote:

On 12/09/2011 01:36 PM, Regan Heath wrote:

4)


if (std.ascii.toLower(p.front) == 'n' 
(p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))


'if' statements with side effects are yuck. I prefer the check for  
error

and bail style but you could use multiple layers of 'if' instead..

if (std.ascii.toLower(p.front) != 'n') //error handling
p.popFront();
if (std.ascii.toLower(p.front) != 'f') //error handling
p.popFront();
if (!p.empty) //error handling



Your '//error handling' shortcut hides relevant information.


What information? With context I could be more specific about what to do
for each/all.


You can always grep the Phobos source to get context. Basically, you are  
suggesting to replace the comma operator with gotos:


 case 'i': case 'I':
 p.popFront();
 if (std.ascii.toLower(p.front) == 'n' 
 (p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))
 {
 // 'inf'
 return sign ? -Target.infinity : Target.infinity;
 }
 goto default;
 default: {}
 }


If using 'goto' is the 'correct' agreed upon style for phobos then, yes.   
It's not my personal preference however and I'd probably refactor it  
further if it was my own code.



5)


enforce((p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'A')
 (p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'N'),
new ConvException(error converting input to floating point));


This is blatant enforce abuse IMO..

p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'A'))
throw new ConvException(error converting input to floating point));
p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'N'))
throw new ConvException(error converting input to floating point));



This is blatant code duplication.


Of the throw line? Sure, and you can re-write with nested 'if' if you
prefer. I prefer the code duplication tho.



Code duplication is very error prone. Furthermore I never ever want to  
duplicate _error handling_ code. That just clutters up the generated  
machine code if the compiler does not manage to reverse engineer and  
generate the proper solution.


I can't comment on the machine code aspect.  I don't find this particular  
duplication error prone, but if you do you can use the nested if that I've  
already mentioned.



10)


return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: (assert(false), 6);


*Much* clearer with the rewrite..

assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: 6;



This is a *much* better rewrite:
assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: 4;


Again, I was missing context.. is the return value of 6 not required in
release mode?


I was joking here. Your 'rewrite' of the original example changed its
release mode semantics, therefore I did the same thing.


My version performs the assert in all cases, throws an assert error in the  
same/error cases, and still returns the correct/original values.  The only  
change is performing the assert in all cases, so I don't see how that is a  
problem.  Yours however is entirely broken (assuming the return value of 6  
is desired/required).


R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Comma operator = broken design

2011-12-09 Thread Timon Gehr

On 12/09/2011 03:25 PM, Regan Heath wrote:

On Fri, 09 Dec 2011 13:42:34 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 02:28 PM, Regan Heath wrote:

On Fri, 09 Dec 2011 13:15:47 -, Timon Gehr timon.g...@gmx.ch
wrote:

On 12/09/2011 01:36 PM, Regan Heath wrote:

4)


if (std.ascii.toLower(p.front) == 'n' 
(p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))


'if' statements with side effects are yuck. I prefer the check for
error
and bail style but you could use multiple layers of 'if' instead..

if (std.ascii.toLower(p.front) != 'n') //error handling
p.popFront();
if (std.ascii.toLower(p.front) != 'f') //error handling
p.popFront();
if (!p.empty) //error handling



Your '//error handling' shortcut hides relevant information.


What information? With context I could be more specific about what to do
for each/all.


You can always grep the Phobos source to get context. Basically, you
are suggesting to replace the comma operator with gotos:

case 'i': case 'I':
p.popFront();
if (std.ascii.toLower(p.front) == 'n' 
(p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))
{
// 'inf'
return sign ? -Target.infinity : Target.infinity;
}
goto default;
default: {}
}


If using 'goto' is the 'correct' agreed upon style for phobos then, yes.
It's not my personal preference however and I'd probably refactor it
further if it was my own code.


5)


enforce((p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'A')
 (p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'N'),
new ConvException(error converting input to floating point));


This is blatant enforce abuse IMO..

p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'A'))
throw new ConvException(error converting input to floating point));
p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'N'))
throw new ConvException(error converting input to floating point));



This is blatant code duplication.


Of the throw line? Sure, and you can re-write with nested 'if' if you
prefer. I prefer the code duplication tho.



Code duplication is very error prone. Furthermore I never ever want to
duplicate _error handling_ code. That just clutters up the generated
machine code if the compiler does not manage to reverse engineer and
generate the proper solution.


I can't comment on the machine code aspect. I don't find this particular
duplication error prone, but if you do you can use the nested if that
I've already mentioned.


10)


return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: (assert(false), 6);


*Much* clearer with the rewrite..

assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: 6;



This is a *much* better rewrite:
assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: 4;


Again, I was missing context.. is the return value of 6 not required in
release mode?


I was joking here. Your 'rewrite' of the original example changed its
release mode semantics, therefore I did the same thing.


My version performs the assert in all cases, throws an assert error in
the same/error cases, and still returns the correct/original values. The
only change is performing the assert in all cases, so I don't see how
that is a problem. Yours however is entirely broken (assuming the return
value of 6 is desired/required).

R



What you might be missing is that assert(false) is not compiled out in 
release mode. It emits a 'hlt' instruction which kills your program. 
However, your assert(c = 0x10); will be removed in release mode.






Re: Comma operator = broken design

2011-12-09 Thread Timon Gehr

I didn't notice the other parts of your post before.

On 12/09/2011 03:25 PM, Regan Heath wrote:

On Fri, 09 Dec 2011 13:42:34 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 02:28 PM, Regan Heath wrote:

On Fri, 09 Dec 2011 13:15:47 -, Timon Gehr timon.g...@gmx.ch
wrote:

On 12/09/2011 01:36 PM, Regan Heath wrote:

4)


if (std.ascii.toLower(p.front) == 'n' 
(p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))


'if' statements with side effects are yuck. I prefer the check for
error
and bail style but you could use multiple layers of 'if' instead..

if (std.ascii.toLower(p.front) != 'n') //error handling
p.popFront();
if (std.ascii.toLower(p.front) != 'f') //error handling
p.popFront();
if (!p.empty) //error handling



Your '//error handling' shortcut hides relevant information.


What information? With context I could be more specific about what to do
for each/all.


You can always grep the Phobos source to get context. Basically, you
are suggesting to replace the comma operator with gotos:

case 'i': case 'I':
p.popFront();
if (std.ascii.toLower(p.front) == 'n' 
(p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))
{
// 'inf'
return sign ? -Target.infinity : Target.infinity;
}
goto default;
default: {}
}


If using 'goto' is the 'correct' agreed upon style for phobos then, yes.
It's not my personal preference however and I'd probably refactor it
further if it was my own code.



The code was probably written that way to give an optimal implementation 
that does not use goto. How would you refactor the code?




5)


enforce((p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'A')
 (p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'N'),
new ConvException(error converting input to floating point));


This is blatant enforce abuse IMO..

p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'A'))
throw new ConvException(error converting input to floating point));
p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'N'))
throw new ConvException(error converting input to floating point));



This is blatant code duplication.


Of the throw line? Sure, and you can re-write with nested 'if' if you
prefer. I prefer the code duplication tho.



Code duplication is very error prone. Furthermore I never ever want to
duplicate _error handling_ code. That just clutters up the generated
machine code if the compiler does not manage to reverse engineer and
generate the proper solution.


I can't comment on the machine code aspect. I don't find this particular
duplication error prone, but if you do you can use the nested if that
I've already mentioned.



I don't like the nested if solution. Also it does not work that well in 
the general case because you might have a || operator somewhere instead 
of just  operators.




Re: Comma operator = broken design

2011-12-09 Thread Steven Schveighoffer
On Fri, 09 Dec 2011 09:25:34 -0500, Regan Heath re...@netmail.co.nz  
wrote:



On Fri, 09 Dec 2011 13:42:34 -, Timon Gehr timon.g...@gmx.ch wrote:

On 12/09/2011 02:28 PM, Regan Heath wrote:
On Fri, 09 Dec 2011 13:15:47 -, Timon Gehr timon.g...@gmx.ch  
wrote:

On 12/09/2011 01:36 PM, Regan Heath wrote:

4)


if (std.ascii.toLower(p.front) == 'n' 
(p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))


'if' statements with side effects are yuck. I prefer the check for  
error

and bail style but you could use multiple layers of 'if' instead..

if (std.ascii.toLower(p.front) != 'n') //error handling
p.popFront();
if (std.ascii.toLower(p.front) != 'f') //error handling
p.popFront();
if (!p.empty) //error handling



Your '//error handling' shortcut hides relevant information.


What information? With context I could be more specific about what to  
do

for each/all.


You can always grep the Phobos source to get context. Basically, you  
are suggesting to replace the comma operator with gotos:


 case 'i': case 'I':
 p.popFront();
 if (std.ascii.toLower(p.front) == 'n' 
 (p.popFront(), std.ascii.toLower(p.front) == 'f') 
(p.popFront(), p.empty))
 {
 // 'inf'
 return sign ? -Target.infinity : Target.infinity;
 }
 goto default;
 default: {}
 }


If using 'goto' is the 'correct' agreed upon style for phobos then,  
yes.  It's not my personal preference however and I'd probably refactor  
it further if it was my own code.




goto in this case is acceptable.  It's a goto case statement, which  
technically should be required for fall-through.



5)

enforce((p.popFront(), !p.empty  std.ascii.toUpper(p.front) ==  
'A')

 (p.popFront(), !p.empty  std.ascii.toUpper(p.front) == 'N'),
new ConvException(error converting input to floating point));


This is blatant enforce abuse IMO..

p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'A'))
throw new ConvException(error converting input to floating point));
p.popFront();
if(p.empty || std.ascii.toUpper(p.front) != 'N'))
throw new ConvException(error converting input to floating point));



This is blatant code duplication.


Of the throw line? Sure, and you can re-write with nested 'if' if you
prefer. I prefer the code duplication tho.



Code duplication is very error prone. Furthermore I never ever want to  
duplicate _error handling_ code. That just clutters up the generated  
machine code if the compiler does not manage to reverse engineer and  
generate the proper solution.


I can't comment on the machine code aspect.  I don't find this  
particular duplication error prone, but if you do you can use the nested  
if that I've already mentioned.


This case is a perfect example of what is right and wrong with the comma  
operator.


With the comma operator, the single statement avoids code duplication,  
which is good for maintenance.  However, it's extremely hard to see what's  
going on.  Timon, please accept that you may be one of the few who reads  
that statement and sees perfectly what's happening, I needed to read  
Regan's version to understand what it does without hurting my head too  
much.


My opinion?  I think it's better written like this:

p.popFront();
bool bad = void;
if(!(bad = p.empty || std.ascii.toUpper(p.front) != 'A'))
{
   p.popFront();
   bad = p.empty || std.ascii.toUpper(p.front) != 'N';
}
if(bad)
   throw new ConvException(error converting input to floating point);

And I'd probably reread it again, and throw in some comments to help me  
remember what the f*** I was doing :)


I don't see a smaller solution, or one that doesn't use a temporary,  
without using the comma operator or duplicating the throw/enforce call.


-Steve


Re: Comma operator = broken design

2011-12-09 Thread Timon Gehr

On 12/09/2011 04:37 PM, Regan Heath wrote:

On Fri, 09 Dec 2011 14:54:16 -, Timon Gehr timon.g...@gmx.ch wrote:

10)


return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: (assert(false), 6);


*Much* clearer with the rewrite..

assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: 6;



This is a *much* better rewrite:
assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: 4;


Again, I was missing context.. is the return value of 6 not
required in
release mode?


I was joking here. Your 'rewrite' of the original example changed its
release mode semantics, therefore I did the same thing.


My version performs the assert in all cases, throws an assert error in
the same/error cases, and still returns the correct/original values. The
only change is performing the assert in all cases, so I don't see how
that is a problem. Yours however is entirely broken (assuming the return
value of 6 is desired/required).

R



What you might be missing is that assert(false) is not compiled out in
release mode. It emits a 'hlt' instruction which kills your program.
However, your assert(c = 0x10); will be removed in release mode.


I was indeed missing that. I couldn't find anything about it on the
website. :)

R



http://d-programming-language.org/expression.html#AssertExpression


Re: Comma operator = broken design

2011-12-09 Thread Regan Heath

On Fri, 09 Dec 2011 14:54:16 -, Timon Gehr timon.g...@gmx.ch wrote:

10)


return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: (assert(false), 6);


*Much* clearer with the rewrite..

assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: c = 0x10 ? 4
: 6;



This is a *much* better rewrite:
assert(c = 0x10);
return
c = 0x7F ? 1
: c = 0x7FF ? 2
: c = 0x ? 3
: 4;


Again, I was missing context.. is the return value of 6 not required  
in

release mode?


I was joking here. Your 'rewrite' of the original example changed its
release mode semantics, therefore I did the same thing.


My version performs the assert in all cases, throws an assert error in
the same/error cases, and still returns the correct/original values. The
only change is performing the assert in all cases, so I don't see how
that is a problem. Yours however is entirely broken (assuming the return
value of 6 is desired/required).

R



What you might be missing is that assert(false) is not compiled out in  
release mode. It emits a 'hlt' instruction which kills your program.  
However, your assert(c = 0x10); will be removed in release mode.


I was indeed missing that.  I couldn't find anything about it on the  
website. :)


R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Comma operator = broken design

2011-12-09 Thread Jonathan M Davis
On Friday, December 09, 2011 13:00:57 Timon Gehr wrote:
 On 12/09/2011 10:26 AM, Jonathan M Davis wrote:
  On Friday, December 09, 2011 10:19:18 Don wrote:
  Are there any cases where you're using comma outside of for loops?
  I wonder how much would break if were made illegal everywhere else.
  
  I'm sure that it would break code, but most people consider it bad
  practice to use the comma operator for much outside of for loops.
 
 'most people'?
 
  Occasionally, it's
  useful to use one in an expression, but on the whole, it's just
  confusing and error-prone.
 
 It is confusing to people who don't know the language. It is a simple
 construct. In my experience, it is certainly not error prone. If you are
 aware that such an operator exists.
 
  And while it might break code to make the comma operator illegal
  outside of for loops, I would expect that fixing the broken code would
  generally be rather trivial.
 
 Sure.
 
  The resulting code may not be as compact, but it
  wouldn't be hard to write.
 
 It would be a PITA in some cases.
 
  And unless you're dealing with a programmer who
  uses it uncommonly often, not much code is going to break.
 
 I _am_ such a programmer.

In my experience, someone like you who uses the comma operator outside of for 
loops much at all is incredibly rare. It's far more typical to consider the 
comma operator confusing and error-prone than it is to use it frequently.

- Jonathan M Davis


Re: Comma operator = broken design

2011-12-09 Thread Jonathan M Davis
On Friday, December 09, 2011 12:36:25 Regan Heath wrote:
 On Fri, 09 Dec 2011 11:39:55 -, Timon Gehr timon.g...@gmx.ch wrote:
  These are the occurences of the comma operator in directory 'std':
 Here is my /very/ quick re-write of each without looking at the context of
 each snippet. There may be much better re-writes in context. Re-writing
 this was problematic /because/ the comma operator makes things that much
 more confusing to me. Especially example #5 below where the last ,
 actually separates enforce parameters!
 
 1)
 
  return r2.empty ? (r1 = r, true) : false;
 
 if (!r2.empty) return false;
 r1 = r;
 return true;

Actually, that particular usage of the comma operator makes me almost want to 
use it that way. It manages to take one of the type of statements that always 
irritates me when it's multiple lines and make it a single line.

- Jonathan M Davis


Re: Comma operator = broken design

2011-12-09 Thread Robert Jacques

On Fri, 09 Dec 2011 01:20:45 -0500, Kagamin s...@here.lot wrote:


On Thursday, 8 December 2011 at 17:18:57 UTC, Joshua Reusch wrote:



Ahem. So are you suggesting that (a,b) means a tuple
everywhere but in a
for loop, where it is used to separate two statements?


If we use the comma operator only for tuples, there needn't to
be a special case for loops:

for(x, y = 0 , 100; x  y ; x, y += 1,-1) { ... }


for(int x, y = 0 , 100; x  y ; x, y += 1,-1) { ... }

?



Here's how I understood it:

int x,y; // Defined somewhere in the code above

for( (x,y) = (0,100); x  y ; (x,y) += (1,-1) ) { ... }

So you have variable capture, assignment and add-assign happening.


Re: Comma operator = broken design

2011-12-09 Thread Robert Jacques

On Fri, 09 Dec 2011 00:27:39 -0500, so s...@so.so wrote:

On Fri, 09 Dec 2011 06:26:27 +0200, Robert Jacques sandf...@jhu.edu
wrote:


So it clashes with another thing about D, pragmatism.

I'm not sure what you mean by that.


It was/is one of the defining points of D AFAIK.
More than being theoretical it chose to be pragmatic, to solve the
problems we face day to day.
For the case at hand; Say uninitialized variables in C are undefined but
all the compilers do
the same thing that makes it in practice defined. So the below line should
execute same on all compilers.

type a;

Same applies to the extensions supported in all major compilers which is
absent in language spec.
If compilers don't support, they can't sell.

To the point. If you want to keep B-D rule with the presence of such big
design mistakes (C), you are not being pragmatic at all.


Interesting point. I agree with D being a very pragmatic language (it's one of 
my favorite things about it), but I come to a different conclusion. The ability 
to copy and paste code, i.e. source compatible, is one of the most pragmatic 
things a language can do. And, unlike C++, the B-D rule allows D to break 
compatibility and therefore convert design mistakes into invalid syntax. 
However, this is at the cost of preventing the invalidated syntax from being 
re-used for other means.


Re: Comma operator = broken design

2011-12-09 Thread Jonathan M Davis
On Friday, December 09, 2011 20:18:36 Robert Jacques wrote:
 On Fri, 09 Dec 2011 01:20:45 -0500, Kagamin s...@here.lot wrote:
  On Thursday, 8 December 2011 at 17:18:57 UTC, Joshua Reusch wrote:
  Ahem. So are you suggesting that (a,b) means a tuple
  everywhere but in a
  for loop, where it is used to separate two statements?
  
  If we use the comma operator only for tuples, there needn't to
  be a special case for loops:
  
  for(x, y = 0 , 100; x  y ; x, y += 1,-1) { ... }
  
  for(int x, y = 0 , 100; x  y ; x, y += 1,-1) { ... }
  
  ?
 
 Here's how I understood it:
 
 int x,y; // Defined somewhere in the code above
 
 for( (x,y) = (0,100); x  y ; (x,y) += (1,-1) ) { ... }
 
 So you have variable capture, assignment and add-assign happening.

I'd _hate_ to be restricted to doing the same operation in the 3rd portion of 
a for loop for all of its parts. The comma operator is _perfect_ for there, 
and I wouldn't want to see its behavior changed there regardless. e.g. things 
like this should continue to be perfectly possible and legal

for(; cond; ++x, y *= 2) {}

Tuples do _not_ have the proper semantics for a for loop. It would be one 
thing for the comma operator were to go away in the general case, but it would 
be horrible IMHO for its behavior to be changed in for loops - be it in an 
effort to make it act like it's using tuples or any other reason.

- Jonathan M Davis


Re: Comma operator = broken design

2011-12-08 Thread Dejan Lekic

 
 Why is this operator still kept around?

No offense, but I find it strange/funny that you even ask why! :)

Have you never used comma in for loops???



Comma operator = broken design

2011-12-08 Thread Kagamin
This is, honestly, ridiculous. On most European keyboard 
layouts, comma is on the same key as semicolon.
Modern shells usually allow to use several keyboard layouts, 
switching between them as you need. You may want to add US 
keyboard layout (selected layout is maintained per-window).


Re: Comma operator = broken design

2011-12-08 Thread Don

On 08.12.2011 05:52, bcs wrote:

On 12/07/2011 08:49 AM, Alex Rønne Petersen wrote:

I really do not see the value in allowing such syntax in the first
place. I've been told that one argument was that generated code might
use it, but I have no idea why it would be needed. Furthermore, this
operator makes it very hard to introduce Python-style tuples in the
language.


IIRC the generated code argument was actually made with regards to the
compiler doing internal rewriting of the AST. If I'm remembering
correctly, this make it even weaker as, at that point, there is no
reason that the form of the AST need match the syntax.


Worth noting that the comma operator inside the compiler is not the same 
as the one in the language. It supports declarations, in a way that D 
doesn't. You can't write this in normal D, for example:


   (int x; , x = 2);

But that's what the compiler does internally.

The compiler uses it internally argument isn't valid at all.


Re: Comma operator = broken design

2011-12-08 Thread so
On Thu, 08 Dec 2011 11:17:48 +0200, Dejan Lekic dejan.le...@gmail.com  
wrote:






Why is this operator still kept around?


No offense, but I find it strange/funny that you even ask why! :)

Have you never used comma in for loops???



Not sure if it is that relevant for D, but good point.

for(auto i=beg(), e=end(); i!=e; ++i)
for(auto i, j, k;; ++i, ++k)
...


Re: Comma operator = broken design

2011-12-08 Thread Regan Heath

On Thu, 08 Dec 2011 12:17:20 -, so s...@so.so wrote:

On Thu, 08 Dec 2011 11:17:48 +0200, Dejan Lekic dejan.le...@gmail.com  
wrote:






Why is this operator still kept around?


No offense, but I find it strange/funny that you even ask why! :)

Have you never used comma in for loops???



Not sure if it is that relevant for D, but good point.

for(auto i=beg(), e=end(); i!=e; ++i)
for(auto i, j, k;; ++i, ++k)
...


It's kinda amusing that this thread appeared just as we had a case of this  
here at work.  The developer accidentally coded something like...


if (function(..), FALSE)
{
}

Accidentally adding the , FALSE /after/ the ) instead of as a new  
parameter to the function.


(note; This was in C++ with default parameter values so the function can  
in fact take 1-4 args).


When I pointed this out, he said how does that even compile and was  
completely unaware of the existence of the comma operator, nor (once I  
explained it) did he realise it was in any way related to the comma used  
in for loops.  People simply don't think of them as being the same thing  
at all.  Instead, people learn the comma syntax as a special  
characteristic of the for loop, and use it nowhere else.


I think the comma operator is of little benefit (except where used in a  
for loop) and it is a source of bugs and we'd be better off without it.   
Even if it means porting C/C++ requires modification, or existing D (I  
doubt very much of it) breaks.


R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: Comma operator = broken design

2011-12-08 Thread so
On Thu, 08 Dec 2011 18:02:11 +0200, Regan Heath re...@netmail.co.nz  
wrote:


When I pointed this out, he said how does that even compile and was  
completely unaware of the existence of the comma operator, nor (once I  
explained it) did he realise it was in any way related to the comma used  
in for loops.  People simply don't think of them as being the same thing  
at all.  Instead, people learn the comma syntax as a special  
characteristic of the for loop, and use it nowhere else.


Not that related but my all time favorite is still:

type a = a + 2; // compiles with no errors, no warnings, no explosions  
(that i know of)


Re: Comma operator = broken design

2011-12-08 Thread Joshua Reusch



Ahem. So are you suggesting that (a,b) means a tuple everywhere but in a
for loop, where it is used to separate two statements?


If we use the comma operator only for tuples, there needn't to be a 
special case for loops:


for(x, y = 0 , 100; x  y ; x, y += 1,-1) { ... }



Re: Comma operator = broken design

2011-12-08 Thread Dejan Lekic


type a = a + 2; // compiles with no errors, no warnings, no 
explosions (that i know of)


If type has the default initialiser, then what is the problem?


Re: Comma operator = broken design

2011-12-08 Thread so
On Thu, 08 Dec 2011 19:25:10 +0200, Dejan Lekic dejan.le...@gmail.com  
wrote:




type a = a + 2; // compiles with no errors, no warnings, no explosions  
(that i know of)


If type has the default initialiser, then what is the problem?


What does it do in both C and D context?
1. It does different things.
2. C version even worse because of debug/release difference.
3. If D still does this, it violates the B-D rule (either does the same  
thing or doesn't compile at all. Actually there are many things violate  
this rule...)


type a; // even this simple code violates B-D rule.

What is the use case?
. Is there any?
. If there is not any you think, but still compiler allows it, it  
generates nothing but bugs (from experience :) ).


Question should be, why does it exist at all?


Re: Comma operator = broken design

2011-12-08 Thread Timon Gehr

On 12/08/2011 05:02 PM, Regan Heath wrote:

On Thu, 08 Dec 2011 12:17:20 -, so s...@so.so wrote:


On Thu, 08 Dec 2011 11:17:48 +0200, Dejan Lekic
dejan.le...@gmail.com wrote:





Why is this operator still kept around?


No offense, but I find it strange/funny that you even ask why! :)

Have you never used comma in for loops???



Not sure if it is that relevant for D, but good point.

for(auto i=beg(), e=end(); i!=e; ++i)
for(auto i, j, k;; ++i, ++k)
...


It's kinda amusing that this thread appeared just as we had a case of
this here at work. The developer accidentally coded something like...

if (function(..), FALSE)
{
}

Accidentally adding the , FALSE /after/ the ) instead of as a new
parameter to the function.

(note; This was in C++ with default parameter values so the function can
in fact take 1-4 args).

When I pointed this out, he said how does that even compile and was
completely unaware of the existence of the comma operator, nor (once I
explained it) did he realise it was in any way related to the comma used
in for loops. People simply don't think of them as being the same thing
at all. Instead, people learn the comma syntax as a special
characteristic of the for loop, and use it nowhere else.

I think the comma operator is of little benefit (except where used in a
for loop) and it is a source of bugs and we'd be better off without it.
Even if it means porting C/C++ requires modification, or existing D (I
doubt very much of it) breaks.



Phobos would break, for example. And some of my code too.




Re: Comma operator = broken design

2011-12-08 Thread Robert Jacques

On Thu, 08 Dec 2011 12:18:56 -0500, Joshua Reusch yos...@arkandos.de wrote:

Ahem. So are you suggesting that (a,b) means a tuple everywhere but in a
for loop, where it is used to separate two statements?


If we use the comma operator only for tuples, there needn't to be a
special case for loops:

for(x, y = 0 , 100; x  y ; x, y += 1,-1) { ... }


Clever! However,
1) Showing that the trivial example can be expressed with tuples is a good 
first step. The next step is to go after some of the advanced comma usages. 
i.e. What's the limitations of this approach? When does it break down?
2) As per the current tuple proposals, the above is a horrendous performance 
sink. Granted, more tuple awareness in the compiler might fix the problem, but 
that awareness is more than what's in the current tuple proposals.



Re: Comma operator = broken design

2011-12-08 Thread Robert Jacques

On Thu, 08 Dec 2011 13:17:44 -0500, so s...@so.so wrote:


On Thu, 08 Dec 2011 19:25:10 +0200, Dejan Lekic dejan.le...@gmail.com
wrote:



type a = a + 2; // compiles with no errors, no warnings, no explosions
(that i know of)


If type has the default initialiser, then what is the problem?


What does it do in both C and D context?
1. It does different things.
2. C version even worse because of debug/release difference.
3. If D still does this, it violates the B-D rule (either does the same
thing or doesn't compile at all. Actually there are many things violate
this rule...)

type a; // even this simple code violates B-D rule.

What is the use case?
. Is there any?
. If there is not any you think, but still compiler allows it, it
generates nothing but bugs (from experience :) ).

Question should be, why does it exist at all?


Actually, these statements don't violate the B-D rule. In C/C++ the value of 
'a' prior to use is implementation defined (i.e. it is undefined by the spec) 
and in practice tends to be some random stack value. D just sets that value to 
a consistent default, which is completely compliant with the C spec.


Re: Comma operator = broken design

2011-12-08 Thread so

On Fri, 09 Dec 2011 03:19:34 +0200, Robert Jacques sandf...@jhu.edu
wrote:


On Thu, 08 Dec 2011 13:17:44 -0500, so s...@so.so wrote:


On Thu, 08 Dec 2011 19:25:10 +0200, Dejan Lekic dejan.le...@gmail.com
wrote:



type a = a + 2; // compiles with no errors, no warnings, no explosions
(that i know of)


If type has the default initialiser, then what is the problem?


What does it do in both C and D context?
1. It does different things.
2. C version even worse because of debug/release difference.
3. If D still does this, it violates the B-D rule (either does the same
thing or doesn't compile at all. Actually there are many things violate
this rule...)

type a; // even this simple code violates B-D rule.

What is the use case?
. Is there any?
. If there is not any you think, but still compiler allows it, it
generates nothing but bugs (from experience :) ).

Question should be, why does it exist at all?


Actually, these statements don't violate the B-D rule. In C/C++ the  
value of 'a' prior to use is implementation defined (i.e. it is  
undefined by the spec) and in practice tends to be some random stack  
value. D just sets that value to a consistent default, which is  
completely compliant with the C spec.


I disagree. As you said while in C/C++ same thing gets assigned random  
values,
in D it doesn't. As a result, it changes both the coders' expectations and  
programs
outcome. Even the definitions are different. Undefined there and defined  
here.

I am not sure how to express this.

As far as i understand you are saying; Because uninitialized variables are  
undefined in C,
D can act as another C compiler and interpret this rule as it pleases. But  
in practice no compiler i know does that.
And assuming the variable initialized to some value is a bad programming  
practice, which i should say the most popular among its kind.

So it clashes with another thing about D, pragmatism.


Re: Comma operator = broken design

2011-12-08 Thread Robert Jacques

On Thu, 08 Dec 2011 21:23:11 -0500, so s...@so.so wrote:

On Fri, 09 Dec 2011 03:19:34 +0200, Robert Jacques sandf...@jhu.edu
wrote:


On Thu, 08 Dec 2011 13:17:44 -0500, so s...@so.so wrote:


On Thu, 08 Dec 2011 19:25:10 +0200, Dejan Lekic dejan.le...@gmail.com
wrote:



type a = a + 2; // compiles with no errors, no warnings, no explosions
(that i know of)


If type has the default initialiser, then what is the problem?


What does it do in both C and D context?
1. It does different things.
2. C version even worse because of debug/release difference.
3. If D still does this, it violates the B-D rule (either does the same
thing or doesn't compile at all. Actually there are many things violate
this rule...)

type a; // even this simple code violates B-D rule.

What is the use case?
. Is there any?
. If there is not any you think, but still compiler allows it, it
generates nothing but bugs (from experience :) ).

Question should be, why does it exist at all?


Actually, these statements don't violate the B-D rule. In C/C++ the
value of 'a' prior to use is implementation defined (i.e. it is
undefined by the spec) and in practice tends to be some random stack
value. D just sets that value to a consistent default, which is
completely compliant with the C spec.


I disagree. As you said while in C/C++ same thing gets assigned random
values,
in D it doesn't. As a result, it changes both the coders' expectations and
programs
outcome. Even the definitions are different. Undefined there and defined
here.
I am not sure how to express this.

As far as i understand you are saying; Because uninitialized variables are
undefined in C,
D can act as another C compiler and interpret this rule as it pleases. But
in practice no compiler i know does that.

In a discussion about language specifications, practical implementation details 
seem tangential to me. Besides, many C++ compilers do set variables to a 
default bit pattern in debug mode, in order to better detect and account for 
uninitialized variables. D's major difference is that it also does this in 
release mode. Besides, strictly speaking, the B-D rule is about valid, portable 
C/C++ code, which (arguably) isn't anything that uses uninitialized variables. 
In other words, the B-D rule isn't about D mimicking the behavior of a 
particular C/C++ compiler, it's about the C spec.


And assuming the variable initialized to some value is a bad programming
practice, which i should say the most popular among its kind.

I totally agree, from a normal control flow perspective. But .init has many 
uses, particularly in error detection and and repeatability of .init greatly 
eases debugging.


So it clashes with another thing about D, pragmatism.

I'm not sure what you mean by that.


Re: Comma operator = broken design

2011-12-08 Thread so
On Fri, 09 Dec 2011 06:26:27 +0200, Robert Jacques sandf...@jhu.edu  
wrote:



So it clashes with another thing about D, pragmatism.

I'm not sure what you mean by that.


It was/is one of the defining points of D AFAIK.
More than being theoretical it chose to be pragmatic, to solve the  
problems we face day to day.
For the case at hand; Say uninitialized variables in C are undefined but  
all the compilers do
the same thing that makes it in practice defined. So the below line should  
execute same on all compilers.


type a;

Same applies to the extensions supported in all major compilers which is  
absent in language spec.

If compilers don't support, they can't sell.

To the point. If you want to keep B-D rule with the presence of such big  
design mistakes (C), you are not being pragmatic at all.


Re: Comma operator = broken design

2011-12-08 Thread Kagamin

On Thursday, 8 December 2011 at 17:18:57 UTC, Joshua Reusch wrote:


Ahem. So are you suggesting that (a,b) means a tuple 
everywhere but in a

for loop, where it is used to separate two statements?


If we use the comma operator only for tuples, there needn't to 
be a special case for loops:


for(x, y = 0 , 100; x  y ; x, y += 1,-1) { ... }


for(int x, y = 0 , 100; x  y ; x, y += 1,-1) { ... }

?


Comma operator = broken design

2011-12-07 Thread Alex Rønne Petersen

Hi,

Consider this code:

if (condition)
foo();
else
bar(),

baz();

Notice the comma in the bar call. This will actually compile. Why? 
Because the program is really interpreted as:


if (condition)
{
foo();
}
else
{
bar();
baz();
}

This is, honestly, ridiculous. On most European keyboard layouts, comma 
is on the same key as semicolon. This means that a typo such as the 
above can lead to an incorrect (but compiling) program easily, rather 
than a compile-time error.


I really do not see the value in allowing such syntax in the first 
place. I've been told that one argument was that generated code might 
use it, but I have no idea why it would be needed. Furthermore, this 
operator makes it very hard to introduce Python-style tuples in the 
language.


Why is this operator still kept around?

- Alex


Comma operator = broken design

2011-12-07 Thread Joshua Cearley

It could be moved to use either the section character or one of the 
application-specific unicode points reserved for internal use by whatever an 
application wants.  This would eliminate confusing typing and, if using this 
for generated code, the generator can easily reference it by unicode ID when 
constructing the strings.


Re: Comma operator = broken design

2011-12-07 Thread Robert Jacques

On Wed, 07 Dec 2011 11:49:33 -0500, Alex Rønne Petersen xtzgzo...@gmail.com 
wrote:

Hi,

Consider this code:

if (condition)
 foo();
else
 bar(),

baz();

Notice the comma in the bar call. This will actually compile. Why?
Because the program is really interpreted as:

if (condition)
{
 foo();
}
else
{
 bar();
 baz();
}

This is, honestly, ridiculous. On most European keyboard layouts, comma
is on the same key as semicolon. This means that a typo such as the
above can lead to an incorrect (but compiling) program easily, rather
than a compile-time error.

I really do not see the value in allowing such syntax in the first
place. I've been told that one argument was that generated code might
use it, but I have no idea why it would be needed. Furthermore, this
operator makes it very hard to introduce Python-style tuples in the
language.

Why is this operator still kept around?


Take your pick:
1) So that legacy B/C/C++/D1/etc code can be trivially ported to D1/D2.
2) The comma operator is heavily used in regular old for loops.
3) It is frequently used internally by the compiler to effect syntactic 
lowerings. A decent portion of D's syntax is not transformed directly to 
instructions; instead it is converted to simpler code which is in turn 
processed. Technically the compiler doesn't need ',' in the language to do this.
4) D has a policy of 'If C/C++ code compiles in D without error, it must have 
the same syntactic meaning as in C.' So even if we remove the comma operator, 
we might not get comma-style tuples. (I don't know if anyone has looked at this 
issue in depth)
5) The comma and semicolon are on different keys on US style keyboards.
6) It is trivial to change your keyboard layout (I've hotkeyed Greek for fast 
math symbols)
7) We are trying to stabilize the language, so massive code-breaks are frowned 
upon.

Personally, I think real tuples outweigh the comma-operator, but real tuples 
don't necessarily need the ',' (we could use '..' or something else instead) 
and removing comma-expressions isn't without its problems.

P.S. I was going to suggest testing/looking into issue 4, but a quick test in D 
suggests that there are valid ',' and '(,)' style expressions in C/C++ that 
would remain valid in D with comma-tuples.


Re: Comma operator = broken design

2011-12-07 Thread Adam Ruppe
Alex Rønne Petersen Wrote:
 I really do not see the value in allowing such syntax in the first 
 place. I've been told that one argument was that generated code might 
 use it, but I have no idea why it would be needed.


Aside from the compiler's implementation, one possible use
is something I ended up doing in Javascript recently.

I have a thing that takes an attribute and pastes it into a code
string to check it.

given validate=this.value.length  3

it writes:

if(!(this.value.length  3))
   return false; // failed validation

since the given string is inside an if statement, you can't put
a semicolon in there.


So, if you have a check more complex than returning a boolean
and want to stuff it all in that string (so functions are out), the
comma lets you do it:

validate=do something, true



This is pretty ugly style that I think I've only ever done in D inside
a for loop... but the point is sometimes something comes up, and
it's nice to have another option available, even if it is ugly.


Re: Comma operator = broken design

2011-12-07 Thread Nick Sabalausky
Adam Ruppe destructiona...@gmail.com wrote in message 
news:jbo8rr$rhh$1...@digitalmars.com...
 Alex Rønne Petersen Wrote:
 I really do not see the value in allowing such syntax in the first
 place. I've been told that one argument was that generated code might
 use it, but I have no idea why it would be needed.


 Aside from the compiler's implementation, one possible use
 is something I ended up doing in Javascript recently.

 I have a thing that takes an attribute and pastes it into a code
 string to check it.

 given validate=this.value.length  3

 it writes:

 if(!(this.value.length  3))
   return false; // failed validation

 since the given string is inside an if statement, you can't put
 a semicolon in there.


 So, if you have a check more complex than returning a boolean
 and want to stuff it all in that string (so functions are out), the
 comma lets you do it:

 validate=do something, true



 This is pretty ugly style that I think I've only ever done in D inside
 a for loop... but the point is sometimes something comes up, and
 it's nice to have another option available, even if it is ugly.

Don't know about JS, but D can solve the same problem with anon delegates, 
which is less obscure anyway.




Re: Comma operator = broken design

2011-12-07 Thread Nick Sabalausky
Robert Jacques sandf...@jhu.edu wrote in message 
news:op.v54q04vd26s...@sandford.myhome.westell.com...
 On Wed, 07 Dec 2011 11:49:33 -0500, Alex Rønne Petersen 
 xtzgzo...@gmail.com wrote:

 Why is this operator still kept around?

 Take your pick:
 1) So that legacy B/C/C++/D1/etc code can be trivially ported to D1/D2.

That's a pretty weak counter-argument:

A. I'd think a lot of C/C++ code can't be trivially ported to D anyway.
B. B, seriously? ;)
C. Being able to link to C/C++ makes it less likely to need to port C/C++ 
code anyway.
D. Outside of for loops (special-case-able), comma operator is rarely used 
in C/C++/D.
E. Even among actual uses of the comma operator, I think it'd be rare (if 
even possible) to have a use of it that isn't trivially convertable to 
non-comma.

 2) The comma operator is heavily used in regular old for loops.

That can be special cased.

 3) It is frequently used internally by the compiler to effect syntactic 
 lowerings. A decent portion of D's syntax is not transformed directly to 
 instructions; instead it is converted to simpler code which is in turn 
 processed. Technically the compiler doesn't need ',' in the language to do 
 this.

Like you're saying, it can exist in the compiler's internal AST without 
having to exist in the parser.

 4) D has a policy of 'If C/C++ code compiles in D without error, it must 
 have the same syntactic meaning as in C.' So even if we remove the comma 
 operator, we might not get comma-style tuples. (I don't know if anyone has 
 looked at this issue in depth)

Meh, I still think it would be better to allow such situations on occasion 
and just provide a --c-lint switch to warn (or error) on any such code. 
Porting C/C++ to D is a much smaller use case than writing/maintaining D. I 
don't think it's a good idea to hamper the langauge for the sake of such an 
edge case when it's just as possible to simply handle that scenario with a 
special tool/switch. But I guess I'm outvoted by Walter on that :(

 5) The comma and semicolon are on different keys on US style keyboards.
 6) It is trivial to change your keyboard layout (I've hotkeyed Greek for 
 fast math symbols)

Those are very weak counter-arguments.

 7) We are trying to stabilize the language, so massive code-breaks are 
 frowned upon.


Poo ;(

 Personally, I think real tuples outweigh the comma-operator, but real 
 tuples don't necessarily need the ',' (we could use '..' or something else 
 instead) and removing comma-expressions isn't without its problems.

 P.S. I was going to suggest testing/looking into issue 4, but a quick test 
 in D suggests that there are valid ',' and '(,)' style expressions in 
 C/C++ that would remain valid in D with comma-tuples. 




Re: Comma operator = broken design

2011-12-07 Thread Timon Gehr

On 12/07/2011 07:02 PM, Nick Sabalausky wrote:

Adam Ruppedestructiona...@gmail.com  wrote in message
news:jbo8rr$rhh$1...@digitalmars.com...

Alex Rønne Petersen Wrote:

I really do not see the value in allowing such syntax in the first
place. I've been told that one argument was that generated code might
use it, but I have no idea why it would be needed.



Aside from the compiler's implementation, one possible use
is something I ended up doing in Javascript recently.

I have a thing that takes an attribute and pastes it into a code
string to check it.

given validate=this.value.length  3

it writes:

if(!(this.value.length  3))
   return false; // failed validation

since the given string is inside an if statement, you can't put
a semicolon in there.


So, if you have a check more complex than returning a boolean
and want to stuff it all in that string (so functions are out), the
comma lets you do it:

validate=do something, true



This is pretty ugly style that I think I've only ever done in D inside
a for loop... but the point is sometimes something comes up, and
it's nice to have another option available, even if it is ugly.


Don't know about JS, but D can solve the same problem with anon delegates,
which is less obscure anyway.




I think Don said that DMD cannot currently inline any delegates. Imho 
the spec should even *require* inlining in the special case that such a 
delegate is immediately executed. (even for debug builds).


Re: Comma operator = broken design

2011-12-07 Thread Jonathan M Davis
On Wednesday, December 07, 2011 23:10:53 Timon Gehr wrote:
 On 12/07/2011 07:02 PM, Nick Sabalausky wrote:
  Adam Ruppedestructiona...@gmail.com wrote in message
  news:jbo8rr$rhh$1...@digitalmars.com...
  
  Alex Rønne Petersen Wrote:
  I really do not see the value in allowing such syntax in the first
  place. I've been told that one argument was that generated code
  might
  use it, but I have no idea why it would be needed.
  
  Aside from the compiler's implementation, one possible use
  is something I ended up doing in Javascript recently.
  
  I have a thing that takes an attribute and pastes it into a code
  string to check it.
  
  given validate=this.value.length 3
  
  it writes:
  
  if(!(this.value.length 3))
  
  return false; // failed validation
  
  since the given string is inside an if statement, you can't put
  a semicolon in there.
  
  
  So, if you have a check more complex than returning a boolean
  and want to stuff it all in that string (so functions are out), the
  comma lets you do it:
  
  validate=do something, true
  
  
  
  This is pretty ugly style that I think I've only ever done in D inside
  a for loop... but the point is sometimes something comes up, and
  it's nice to have another option available, even if it is ugly.
  
  Don't know about JS, but D can solve the same problem with anon
  delegates, which is less obscure anyway.
 
 I think Don said that DMD cannot currently inline any delegates. Imho
 the spec should even *require* inlining in the special case that such a
 delegate is immediately executed. (even for debug builds).

lazy doesn't get inlined for the same reason (since it's essentially using a 
delegate), and that potentially has some nasty implications for performance 
with regards to stuff like enforce. In the recent thread on std.regex's 
performance, while enforce was definitely not at the top of the list of 
functions in the profiler (listed descending by running time), it was 
definitely 
a decent portion of the running time of the program. The cost of enforce 
should be comparable to the cost of assert, but with the issues of inlining 
lazy and delegates, it definitely isn't that efficient. These sorts of things 
need to be inlinable.

- Jonathan M Davis


Re: Comma operator = broken design

2011-12-07 Thread Robert Jacques

On Wed, 07 Dec 2011 13:19:31 -0500, Nick Sabalausky a@a.a wrote:


Robert Jacques sandf...@jhu.edu wrote in message
news:op.v54q04vd26s...@sandford.myhome.westell.com...

On Wed, 07 Dec 2011 11:49:33 -0500, Alex Rønne Petersen
xtzgzo...@gmail.com wrote:


Why is this operator still kept around?


Take your pick:
1) So that legacy B/C/C++/D1/etc code can be trivially ported to D1/D2.


That's a pretty weak counter-argument:

A. I'd think a lot of C/C++ code can't be trivially ported to D anyway.

That statement implies that there is a lot of code that can be trivially ported 
to D.


B. B, seriously? ;)

Yes, the poster was (in part) asking about where the comma operator came from. 
C did a lot of stupid things to be portable with B and we have all inherited 
that legacy.


C. Being able to link to C/C++ makes it less likely to need to port C/C++
code anyway.

Sure, for code that's in reasonably complete libraries that full fill your use 
cases and are supported by someone else. That's not always the case.


D. Outside of for loops (special-case-able), comma operator is rarely used
in C/C++/D.

Special casing is a big and dangerous hammer. Generally, it introduces extra 
work for the compiler and cognitive load for the programmer. Now, we have used 
special casing to detect common errors to great effect, but these don't add 
cognitive load to the programmer.


E. Even among actual uses of the comma operator, I think it'd be rare (if
even possible) to have a use of it that isn't trivially convertable to
non-comma.

True, but that still implies extra work on the part of the programmer.


2) The comma operator is heavily used in regular old for loops.


That can be special cased.

Ahem. So are you suggesting that (a,b) means a tuple everywhere but in a for 
loop, where it is used to separate two statements?


5) The comma and semicolon are on different keys on US style keyboards.
6) It is trivial to change your keyboard layout (I've hotkeyed Greek for
fast math symbols)


Those are very weak counter-arguments.

I don't disagree, but the poster's original argument was (essentially) that EU 
keyboards put ; and , on the same key, so it was easy to mistype between the 
two. I was just suggesting that maybe the poster might want to fix their 
keyboard before trying to 'fix' the language.


Re: Comma operator = broken design

2011-12-07 Thread bcs

On 12/07/2011 08:49 AM, Alex Rønne Petersen wrote:

I really do not see the value in allowing such syntax in the first
place. I've been told that one argument was that generated code might
use it, but I have no idea why it would be needed. Furthermore, this
operator makes it very hard to introduce Python-style tuples in the
language.


IIRC the generated code argument was actually made with regards to the 
compiler doing internal rewriting of the AST. If I'm remembering 
correctly, this make it even weaker as, at that point, there is no 
reason that the form of the AST need match the syntax.