1. "Nasty" bug
- Posted by Jd63 Feb 24, 2019
- 2176 views
I came across a couple of posts on the sourceforge mailing list which refers to a bug in 3.1.1 (which was apparently also present in 4.06), but haven't been able to find the code which generated it. Here are the posts :
Wow. You found a really nasty bug in Euphoria 3.1.1. I tried this on 4.0.6 on Linux and it behaves the same way both interpreted and compiled! I tried tracing through this program with trace(1). The global gets updated in the sub routine but then it reverts to its old value when it comes out.
Using gdb on the compiled version is what I would try next.
Shawn Pringle
On 9 June 2016 at 16:55, john Doe <graemeburke@...> wrote:
I 've been using EU for over 20 years now, it's still my go-to work horse
for just about anything, and to be honest, I usually still use 3.1.1 mainly
cos Rob's stuff is always rock solid. However....
Can anyone tell me how this isn't a serious critter right in the middle of
EU's sequence handling?
Behavior is the same in exe/exw/exwc 311 and eui 405.
Been beating my head against a brick wall for 2 days and was stunned at
what I found... more amazed that I've never noticed it before in 10 jillion
hours of using eu.
comments?
Graeme Burke
Anyone remember this? it was posted in 2016. It would be nice to know how to avoid this bug...
2. Re: "Nasty" bug
- Posted by irv Feb 24, 2019
- 2205 views
Perhaps:
https://sourceforge.net/p/rapideuphoria/mailman/rapideuphoria-develop/?viewmonth=201606
It's called lost_ball.ex, and is an attachment on the second message on that page.
Too big to post here.
Good luck cleaning it up so as to prove or disprove the error.
3. Re: "Nasty" bug
- Posted by irv Feb 24, 2019
- 2172 views
By removing the extraneous stuff, this shows the bug:
with trace trace(1) sequence our_place = {{0}, {{0,0,0,0,0}} } constant ball = 88 function you(integer thing) integer score = rand(5) our_place[2][1][score] = thing puts(1,"You ") ? our_place return score end function puts(1,"Me 1 ") ? our_place[2] our_place[1][1] += you( ball ) -- here is problem. --integer x = you(ball) -- separating the steps works --our_place[1][1] += x puts(1,"Me 2 ") ? our_place[2] puts(1,"Done")
4. Re: "Nasty" bug
- Posted by lesterb Feb 24, 2019
- 2095 views
Hi Irv,
I had a look at this and discovered 2 things...
1. Phix gets it right.
2. There's a note in the 3.1.1 documentation about exactly this case. It reads..
The expressions are evaluated, and any subscripting is performed, from left to right. It is possible to have function calls in the right-hand-side expression, or in any of the left-hand-side expressions. If a function call has the side-effect of modifying the lhs_var, it is not defined whether those changes will appear in the final value of the lhs_var, once the assignment has been completed. To be sure about what is going to happen, perform the function call in a separate statement, i.e. do not try to modify the lhs_var in two different ways in the same statement. Where there are no left-hand-side subscripts, you can always assume that the final value of the lhs_var will be the value of rhs_expr, regardless of any side-effects that may have changed lhs_var.
Les
5. Re: "Nasty" bug
- Posted by irv Feb 24, 2019
- 2111 views
Thanks. It is still there in 4.1b2
I'm not sure whether this is a bug or a "feature". Most programming languages have lots of "features" like this:)
Anyway, for some reason, in all the coding I have done, the problem has never presented itself before.
7. Re: "Nasty" bug
- Posted by Jd63 Feb 25, 2019
- 2058 views
Thanks a lot for the feedback guys, interesting. I've never come across this scenario myself, but good to be reminded that it exists.
8. Re: "Nasty" bug
- Posted by ghaberek (admin) Feb 25, 2019
- 2037 views
Anyway, for some reason, in all the coding I have done, the problem has never presented itself before.
Same here. I'm not sure if this counts as a bug, or simply a side-effect of the logic of the code parser. There's a logic error in the code parser because there's a logic error in the code that was written. Euphoria doesn't, for better or worse, tell the user what "good" code should be. This is one of the rare examples where writing bad code leads to weird side-effects and undefined behavior.
If you're looking for a solution to avoiding this problem, I have but one word: abstraction. If you need to store data in memory and manipulate it elsewhere, do yourself a favor and write a library with all of the functions required to manage the data without having to touch the variable(s) that holds the data directly.
This problem would have continued unnoticed had the original author of the code written it in such a way as to conceptualize the actions in code first. I have to imagine that the code posted was merely an example to demonstrate the problem, but that worries me even more as to what the author's original code looks like!
Overall, I don't if this something that should be fixed or not. On one hand, yes it's a weird logic error. But on the other, the expected behavior is undefined. If we can detect the problem in the parser, then maybe we should just issue a warning, like Warning { side_effect }: lhs_var will not be updated due to side-effect in function func_name.
-Greg
9. Re: "Nasty" bug
- Posted by irv Feb 25, 2019
- 2063 views
This problem would have continued unnoticed had the original author of the code written it in such a way as to conceptualize the actions in code first. I have to imagine that the code posted was merely an example to demonstrate the problem, but that worries me even more as to what the author's original code looks like!
The original code was lost_ball.ex, linked above. It appears to be a Eu translation from some other language, perhaps basic, which of course makes it messy. Probably just an accident that the one line happened to uncover a problem. The code I show was the original pared down to the minimum to show the error.
There's an additional "gotcha" involved. Some experimenting I did:
sequence our_place = {{0}, {{0,0,0,0,0}} } -- fails sequence our_place = {0,{{0,0,0,0,0}} -- make first an atom, our_place[1] += you( ball ) -- and it works
If the first element of the sequence is an atom, the problem doesn't occur.
10. Re: "Nasty" bug
- Posted by _tom (admin) Feb 25, 2019
- 2099 views
Another variation on "dropping the ball."
oE works "as expected"; Phix gives a different result when index is one (1).
constant ball = 88 sequence blank = { 0,0,0,0,0 } sequence lst for index = 1 to 5 do puts(1, "\n----------------------------------------- no assignment \n" ) lst = blank printf(1,"Outside lst value %g %g %g %g %g \n\n", lst ) ? set(ball, index) printf(1,"Outside lst value %g %g %g %g %g \n", lst ) puts(1, "\n----------------------------------------- with += assignment\n" ) lst = blank printf(1,"Outside lst value %g %g %g %g %g \n\n", lst ) lst[1] += set( ball, index) printf(1,"Outside lst value %g %g %g %g %g \n\n", lst ) puts(1, "\n----------------------------------------- with staged assignment\n" ) lst = blank printf(1,"Outside lst value %g %g %g %g %g \n\n", lst ) integer NDX = set(ball, index) lst[1] += NDX printf(1,"Outside lst value %g %g %g %g %g \n\n", lst ) puts(1, "\n-----------------------------------------\n" ) ? gets(0) -- pause to review results clear_screen() end for function set(integer thing, integer index) lst[index] = thing printf(1," Inside set argument %g\n", thing ) printf(1," Inside set index %d\n", index ) printf(1," Inside set value %g %g %g %g %g \n", lst ) return index end function puts(1,"\n\n Done")
_tom
11. Re: "Nasty" bug
- Posted by petelomax Feb 26, 2019
- 2010 views
oE works "as expected"; Phix gives a different result when index is one (1).
lst[1] += set( ball, index)
If you replace that with
lst[1] = lst[1] + set( ball, index)
Then eui and phix behave the same.
I think I have a slight preference for "lst[1] +=" always behaving exactly the same as "lst[1] = lst[1] +", and hence have no plans to change anything.
Pete
12. Re: "Nasty" bug
- Posted by _tom (admin) Feb 28, 2019
- 1824 views
I do not have a simple way to document the failure of oE for this "Nasty" bug.
This works. So the trap is set.
-- Version 1 constant ball = 88 sequence our_place = { 0, {0,0,0,0,0} } function you(integer thing) integer score = rand(5) our_place[2][score] = thing printf(1, "__________________________ score %d \n", score ) puts(1, "Inside " ) ? our_place return score end function for i=1 to 5 do our_place[1] += you( ball ) -- OK puts(1, "Outside ") ? our_place end for puts(1,"Done")
Increasing the nesting of the sequence results in failure.
-- Version 2 constant ball = 88 sequence our_place = { {0}, {{0,0,0,0,0}} } -- increased nesting function you(integer thing) integer score = rand(5) our_place[2][1][score] = thing printf(1, "__________________________ score %d \n", score ) puts(1, "Inside " ) ? our_place return score end function for i=1 to 5 do our_place[1][1] += you( ball ) -- eui euc FAILING puts(1, "Outside ") ? our_place end for puts(1,"Done")
There is a fix
-- Version 3 constant ball = 88 sequence our_place = { {0}, {{0,0,0,0,0}} } -- increased nesting function you(integer thing) integer score = rand(5) our_place[2][1][score] = thing printf(1, "__________________________ score %d \n", score ) puts(1, "Inside " ) ? our_place return score end function for i=1 to 5 do atom tmp = you(ball) --eui euc requires this fix our_place[1][1] += tmp puts(1, "Outside ") ? our_place end for puts(1,"Done")
- Phix works all of the time
- oE does not work uniformly
avoid functions that have side-effects!
_tom
13. Re: "Nasty" bug
- Posted by petelomax Mar 01, 2019
- 1878 views
I do not have a simple way to document the failure of oE for this "Nasty" bug.
See the italic quote in #4, and the technicalia drop-down on http://phix.x10.mx/docs/html/seqformation.htm
It is also mentioned on http://phix.x10.mx/docs/html/multiassign.htm in the "Update" of "How NOT to use multiple assignment".