TensorFlow 2.0 uses eager execution by default. The result is more intuitive, object oriented and pythonic.

Nothing like a simple example to conceptualize the difference:

```
import tensorflow as tf
sum = tf.add(1, 2)
```

If we print the `sum`

result in TensorFlow 1.X, we get the operation definition in the graph and not the actual result. It is only when the operation is executed inside a session that we get the expected result:

```
# Using TensorFlow 1.X
print(sum)
# Tensor("Add:0", shape=(), dtype=int32)
with tf.Session() as sess:
print(sess.run(sum))
# 3
```

If we repeat the operation in TensorFlow 2.0, the result is as follows

```
# Using TensorFlow 2.0
print(sum)
# tf.Tensor(3, shape=(), dtype=int32)
```

Eager execution is intuitive and corresponds to the expected behavior when using Python. It also has some practical benefits. For example, it simplifies debugging as the code does not wait for the session to be executed and, potentially, fail. This allows using `print()`

to quickly inspect results for debugging.

Applications that require graphs can still use them with TensorFlow 2.0, but graphs are no longer the default behavior.