= #JxnPortable\docs\programmer_examples\demos\AugmentedAssignment_Demo.jxn ...

! The following quirk with augmented assignment may occur if more than one variables refer to the same instance.
! - Two variables a and b refering to the same single instance comes from the assignment b = a.
! - After the assigmnent isSame( b, a ) returns true and any modification on b also changes a.
! - If b is intended to refer to an independant copy of a, use e.g. b = a * 1
!   or b = a.cloneThis() if class A implements the method or b = @A(a) if the copy constructor exists.

! *** OLD behaviour:
! Augmented assignment behaves differently depending on whether the instance refered to by the variable assigned to is immutable or not
! - in case of an immutable instance augmented assignment to a variable always assigns a new instance
! - in case of a mutable instance augmented assignment to a variable may assign a new instance or modify the instance refered to by the variable
!   => the possible side effect on the instance the variable originally refers to is allowed but not garantied
! The same behaviour is observed in programming languages e.g. Python.

! *** NEW behaviour:
! jxn handles  variable_name op= expression  as a syntactical shortcut of  variable_name = variable_name op ( expression )
! and always assigns a new instance to variable_name rather than modifying the existing instance variable_name is refering to.

z = j
 = 0.0 + j 1.0 = 1.0 <) 90.0° (JxnComplexAlgebra)
isSame( z, j )  ! z refers to the same object j refers to
 = true (boolean)
z = 2z  ! assigns new instance
 = 0.0 + j 2.0 = 2.0 <) 90.0° (JxnComplexAlgebra)
isSame( z, j )  ! no more same
 = false (boolean)
j  ! not changed
 = 0.0 + j 1.0 = 1.0 <) 90.0° (JxnComplexAlgebra)

z = j
 = 0.0 + j 1.0 = 1.0 <) 90.0° (JxnComplexAlgebra)
isSame( z, j )  ! z refers to the same object j refers to
 = true (boolean)
z *= 2  ! <= NEW: j not changed, OLD: changes j
 = 0.0 + j 2.0 = 2.0 <) 90.0° (JxnComplexAlgebra)
isSame( z, j )  ! NEW: no more same, OLD: still same
 = false (boolean)
j  ! <= NEW: not changed, OLD: j changed!!
 = 0.0 + j 1.0 = 1.0 <) 90.0° (JxnComplexAlgebra)


t2 = 2 t
 = {0.0, 0.004 ... 2.0}[501] (JxnRealArrayAlgebra)
!
t2a = t2
 = {0.0, 0.004 ... 2.0}[501] (JxnRealArrayAlgebra)
isSame( t2a, t2 )
 = true (boolean)
t2a *= 5
 = {0.0, 0.02 ... 10.0}[501] (JxnRealArrayAlgebra)
t2  ! not changed
 = {0.0, 0.004 ... 2.0}[501] (JxnRealArrayAlgebra)
isSame( t2a, t2 )  ! no more same
 = false (boolean)
!
t2b = t2
 = {0.0, 0.004 ... 2.0}[501] (JxnRealArrayAlgebra)
isSame( t2b, t2 )
 = true (boolean)
t2b.mul( 5 )  ! the operator method mul modifies the left operand t2b
 = {0.0, 0.02 ... 10.0}[501] (JxnRealArrayAlgebra)
t2  ! changed
 = {0.0, 0.02 ... 10.0}[501] (JxnRealArrayAlgebra)
isSame( t2b, t2 )  ! still same
 = true (boolean)
!
isSame( t2b, t2a )
 = false (boolean)
JxnObject.equals( t2b, t2a )
 = true (boolean)


big = BIG1
 = 1 (BigIntegerAlgebra)
isSame( big, BIG1 )
 = true (boolean)
big = 2big
 = 2 (BigIntegerAlgebra)
isSame( big, BIG1 )
 = false (boolean)
BIG1
 = 1 (BigIntegerAlgebra)

big = BIG1
 = 1 (BigIntegerAlgebra)
isSame( big, BIG1 )  ! big refers to the same object BIG1 refers to
 = true (boolean)
big *= 2  ! does not change immutable BIG1
 = 2 (BigIntegerAlgebra)
isSame( big, BIG1 )  ! no more same
 = false (boolean)
BIG1  ! not changed
 = 1 (BigIntegerAlgebra)


ia = { 2, 3, 5 }
 = { 2, 3, 5 } (int[3])
ib = ia
 = { 2, 3, 5 } (int[3])
isSame( ib, ia )
 = true (boolean)
ib *= 2
 = { 4, 6, 10 } (int[3])
isSame( ib, ia )  ! no more same
 = false (boolean)
ib /= 4
? statement: overwrites { 4, 6, 10 } (int[3]), old value in $$
 = { 1.0, 1.5, 2.5 } (double[3])
ia
 = { 2, 3, 5 } (int[3])

da = ib
 = { 1.0, 1.5, 2.5 } (double[3])
db = da
 = { 1.0, 1.5, 2.5 } (double[3])
isSame( db, da )  ! db refers to the same object da refers to
 = true (boolean)
db *= 2
 = { 2.0, 3.0, 5.0 } (double[3])
isSame( db, da )  ! <= NEW: no more same, OLD: still same
 = false (boolean)
db
 = { 2.0, 3.0, 5.0 } (double[3])
da  ! <= NEW: not changed, OLD: da changed
 = { 1.0, 1.5, 2.5 } (double[3])


da = { 2.0, 3.0, 5.0 }
 = { 2.0, 3.0, 5.0 } (double[3])
da + 2
 = { 4.0, 5.0, 7.0 } (double[3])
da 2
 = { 4.0, 6.0, 10.0 } (double[3])
da da
 = { 4.0, 9.0, 25.0 } (double[3])
da  ! not changed
 = { 2.0, 3.0, 5.0 } (double[3])

ia
 = { 2, 3, 5 } (int[3])
ia + 2
 = { 4, 5, 7 } (int[3])
ia 2
 = { 4, 6, 10 } (int[3])
ia ia
 = { 4, 9, 25 } (int[3])
ia  ! not changed
 = { 2, 3, 5 } (int[3])