BBC BASIC
« Care with compound assignment »

Welcome Guest. Please Login or Register.
Jan 20th, 2018, 4:22pm


Cross-platform BBC BASIC (Win32, Linux x86, Android, Mac OS-X, Raspberry Pi)

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Care with compound assignment  (Read 391 times)
Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Care with compound assignment
« Thread started on: Jul 18th, 2017, 9:24pm »

BBC BASIC supports compound assignment operators such as +=. It is usual to explain these by asserting that these operations are equivalent:

Code:
      a += b 

and

Code:
      a = a + b 

and they usually are, but there are exceptions. Consider the following program:

Code:
      x = 0
      x += FNf
      PRINT x
      END

      DEF FNf
      x += 10
      = 1 

When run it prints 11. Now convert it as follows:

Code:
      x = 0
      x = x + FNf
      PRINT x
      END

      DEF FNf
      x += 10
      = 1 

Now it prints 1. So in this case the compound assignment isn't equivalent to the expanded version! You should be able to work out why.

I have confirmed that these same results are obtained in Acorn's BASIC V, BBC BASIC for Windows and BBC BASIC for SDL 2.0.

My thanks are due to Raymond Chen who raised this issue in his Microsoft blog.

Richard.
User IP Logged

DDRM
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 29
xx Re: Care with compound assignment
« Reply #1 on: Jul 19th, 2017, 08:20am »

Hi Richard,

Hmm, interesting! And this:
Code:
    x = 0
      x = FNf+x
      PRINT x
      END

      DEF FNf
      x += 10
      = 1
 
returns 11 again.

So in your second case, the x (which is still 0) is analysed before FNf changes it to 10, and then the result of FNf (i.e. 1) is added, and the sum (1) is assigned to x. In my version, the value of x has already been changed to 10 in the function before it is added.

So in the compound form the addition occurs last, and uses the value of x that is true at that time, rather than at the beginning of the statement?

If I understand Raymond Chen's blog correctly (quite likely not the case!) that suggests that BBC BASIC in it's various forms has right to left evaluation of these compound functions, unlike the C# he is talking about? Whether that's a good or a bad thing appears to be a moot point, but it's useful to be aware of it!

Is another take-home message that you should use local variables inside functions or be very careful about what you are doing? :-)

Best wishes,

D
User IP Logged

michael
Full Member
ImageImageImage


member is offline

Avatar




PM


Posts: 141
xx Re: Care with compound assignment
« Reply #2 on: Jul 19th, 2017, 08:40am »

this should fix the issue.
Code:
      x = 0
      x = x + FNf
      PRINT x
      END

      DEF FNf
      x += 10
      = 1+x
 

prints 11

OR to make it a bit more compact:

Code:
     
      x = 0
      x = FNf
      x = FNf
      PRINT x
      END

      DEF FNf
      x += 10
      = 1+x
 


Even with the issue, this is a fascinating way of using a FN if a person were to use global variables.
prints 22

Do I win?
« Last Edit: Jul 19th, 2017, 08:47am by michael » User IP Logged

I like reinventing the wheel, but for now I will work on tools for D3D
Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Care with compound assignment
« Reply #3 on: Jul 19th, 2017, 11:40am »

on Jul 19th, 2017, 08:40am, michael wrote:
this should fix the issue.

There's nothing to "fix" since BB4W and BBCSDL are working entirely correctly! I deliberately stated that Acorn's BASIC V worked the same way, as confirmation of that.

Quote:
Even with the issue, this is a fascinating way of using a FN if a person were to use global variables.

Of course one should ideally not modify global variables in a function, so the issue wouldn't arise if good practice was adhered to.

Richard.
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Care with compound assignment
« Reply #4 on: Jul 19th, 2017, 11:57am »

on Jul 19th, 2017, 08:20am, DDRM wrote:
If I understand Raymond Chen's blog correctly (quite likely not the case!) that suggests that BBC BASIC in it's various forms has right to left evaluation of these compound functions

Erm, BBC BASIC is an interpreted language; 'right to left' evaluation would be difficult and messy to achieve! No, BBC BASIC evaluates left-to-right as do the vast majority of programming languages. Indeed wasn't Raymond's point that people expect that, even if only subconsciously, so whilst it might seem superficially 'wrong' changing it would cause far more confusion than it would solve.

BBC BASIC behaves exactly as you would expect it to, given left-to-right evaluation and a na´ve understanding of how an interpreter works (because that's exactly how it does work!). The reason for my post wasn't to suggest that anything 'surprising' happens - it doesn't - but that the simplistic description of 'a += b' as being equivalent to 'a = a + b' isn't always correct.

Richard.
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Care with compound assignment
« Reply #5 on: Jul 19th, 2017, 4:59pm »

on Jul 19th, 2017, 11:57am, Richard Russell wrote:
BBC BASIC behaves exactly as you would expect it to, given left-to-right evaluation

If anybody is unsure about that, here is a breakdown of exactly what happens internally in each case:

Code:
      *float 80

      REM (1) x = x + FNf
      x = 0
      address_of_x = ^x : REM Left hand side of assignment
      value_of_x = x
      x = x + 10        : REM Side-effect of FNf
      value_of_FNf = 1
      |address_of_x = value_of_x + value_of_FNf
      PRINT x

      REM (2) x += FNf
      x = 0
      address_of_x = ^x : REM Left hand side of assignment
      x = x + 10        : REM Side-effect of FNf
      value_of_FNf = 1
      |address_of_x = |address_of_x + value_of_FNf
      PRINT x 

Richard.
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

Donate $6.99 for 50,000 Ad-Free Pageviews!


This forum powered for FREE by Conforums ©
Sign up for your own Free Message Board today!
Terms of Service | Privacy Policy | Conforums Support | Parental Controls