Re: undefined compound chaining behavior

classic Classic list List threaded Threaded
62 messages Options
1234
Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Rik-4
On 06/06/2014 08:06 AM, [hidden email] wrote:

> Message: 5
> Date: Fri, 6 Jun 2014 17:20:08 +0330
> From: Hossein Sajjadi <[hidden email]>
> To: [hidden email]
> Subject: chaining compound assignment results in undefined behavior
> Message-ID:
> <[hidden email]>
> Content-Type: text/plain; charset=UTF-8
>
> Hi
>
> There is a problem with chaining compound assignment.
> For example the expression a=1;a+=a+=4 will result 10.
> I think such a behavior is borrowed from C language but this behavior
> is known as "undefined behavior".
>  This issue have been resolven in Java.
>  Java language guarantees that the operands of operators appear
> to be evaluated in a specific evaluation order , namely, from left to
> right. ?15.7
> Other specifications about evaluation of expressions are in
> "The Java? Language Specification"
>
>  also this approach is followed by c# language
>  so result of above expression in Java is 6

I don't think we need to do anything here.  First, code should
self-documenting and easy to understand.  When I first looked at the
statement I couldn't figure out what the intent was, and so I'm not
surprised that the compiler also has a hard time deciding what to do.  So,
I would suggest that rather than introduce complexities in to the parser,
the programmer should simply write what they mean.

If the programmer wants 6 as an answer, then code
a = 1; a += a; a+= 4

If the programmer wants 10 as an answer, then code
a = 1; a +=4; a += a

I tried the example in C++ and the result with the gcc compiler is 10 so
I'm perfectly happy to define the behavior that multiple in-place operators
are evaluated in a specific evaluation order which happens to be "right to
left".

Cheers,
Rik

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Seyyed Hossein Sajjadi
but such an expression results in undefined behavior

On 6/6/14, Rik <[hidden email]> wrote:

> On 06/06/2014 08:06 AM, [hidden email] wrote:
>> Message: 5
>> Date: Fri, 6 Jun 2014 17:20:08 +0330
>> From: Hossein Sajjadi <[hidden email]>
>> To: [hidden email]
>> Subject: chaining compound assignment results in undefined behavior
>> Message-ID:
>> <[hidden email]>
>> Content-Type: text/plain; charset=UTF-8
>>
>> Hi
>>
>> There is a problem with chaining compound assignment.
>> For example the expression a=1;a+=a+=4 will result 10.
>> I think such a behavior is borrowed from C language but this behavior
>> is known as "undefined behavior".
>>  This issue have been resolven in Java.
>>  Java language guarantees that the operands of operators appear
>> to be evaluated in a specific evaluation order , namely, from left to
>> right. ?15.7
>> Other specifications about evaluation of expressions are in
>> "The Java? Language Specification"
>>
>>  also this approach is followed by c# language
>>  so result of above expression in Java is 6
>
> I don't think we need to do anything here.  First, code should
> self-documenting and easy to understand.  When I first looked at the
> statement I couldn't figure out what the intent was, and so I'm not
> surprised that the compiler also has a hard time deciding what to do.  So,
> I would suggest that rather than introduce complexities in to the parser,
> the programmer should simply write what they mean.
>
> If the programmer wants 6 as an answer, then code
> a = 1; a += a; a+= 4
>
> If the programmer wants 10 as an answer, then code
> a = 1; a +=4; a += a
>
> I tried the example in C++ and the result with the gcc compiler is 10 so
> I'm perfectly happy to define the behavior that multiple in-place operators
> are evaluated in a specific evaluation order which happens to be "right to
> left".
>
> Cheers,
> Rik
>

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Daniel Sebald
In reply to this post by Rik-4
On 06/06/2014 01:12 PM, Rik wrote:

> On 06/06/2014 08:06 AM, [hidden email] wrote:
>> Message: 5
>> Date: Fri, 6 Jun 2014 17:20:08 +0330
>> From: Hossein Sajjadi<[hidden email]>
>> To: [hidden email]
>> Subject: chaining compound assignment results in undefined behavior
>> Message-ID:
>> <[hidden email]>
>> Content-Type: text/plain; charset=UTF-8
>>
>> Hi
>>
>> There is a problem with chaining compound assignment.
>> For example the expression a=1;a+=a+=4 will result 10.
>> I think such a behavior is borrowed from C language but this behavior
>> is known as "undefined behavior".
>>   This issue have been resolven in Java.
>>   Java language guarantees that the operands of operators appear
>> to be evaluated in a specific evaluation order , namely, from left to
>> right. ?15.7
>> Other specifications about evaluation of expressions are in
>> "The Java? Language Specification"
>>
>>   also this approach is followed by c# language
>>   so result of above expression in Java is 6
>
> I don't think we need to do anything here.  First, code should
> self-documenting and easy to understand.  When I first looked at the
> statement I couldn't figure out what the intent was, and so I'm not
> surprised that the compiler also has a hard time deciding what to do.  So,
> I would suggest that rather than introduce complexities in to the parser,
> the programmer should simply write what they mean.
>
> If the programmer wants 6 as an answer, then code
> a = 1; a += a; a+= 4
>
> If the programmer wants 10 as an answer, then code
> a = 1; a +=4; a += a
>
> I tried the example in C++ and the result with the gcc compiler is 10 so
> I'm perfectly happy to define the behavior that multiple in-place operators
> are evaluated in a specific evaluation order which happens to be "right to
> left".

Also, I'm not so sure the right-to-left evaluation makes sense because
this is both an operation and assignment in one.  Explicitly applying
associativity using parentheses, think about:

octave-cli:7> a=1;a+=(a+=4)
a =  10

which makes sense, I guess.  The parentheses are evaluated with an
inherent assignment and serves as an input to the proceeding add/assign.
  But the following makes no sense:

octave-cli:8> a=1;(a+=a)+=4
parse error:

   invalid left hand side of assignment

>>> a=1;(a+=a)+=4

and the parser gives up, appropriately.  The first parentheses is an
evaluation (i.e., quantity) and the add/assign can only apply to a
variable, not a quantity.

Dan


Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Seyyed Hossein Sajjadi
I evaluated the expression on some languages:

languages that the expression will result 6 are:
Java , C# ,bash , julia , Ruby , javascript

languages that the expression will result 10 are:
C++ ,C , Objective-C , D , Octave, Perl , PHP , AWK , batch , Windows Powershell

with regard to C-C++ standard such an expression results in undefined behavior

I accept that "the result is always going to be 10 in Octave and there
is no concept of "undefined behaviour" in the Octave language"(Jordi
Gutiérrez Hermoso as of probably core developer of the interpreter
said), but I can say that developers of  languages such as PHP, perl,
octave ,.. did not take into account undefined behavior in c/c++ and
based their interpreter/compiler on wrong assumptions ,in the other
words result of c++ expression is wrong and octave developers simulate
the wrong behavior.
Jordi sayid "There is no Matlab or Octave standard" so anything is
possible in Octave.


On 6/9/14, Daniel J Sebald <[hidden email]> wrote:

> On 06/06/2014 01:12 PM, Rik wrote:
>> On 06/06/2014 08:06 AM, [hidden email] wrote:
>>> Message: 5
>>> Date: Fri, 6 Jun 2014 17:20:08 +0330
>>> From: Hossein Sajjadi<[hidden email]>
>>> To: [hidden email]
>>> Subject: chaining compound assignment results in undefined behavior
>>> Message-ID:
>>> <[hidden email]>
>>> Content-Type: text/plain; charset=UTF-8
>>>
>>> Hi
>>>
>>> There is a problem with chaining compound assignment.
>>> For example the expression a=1;a+=a+=4 will result 10.
>>> I think such a behavior is borrowed from C language but this behavior
>>> is known as "undefined behavior".
>>>   This issue have been resolven in Java.
>>>   Java language guarantees that the operands of operators appear
>>> to be evaluated in a specific evaluation order , namely, from left to
>>> right. ?15.7
>>> Other specifications about evaluation of expressions are in
>>> "The Java? Language Specification"
>>>
>>>   also this approach is followed by c# language
>>>   so result of above expression in Java is 6
>>
>> I don't think we need to do anything here.  First, code should
>> self-documenting and easy to understand.  When I first looked at the
>> statement I couldn't figure out what the intent was, and so I'm not
>> surprised that the compiler also has a hard time deciding what to do.
>> So,
>> I would suggest that rather than introduce complexities in to the parser,
>> the programmer should simply write what they mean.
>>
>> If the programmer wants 6 as an answer, then code
>> a = 1; a += a; a+= 4
>>
>> If the programmer wants 10 as an answer, then code
>> a = 1; a +=4; a += a
>>
>> I tried the example in C++ and the result with the gcc compiler is 10 so
>> I'm perfectly happy to define the behavior that multiple in-place
>> operators
>> are evaluated in a specific evaluation order which happens to be "right
>> to
>> left".
>
> Also, I'm not so sure the right-to-left evaluation makes sense because
> this is both an operation and assignment in one.  Explicitly applying
> associativity using parentheses, think about:
>
> octave-cli:7> a=1;a+=(a+=4)
> a =  10
>
> which makes sense, I guess.  The parentheses are evaluated with an
> inherent assignment and serves as an input to the proceeding add/assign.
>   But the following makes no sense:
>
> octave-cli:8> a=1;(a+=a)+=4
> parse error:
>
>    invalid left hand side of assignment
>
>>>> a=1;(a+=a)+=4
>
> and the parser gives up, appropriately.  The first parentheses is an
> evaluation (i.e., quantity) and the add/assign can only apply to a
> variable, not a quantity.
>
> Dan
>
>

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Seyyed Hossein Sajjadi
"Except  where  noted,  evaluations  of  operands  of  individual
operators  and  of  subexpressions  of  individual  expressions are
unsequenced.
Given any two evaluations A and B, if A is sequenced before B, then
the execution of A shall precede the execution of B. If A is not
sequenced before      B  and B  is not sequenced before  A, then A and
B  are  unsequenced. [ Note:  The execution of unsequenced evaluations
 can  overlap. — end  note] §1.9"(ISO International Standard ISO/IEC
14882:2011(E) -- Programming Language C++)
For example in expression a + b the standard imposes no requirement if
a evaluated first or b.
so evaluation of expression a=1;a+=a+=4 due to above and other
specifications in §1.9 of standard.

But "the Java programming language guarantees that the operands of
operators appear
to be evaluated in a specific evaluation order , namely, from left to
right.§1.5"(The Java® Language Specification Java SE 8 Edition)
so a=1;a+=a+=4; in Java programming language well defined.

Octave has no standard, so evaluation of expressions can be in any order

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Mike Miller
I think you've gotten a few very good and clear answers to your
questions, do you still have any unanswered questions about this
topic?

On Mon, Jun 9, 2014 at 21:47:32 +0330, Hossein Sajjadi wrote:
> "Except  where  noted,  evaluations  of  operands
> [...]
> For example in expression a + b the standard imposes no requirement if
> a evaluated first or b.
> so evaluation of expression a=1;a+=a+=4 due to above and other
> specifications in §1.9 of standard.

I think everyone is clear on your point about the C and C++ languages,
no need to quote the language specification.

> But "the Java programming language guarantees that the operands of
> operators appear
> to be evaluated in a specific evaluation order , namely, from left to
> right.§1.5"(The Java® Language Specification Java SE 8 Edition)
> so a=1;a+=a+=4; in Java programming language well defined.

Again, I think everyone also understands what you are saying about the
Java language.

> Octave has no standard, so evaluation of expressions can be in any order

Not sure what you meant here. Did you mean that Octave is not adhering
to any existing language standard, and therefore we could change the
order of evaluation if we wanted to? True, we could, but we don't want
to :)

Or do you mean that Octave's lack of a language standard means that
there is no document making it clear what the correct order of
evaluation is?

As Rik said and as the manual specifically advises [1], the best
policy is to avoid such nested assignments anyway.

[1] http://www.gnu.org/software/octave/doc/interpreter/Assignment-Ops.html

--
mike

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Seyyed Hossein Sajjadi
> Not sure what you meant here. Did you mean that Octave is not adhering
> to any existing language standard, and therefore we could change the
> order of evaluation if we wanted to? True, we could, but we don't want
> to :)
I expect Octave to  adhere to its own style of evaluation but it seems
that in this special case Octave violates its own ordinary rules

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Mike Miller
On Tue, Jun 10, 2014 at 06:38:08 +0330, Hossein Sajjadi wrote:
> I expect Octave to  adhere to its own style of evaluation but it seems
> that in this special case Octave violates its own ordinary rules

That's a reasonable expectation. Can you explain what rules you think
Octave is violating?

--
mike

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Seyyed Hossein Sajjadi
accoring to the manual:
expr1 op= expr2
is evaluated as
expr1 = (expr1) op (expr2)

so the expression
a=1;
a+=(a+=4);

should be equivalent to
a=1;
a=a+(a=a+4);

but the firt expression results 10  and second results 6

in expression a+=(a+=4) this procedure should be followed if order of
evaluations to be left to right:
first "a" in LHS is evaluated , so its value (1) will be stored to be
used by the rest of the expression
In RHS "a" is evaluated and its value (1) is sums with 4 reults 5
5 sums with "a" in LHS then result will be 6

but Octave's behavior is similar to c++ that takes the address of LHS
variable first and then evaluate RHS expression

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

bpabbott
Administrator

On Jun 10, 2014, at 12:39 AM, Hossein Sajjadi <[hidden email]> wrote:

> accoring to the manual:
> expr1 op= expr2
> is evaluated as
> expr1 = (expr1) op (expr2)
>
> so the expression
> a=1;
> a+=(a+=4);
>
> should be equivalent to
> a=1;
> a=a+(a=a+4);
>
> but the firt expression results 10  and second results 6

Both evaluate to 10 for me.

a=1;a+=(a+=4)
a =  10
a=1;a+=(a=a+4)
a =  10

Ben

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Seyyed Hossein Sajjadi
> Both evaluate to 10 for me.
>
> a=1;a+=(a+=4)
> a =  10
> a=1;a+=(a=a+4)
> a =  10
>
> Ben
>
Please compare these two expressions:

a=1;a+=(a=a+4)

a=1;a=a+(a=a+4)

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Mike Miller
In reply to this post by Seyyed Hossein Sajjadi
On Tue, Jun 10, 2014 at 08:09:40 +0330, Hossein Sajjadi wrote:

> accoring to the manual:
> expr1 op= expr2
> is evaluated as
> expr1 = (expr1) op (expr2)
>
> so the expression
> a=1;
> a+=(a+=4);
>
> should be equivalent to
> a=1;
> a=a+(a=a+4);
>
> but the firt expression results 10  and second results 6

Ok, I understand. I think the best thing you can do to resolve this is
to report a bug [1] requesting that the manual be updated to describe
this behavior of assignment operators more clearly. To be clear, there
is no undefined behavior here, it's just that OP= means that the
left-hand side of the assignment is evaluated when the assignment is
made. So the simple equivalence described in the manual is not correct
if EXPR2 modifies EXPR1 as a side effect.

[1] https://savannah.gnu.org/bugs/?func=additem&group=octave

Thanks,

--
mike

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Seyyed Hossein Sajjadi
> Ok, I understand. I think the best thing you can do to resolve this is
> to report a bug [1] requesting that the manual be updated to describe
> this behavior of assignment operators more clearly. To be clear, there
> is no undefined behavior here, it's just that OP= means that the
> left-hand side of the assignment is evaluated when the assignment is
> made. So the simple equivalence described in the manual is not correct
> if EXPR2 modifies EXPR1 as a side effect.
>
> [1] https://savannah.gnu.org/bugs/?func=additem&group=octave
>
> Thanks,
>
> --
> mike
>

By introduction of compound assignment in Octave it is intended to be
an improvement regards to Matlab but this introduce other issuses such
as violation of referential transparency.
I suggest two approach:
1. Do not allow compound assignment to be chained (  VB.NET , PACAL ,
Python, Go)
2. compound assignment can be chained but like what Java, C# , julia ,.. do.
I prefer second approach but it seems that you say correctly what you say:

"We can change the order of evaluation if we want to, but we don't want to."

I think the rules, if there are any rules, should be updated.
Thank you very much,

Hossein

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Mike Miller
On Tue, Jun 10, 2014 at 16:42:25 +0330, Hossein Sajjadi wrote:
> By introduction of compound assignment in Octave it is intended to be
> an improvement regards to Matlab but this introduce other issuses such
> as violation of referential transparency.

Well, an assignment or any other expression that has side effects is
not referentially transparent, that's the way it is. Octave is not a
functional language.

> I think the rules, if there are any rules, should be updated.

There are rules, as I think it's been made clear here. It also seems
clear from the responses you have gotten that many others find the
current behavior more correct, so I think you are in the minority.

Thanks for the discussion,

--
mike

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Seyyed Hossein Sajjadi
> Well, an assignment or any other expression that has side effects is
> not referentially transparent, that's the way it is. Octave is not a
> functional language.
>

Yes, Octave is not a functional programming language, but as an
imperative language it is necessary to guarantee the order of
evaluation or define sequence point as c++ do. Also as a language
specially designed for mathematical computations such a behavior is no
acceptable.
Simply changing the manual and notice the user about behavior of
chaining without any theroretical backend(order of evaluation or
sequence point) does not resolve the issue.

> There are rules, as I think it's been made clear here. It also seems
> clear from the responses you have gotten that many others find the
> current behavior more correct, so I think you are in the minority.

It seems that I should do some sort of diplomacy or negotiation or
lobbying to gather more votes to prove my assertion. :)) Besides, I
think "more correct" is not accptable when we talk about such a
problem. This assertion is correct or is not correct.

Thanks,

Hossein

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Michael Goffioul
On Tue, Jun 10, 2014 at 11:58 AM, Hossein Sajjadi <[hidden email]> wrote:
> Well, an assignment or any other expression that has side effects is
> not referentially transparent, that's the way it is. Octave is not a
> functional language.
>

Yes, Octave is not a functional programming language, but as an
imperative language it is necessary to guarantee the order of
evaluation or define sequence point as c++ do. Also as a language
specially designed for mathematical computations such a behavior is no
acceptable.
Simply changing the manual and notice the user about behavior of
chaining without any theroretical backend(order of evaluation or
sequence point) does not resolve the issue.

I don't understand, why would it be wrong to have the manual say:

expr1 OP= expr2

is equivalent to

tmp = (expr2)
expr1 = (expr1) OP tmp

AFAK, this is what octave is doing. Is there a theory somewhere that states the above is plain wrong?

Michael.

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Mike Miller
In reply to this post by Seyyed Hossein Sajjadi
On Tue, Jun 10, 2014 at 19:28:18 +0330, Hossein Sajjadi wrote:
> Yes, Octave is not a functional programming language, but as an
> imperative language it is necessary to guarantee the order of
> evaluation or define sequence point as c++ do. Also as a language
> specially designed for mathematical computations such a behavior is no
> acceptable.

As has been said multiple times now, there is a guaranteed order of
evaluation, so no problem there.

> Simply changing the manual and notice the user about behavior of
> chaining without any theroretical backend(order of evaluation or
> sequence point) does not resolve the issue.

So if the manual said something like the following

  An expression of the form

    EXPR1 OP= EXPR2

  is evaluated as

    temp = EXPR2; EXPR1 = (EXPR1) OP temp

  where 'temp' is a placeholder temporary value storing the result of
evaluating EXPR2.

that does not resolve the issue? That seems pretty simple and clear.
And this is what I believe everyone understands as the current and
correct behavior of such expressions in Octave. Assignment is
evaluated right-to-left, as the manual states, EXPR2 is evaluated
first, and then combined with EXPR1.

> It seems that I should do some sort of diplomacy or negotiation or
> lobbying to gather more votes to prove my assertion. :)) Besides, I
> think "more correct" is not accptable when we talk about such a
> problem. This assertion is correct or is not correct.

Then Octave is correct with respect to the substitution shown above.
Feel free to lobby for a change as you wish.

--
mike

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Seyyed Hossein Sajjadi
In reply to this post by Michael Goffioul
> I don't understand, why would it be wrong to have the manual say:
>
> expr1 OP= expr2
>
> is equivalent to
>
> tmp = (expr2)
> expr1 = (expr1) OP tmp
>
> AFAK, this is what octave is doing. Is there a theory somewhere that states
> the above is plain wrong?
>
> Michael.
>
Associativity of assignment operator in many programming languages is
right to left but evaluation of expression if is guaranteed to be left
to right such an expression is no correct. Simply you first evaluate
RHS then LFS.

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Seyyed Hossein Sajjadi
In reply to this post by Mike Miller
> So if the manual said something like the following
>
>   An expression of the form
>
>     EXPR1 OP= EXPR2
>
>   is evaluated as
>
>     temp = EXPR2; EXPR1 = (EXPR1) OP temp
>
>   where 'temp' is a placeholder temporary value storing the result of
> evaluating EXPR2.
>
> that does not resolve the issue? That seems pretty simple and clear.
> And this is what I believe everyone understands as the current and
> correct behavior of such expressions in Octave. Assignment is
> evaluated right-to-left, as the manual states, EXPR2 is evaluated
> first, and then combined with EXPR1.
>
 As I say to Michael Goffioul this expression is not correct ,becuase
order of evaluation that where guaranteed to be left to right is
violated
Hossein

Reply | Threaded
Open this post in threaded view
|

Re: undefined compound chaining behavior

Michael Godfrey
Best to end this discussion with a quote from one of
the authors of C:  He was asked to explain the correct
interpretation of a compound expression. His answer
was: "ask the compiler."



1234