#
```"""
# Mutable objects include variables, dictionaries and lists:
#           x, {}, 
# Immutable objects include numbers, strings, and tuples:
#           3.14, 'asdf', (0, 1)

# The number of copies made of each mutable object is determined lexically.

#   We want
#     x = 7
#     A = 2 * [x]
#   to behave the same as
#     x = 7
#     A = [x, x]
# because there is only one x in A = 2 * [x]. Similarly for A = B = x.

print 'One object.'
watchall1(['a = 7', 'x = 2 * [a]'])
watchall1(['b = 7', 'x = y = b'])
prog = [
'class trivial:',
'    pass',
'x = 2 * [trivial()]'
]

watchall1(prog)
print

print 'Two objects.'
watchall1(['a = 7', 'x = [a, a]'])
watchall1(['x = 7', 'y = 8'])
prog  = [
'class trivial:',
'    pass',
'x = [trivial(), trivial()]'
]
watchall(prog)
print

# The implementation chooses how many copies are made of immutable objects.

watchall1('xx = [(0,1), (0,1)]')
watchall1('xx = [3.14, 3.14]')
print

# Assignment gives the object on the left hand side the value of the object
# on the right hand side.

watchall(['a = 7', 'x = a'])
print

# An assignment to a sub-object of a mutable object does not change the
# mutable object (it changes its _content_). The id numbers assigned while
# executing the following two lines need not be the same, but they are on my
# system.

watchall1('x = [3.14, 99]')
watchall1(['x = [3.14, 99]', 'x = 98'])
print

# An assignment to a sub-object of a mutable object is allowed. In the
# example, I am not changing the immutable objects, I am replacing them.

prog = [
"x = [[], 'asdf', (0,1)]",
"for i in range(3):",
"    x[i] = 2*i"
]
print prog
watchall1(prog)
print

# An assignment to a sub-object of an immutable object is forbidden.

x = (3.14, 99)
print x
try:
x = 2.718
except Exception, y:
print str(y)
print

# Assignment to a sub-object of a mutable sub-object of an immutable object
# is allowed
#   x = (,)
#   x = 1

watchall1(['x = ([0, 1], 3)', 'x = 77'])
# ``` 