In this post of my syntactic sugar series, I want to tackle literals. Now some literals don't really require any code changes and are really just an alternative way to write the same thing, no call of code required (e.g. writing integers in hexadecimal format versus in base-10). Others, though, can be done away with entirely using some code transformations (e.g. strings). Regardless, this blog post is somewhat academic and doesn't really help simplify the semantics of Python.

## Numeric literals

You can break the numeric literals in Python down into integers, floats, and complex numbers. For integers and floats, the various representations directly translate to a base representation, e.g. integers can be written in binary, octal, hex, and base-10 and they are all equivalent.

Complex numbers do have a slight translation, though. If you write `4+3j` you can reconstruct it with `complex(4, 3)`.  And if you leave off the real part of the complex number then it simply defaults to 0: `3j` becomes `complex(0, 3)`.

## `True` and `False`

The boolean keywords/literals can be created by calling `bool()`, i.e. `bool(1)` for `True` and `bool(0)` for `False`. The one interesting thing to note is you can't fully replicate `bool()` in pure Python code as there eventually needs to be a break as to what represents true and false as you can't keep calling `__bool__()` which is expected to itself return `True` or `False`.

## `None`

Did you know that all Python functions return `None` if you don't explicitly return something? This is because there's no concept of a "void" function like in typed languages such as C. As such, everything in Python has to return something, and that something happens to be `None`. Thanks to this, it's easy to replace `None` as a function call.

So now any place you would write `None` you can write `_None()`.

## Bytes

Bytes literals, thanks to relying on ASCII, translate to lists of integers passed to `bytes()`: `b"ABC"` becomes `bytes([65, 66, 67])`.

## Strings

When you think about it, strings are just bytes with special meaning. And thanks to Unicode we have a shared understanding of what various bytes represent when it comes to strings. That means we can write strings out as those equivalent bytes and then decode them into strings. Using UTF-8 as an example, we can translate `"ABC"` into `bytes([65, 66, 67]).decode("utf-8")`.