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.
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.
For floats, they are effectively integers that have been divided by some power-of-ten number. For example,
3.14 is the same as
Complex numbers also have a slight translation. 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:
The boolean keywords/literals can be created by calling
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
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
Bytes literals, thanks to relying on ASCII, translate to lists of integers passed to
bytes([65, 66, 67]).
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
bytes([65, 66, 67]).decode("utf-8").