Re: Increment / Decrement Operator Behavior

2012-06-06 Thread Dejan Lekic
On Tue, 05 Jun 2012 10:23:18 +0200, Mikael Lindsten wrote:

 2012/6/5 Jonathan M Davis jmdavisp...@gmx.com


 I think that Bernard is being a bit harsh, but in essence, I agree.
 Since the
 evaluation order of arguments is undefined, programmers should be aware
 of that
 and code accordingly. If they don't bother to learn, then they're going
 to get
 bitten, and that's life.

 Now, Walter _has_ expressed interest in changing it so that the order
 of evaluation for function arguments is fully defined as being
 left-to-right, which solves the issue. I'd still council against
 getting into the habit of writing code which relies on the order of
 evaluation for the arguments to a function, since it's so common for
 other languages not to define it (so that
 the compiler can better optimize the calls), and so getting into the
 habit of
 writing code which _does_ depend on the order of evalution for function
 arguments will cause you to write bad code you when you work in most
 other programming languages.

 As for treating pre or post-increment operators specially in some
 manner, that
 doesn't make sense. The problem is far more general than that. If we're
 going
 to change anything, it would be to make it so that the language itself
 defines
 the order of evaluation of function arguments as being left-to-right.

 - Jonathan M Davis


 Agree completely!
 div class=gmail_quote2012/6/5 Jonathan M Davis span
 dir=ltrlt;a href=mailto:jmdavisp...@gmx.com;
 target=_blankjmdavisp...@gmx.com/agt;/spanblockquote
 class=gmail_quote style=margin:0 0 0 .8ex;border-left:1px #ccc
 solid;padding-left:1ex div class=HOEnZbdiv class=h5
 br
 /div/divI think that Bernard is being a bit harsh, but in essence, I
 agree. Since thebr evaluation order of arguments is undefined,
 programmers should be aware of thatbr and code accordingly. If they
 don#39;t bother to learn, then they#39;re going to getbr bitten, and
 that#39;s life.br
 br
 Now, Walter _has_ expressed interest in changing it so that the order
 ofbr evaluation for function arguments is fully defined as being
 left-to-right,br which solves the issue. I#39;d still council against
 getting into the habit ofbr writing code which relies on the order of
 evaluation for the arguments to abr function, since it#39;s so common
 for other languages not to define it (so thatbr the compiler can
 better optimize the calls), and so getting into the habit ofbr writing
 code which _does_ depend on the order of evalution for functionbr
 arguments will cause you to write bad code you when you work in most
 otherbr programming languages.br
 br
 As for treating pre or post-increment operators specially in some
 manner, thatbr doesn#39;t make sense. The problem is far more general
 than that. If we#39;re goingbr to change anything, it would be to
 make it so that the language itself definesbr the order of evaluation
 of function arguments as being left-to-right.br span
 class=HOEnZbfont color=#88br - Jonathan M Davisbr
 /font/span/blockquote/divbrdivAgree
 completely!/divdivbr/div


Ah noes, my eyes... HTML code... :-(


-- 
Dejan Lekic
  mailto:dejan.lekic(a)gmail.com
  http://dejan.lekic.org 


Re: Increment / Decrement Operator Behavior

2012-06-06 Thread Iain Buclaw
On 4 June 2012 23:37, Jonathan M Davis jmdavisp...@gmx.com wrote:
 On Monday, June 04, 2012 23:22:26 Bernard Helyer wrote:
 On Monday, 4 June 2012 at 20:44:42 UTC, bearophile wrote:
  Bernard Helyer:
  If you find yourself using postfix increment/decrement
  operators in the same function call in multiple arguments,
  slap yourself firmly in the face and refactor that code.
 
  I think this is not acceptable, you can't rely on that, future
  D programers will not slap themselves and refactor their code.
  Some of the acceptable alternatives are:
  1) Make post/pre increments return void. This avoid those
  troubles. I think Go language has chosen this. This is my
  preferred solution.
  2) Turn that code into a syntax error for some other cause.
  3) Design the language so post/pre increments give a defined
  effect on all D compilers on all CPUs. Walter since lot of time
  says this is planned for D. This leads to deterministic
  programs, but sometimes they are hard to understand and hard to
  translate (port) to other languages any way. Translating code
  to other languages is not irrelevant because D must be designed
  to make it easy to understand the semantics of the code.
 
  Bye,
  bearophile

 If people can't be bothered to understand what they write, they
 can go hang.

 I think that Bernard is being a bit harsh, but in essence, I agree. Since the
 evaluation order of arguments is undefined, programmers should be aware of 
 that
 and code accordingly. If they don't bother to learn, then they're going to get
 bitten, and that's life.

 Now, Walter _has_ expressed interest in changing it so that the order of
 evaluation for function arguments is fully defined as being left-to-right,
 which solves the issue. I'd still council against getting into the habit of
 writing code which relies on the order of evaluation for the arguments to a
 function, since it's so common for other languages not to define it (so that
 the compiler can better optimize the calls), and so getting into the habit of
 writing code which _does_ depend on the order of evalution for function
 arguments will cause you to write bad code you when you work in most other
 programming languages.

 As for treating pre or post-increment operators specially in some manner, that
 doesn't make sense. The problem is far more general than that. If we're going
 to change anything, it would be to make it so that the language itself defines
 the order of evaluation of function arguments as being left-to-right.


the language itself defines the order of evaluation of function
arguments as being left-to-right ... if the calling convention
defines it.

For extern(D) the way you can expect order of evaluation to work in
gdc generated code - for instance - is that each argument is evaluated
from left to right, and if it has any side effects, then it is stored
into a temporary prior to calling the function.

For extern(C) the order of evaluation is actually defined by the
underlying architecture.  For example, i386 evaluates right-to-left,
however other architectures (ie: ARM) perform left-to-right evaluation
of function arguments.  Incidentally, I know there are a few tests in
the testsuite that depend on the i386 behaviour, but that is something
else to worry about.


Regards
-- 
Iain Buclaw

*(p  e ? p++ : p) = (c  0x0f) + '0';


Re: Increment / Decrement Operator Behavior

2012-06-05 Thread Timon Gehr

On 06/04/2012 08:36 PM, Xinok wrote:

The increment and decrement operators are highly dependent on operator
precedence and associativity. If the actions are performed in a
different order than the developer presumed, it could cause unexpected
behavior.

I had a simple idea to change the behavior of this operator. It works
for the postfix operators but not prefix. Take the following code:

size_t i = 5;
writeln(i--, i--, i--);

As of now, this writes 543. With my idea, instead it would write,
555. Under the hood, the compiler would rewrite the code as:

size_t i = 5;
writeln(i, i, i);
--i;
--i;
--i;

It decrements the variable after the current statement. While not the
norm, this behavior is at least predictable. For non-static variables,
such as array elements, the compiler could store a temporary reference
to the variable so it can decrement it afterwards.

I'm not actually proposing we actually make this change. I simply
thought it was a nifty idea worth sharing.


The behaviour the language requires is that the function call executes 
as if the parameters were evaluated from left to right. This is exactly 
the behaviour you observe. What is the problem you want to fix?


Re: Increment / Decrement Operator Behavior

2012-06-05 Thread Mikael Lindsten
2012/6/5 Jonathan M Davis jmdavisp...@gmx.com


 I think that Bernard is being a bit harsh, but in essence, I agree. Since
 the
 evaluation order of arguments is undefined, programmers should be aware of
 that
 and code accordingly. If they don't bother to learn, then they're going to
 get
 bitten, and that's life.

 Now, Walter _has_ expressed interest in changing it so that the order of
 evaluation for function arguments is fully defined as being left-to-right,
 which solves the issue. I'd still council against getting into the habit of
 writing code which relies on the order of evaluation for the arguments to a
 function, since it's so common for other languages not to define it (so
 that
 the compiler can better optimize the calls), and so getting into the habit
 of
 writing code which _does_ depend on the order of evalution for function
 arguments will cause you to write bad code you when you work in most other
 programming languages.

 As for treating pre or post-increment operators specially in some manner,
 that
 doesn't make sense. The problem is far more general than that. If we're
 going
 to change anything, it would be to make it so that the language itself
 defines
 the order of evaluation of function arguments as being left-to-right.

 - Jonathan M Davis


Agree completely!


Re: Increment / Decrement Operator Behavior

2012-06-04 Thread simendsjo

On Mon, 04 Jun 2012 20:36:14 +0200, Xinok xi...@live.com wrote:

The increment and decrement operators are highly dependent on operator  
precedence and associativity. If the actions are performed in a  
different order than the developer presumed, it could cause unexpected  
behavior.


I had a simple idea to change the behavior of this operator. It works  
for the postfix operators but not prefix. Take the following code:


size_t i = 5;
writeln(i--, i--, i--);

As of now, this writes 543. With my idea, instead it would write,  
555. Under the hood, the compiler would rewrite the code as:


size_t i = 5;
writeln(i, i, i);
--i;
--i;
--i;

It decrements the variable after the current statement. While not the  
norm, this behavior is at least predictable. For non-static variables,  
such as array elements, the compiler could store a temporary reference  
to the variable so it can decrement it afterwards.


I'm not actually proposing we actually make this change. I simply  
thought it was a nifty idea worth sharing.


If I ever saw a construct like that, I would certainly test how that  
works, then rewrite it.
I wouldn't find it natural with the new behavior either. I would expect  
543 or 345.
How often do you come across code like that? I think it's an anti-pattern,  
and shouldn't be encouraged even if it was easier to understand.


Re: Increment / Decrement Operator Behavior

2012-06-04 Thread Bernard Helyer
If you find yourself using postfix increment/decrement operators 
in the same function call in multiple arguments, slap yourself 
firmly in the face and refactor that code.




Re: Increment / Decrement Operator Behavior

2012-06-04 Thread simendsjo

On Mon, 04 Jun 2012 20:57:11 +0200, simendsjo simend...@gmail.com wrote:


On Mon, 04 Jun 2012 20:36:14 +0200, Xinok xi...@live.com wrote:

The increment and decrement operators are highly dependent on operator  
precedence and associativity. If the actions are performed in a  
different order than the developer presumed, it could cause unexpected  
behavior.


I had a simple idea to change the behavior of this operator. It works  
for the postfix operators but not prefix. Take the following code:


size_t i = 5;
writeln(i--, i--, i--);

As of now, this writes 543. With my idea, instead it would write,  
555. Under the hood, the compiler would rewrite the code as:


size_t i = 5;
writeln(i, i, i);
--i;
--i;
--i;

It decrements the variable after the current statement. While not the  
norm, this behavior is at least predictable. For non-static variables,  
such as array elements, the compiler could store a temporary reference  
to the variable so it can decrement it afterwards.


I'm not actually proposing we actually make this change. I simply  
thought it was a nifty idea worth sharing.


If I ever saw a construct like that, I would certainly test how that  
works, then rewrite it.
I wouldn't find it natural with the new behavior either. I would expect  
543 or 345.
How often do you come across code like that? I think it's an  
anti-pattern, and shouldn't be encouraged even if it was easier to  
understand.


Oh, and what should writeln(i++, ++i, ++i, i++) do?

It is messy whatever the logic implementation.


Re: Increment / Decrement Operator Behavior

2012-06-04 Thread Xinok

On Monday, 4 June 2012 at 20:08:57 UTC, simendsjo wrote:

Oh, and what should writeln(i++, ++i, ++i, i++) do?

It is messy whatever the logic implementation.


For prefix operators, it would be logical to perform the action 
before the statement, such as the code would be rewritten as:


++i
++i
writeln(i, i, i, i)
i++
i++

However, I already stated that it wouldn't work for prefix 
operators. Take this statement:


++foo(++i)

There's no way to increment the return value of foo without 
calling foo first. This logic would only work for the postfix 
operators.


I came up with the idea after refactoring this code:
https://github.com/Xinok/XSort/blob/master/timsort.d#L111

Each call to mergeAt is followed by --stackLen. I could have used 
stackLen-- in the mergeAt statement instead, but I didn't want to 
rely on operator precedence for the correct behavior.


Re: Increment / Decrement Operator Behavior

2012-06-04 Thread bearophile

Bernard Helyer:

If you find yourself using postfix increment/decrement 
operators in the same function call in multiple arguments, slap 
yourself firmly in the face and refactor that code.


I think this is not acceptable, you can't rely on that, future D 
programers will not slap themselves and refactor their code. Some 
of the acceptable alternatives are:
1) Make post/pre increments return void. This avoid those 
troubles. I think Go language has chosen this. This is my 
preferred solution.

2) Turn that code into a syntax error for some other cause.
3) Design the language so post/pre increments give a defined 
effect on all D compilers on all CPUs. Walter since lot of time 
says this is planned for D. This leads to deterministic programs, 
but sometimes they are hard to understand and hard to translate 
(port) to other languages any way. Translating code to other 
languages is not irrelevant because D must be designed to make it 
easy to understand the semantics of the code.


Bye,
bearophile


Re: Increment / Decrement Operator Behavior

2012-06-04 Thread Bernard Helyer

On Monday, 4 June 2012 at 20:44:42 UTC, bearophile wrote:

Bernard Helyer:

If you find yourself using postfix increment/decrement 
operators in the same function call in multiple arguments, 
slap yourself firmly in the face and refactor that code.


I think this is not acceptable, you can't rely on that, future 
D programers will not slap themselves and refactor their code. 
Some of the acceptable alternatives are:
1) Make post/pre increments return void. This avoid those 
troubles. I think Go language has chosen this. This is my 
preferred solution.

2) Turn that code into a syntax error for some other cause.
3) Design the language so post/pre increments give a defined 
effect on all D compilers on all CPUs. Walter since lot of time 
says this is planned for D. This leads to deterministic 
programs, but sometimes they are hard to understand and hard to 
translate (port) to other languages any way. Translating code 
to other languages is not irrelevant because D must be designed 
to make it easy to understand the semantics of the code.


Bye,
bearophile


If people can't be bothered to understand what they write, they 
can go hang.





Re: Increment / Decrement Operator Behavior

2012-06-04 Thread Jonathan M Davis
On Monday, June 04, 2012 23:22:26 Bernard Helyer wrote:
 On Monday, 4 June 2012 at 20:44:42 UTC, bearophile wrote:
  Bernard Helyer:
  If you find yourself using postfix increment/decrement
  operators in the same function call in multiple arguments,
  slap yourself firmly in the face and refactor that code.
  
  I think this is not acceptable, you can't rely on that, future
  D programers will not slap themselves and refactor their code.
  Some of the acceptable alternatives are:
  1) Make post/pre increments return void. This avoid those
  troubles. I think Go language has chosen this. This is my
  preferred solution.
  2) Turn that code into a syntax error for some other cause.
  3) Design the language so post/pre increments give a defined
  effect on all D compilers on all CPUs. Walter since lot of time
  says this is planned for D. This leads to deterministic
  programs, but sometimes they are hard to understand and hard to
  translate (port) to other languages any way. Translating code
  to other languages is not irrelevant because D must be designed
  to make it easy to understand the semantics of the code.
  
  Bye,
  bearophile
 
 If people can't be bothered to understand what they write, they
 can go hang.

I think that Bernard is being a bit harsh, but in essence, I agree. Since the 
evaluation order of arguments is undefined, programmers should be aware of that 
and code accordingly. If they don't bother to learn, then they're going to get 
bitten, and that's life.

Now, Walter _has_ expressed interest in changing it so that the order of 
evaluation for function arguments is fully defined as being left-to-right, 
which solves the issue. I'd still council against getting into the habit of 
writing code which relies on the order of evaluation for the arguments to a 
function, since it's so common for other languages not to define it (so that 
the compiler can better optimize the calls), and so getting into the habit of 
writing code which _does_ depend on the order of evalution for function 
arguments will cause you to write bad code you when you work in most other
programming languages.

As for treating pre or post-increment operators specially in some manner, that 
doesn't make sense. The problem is far more general than that. If we're going 
to change anything, it would be to make it so that the language itself defines 
the order of evaluation of function arguments as being left-to-right.

- Jonathan M Davis


Re: Increment / Decrement Operator Behavior

2012-06-04 Thread bearophile

Jonathan M Davis:

If they don't bother to learn, then they're going to get 
bitten, and that's life.


A modern language must try to avoid common programmer mistakes, 
where possible (like in this case).



As for treating pre or post-increment operators specially in 
some manner, that
doesn't make sense. The problem is far more general than that. 
If we're going
to change anything, it would be to make it so that the language 
itself defines
the order of evaluation of function arguments as being 
left-to-right.


Probably I have expressed myself badly there, sorry. I'd like to 
see function calls fixed as Walter has stated.
And regarding pre/post de/increment operators, I find them handy, 
but I have seen _so much_ C/C++ code that abuses them that maybe 
I'd like them to return void, as in Go.


Bye,
bearophile


Re: Increment / Decrement Operator Behavior

2012-06-04 Thread Xinok

On Monday, 4 June 2012 at 20:44:42 UTC, bearophile wrote:
1) Make post/pre increments return void. This avoid those 
troubles. I think Go language has chosen this. This is my 
preferred solution.
I wonder in that case, is it even worth including in the 
language? For me anyways, the whole point of these operators is 
to use them in expressions. Otherwise, why not simply write 
(i+=1)?


Re: Increment / Decrement Operator Behavior

2012-06-04 Thread Kevin Cox
On Jun 4, 2012 8:43 PM, Xinok xi...@live.com wrote:

 I wonder in that case, is it even worth including in the language? For me
anyways, the whole point of these operators is to use them in expressions.
Otherwise, why not simply write (i+=1)?

For pointers they are useful because they go up in units not bytes
(although addition often does too).