'''
This code was written in 15-113 lecture.
It is only for demonstrational purposes, and may contain
dubious style and even an occasional bug.
'''

# It looks like Python uses singletons for all integers,
# so for integers, if (x == y) then (x is y):
x = 256
y = 256
print(x is y) # True

# And...
x = 255
y = 255
x += 1
y += 1
print(x is y) # True, as expected

# But...
x = 256
y = 256
x += 1
y += 1
print(x is y) # False, because Python does NOT reuse integers
              # that are larger than 256!

# But...
x = 256 + 1
y = 256 + 1
print(x is y) # True, because Python performed the (256 + 1)
              # at compile time, and Python reuses compile-time constants
              # even if they are larger than 256.

x = 256**20 + 1
y = 256**20 + 1
print(x is y) # False, because Python only does this sharing up to some
              # point, after which even compile-time constants result
              # in unshared integer objects (oh my).

# This behavior is similar with strings.

s = 'ab'
t = 'a' + 'b'
print(s is t) # True, because Python added ('a' + 'b') to get 'ab'
              # at compile-time, and shared the constant 'ab'

s = 'ab'
t = 'a'
t += 'b'
print(s is t) # False, because Python added ('a' + 'b') at runtime,
              # when it does NOT share the constants

# Moral of the story: do not use "is" with immutables, since
# the result is very hard to predict.