I’m curious about the history of the pass statement. I know the blurb It is useful as a placeholder when a statement is required syntactically.
Was it introduced because it was too hard to implement Python without it, or did early Python developers think it was preferrable to allowing blank statements in the source code?
As far as I can imagine, it doesn’t help implement Python. It means that the parser goes from the rule “a block contains zero or more indented lines” to the rule “a block contains one or more indented lines” which isn’t any simpler; it adds a keyword (pass); it adds a statement (the pass statement consisting of that keyword by itself); that syntax needs to be checked (syntax errors have to be generated for e.g. foo + pass); etc.
And really any expression without side effects could be used instead - in particular, a constant such as None or ... - but using pass (instead of “computing” a value that is then immediately discarded) is clearer and properly expresses the desired semantics.
So it seems pretty clear that it was deliberately added for this purpose.
To answer that question, first explore this: What is a “blank statement” in the source code? How would you write one?
Have a think about that, from a language design and syntax perspective. What is the cleanest and simplest way to have a blank statement or an empty block? In C-like languages, a block is defined by braces, so an empty block is an open brace followed by a close brace, with nothing inside them. In Python, a block is defined by indentation.
There are multiple correct answers, here, but I think the process of thinking through this will reveal a lot about Python’s design and how things came to be how they are.
With pass, the parser is able to discard any blank line consisting solely of whitespace without generating any tokens for it. If an empty statement were allowed, then every line is potentially an empty statement, and thus has to be parsed as a series of INDENT tokens. At a glance, is
class A:
x = 3
a valid class definition, or an IndentationError? (Spoiler, it’s an indentation error, as the empty statement making up the first line of the definition is indented 8 spaces, which makes x = 3 under-indented.)
You could argue that the parser could treat indentation specially for empty statements, but that’s no less a special case than requiring pass in the first place, and is much less readable.
I think the question isn’t really so much about empty statements, but rather empty blocks (“suites”, as termed in the grammar). A bizarro-world Python could perfectly well parse
if foo:
bar()
to mean the same thing as actual-reality Python
if foo:
pass
bar()
But doing so involves asserting that the programmer in the first example was probably deliberate in leaving the block empty, whereas in reality it’s overwhelmingly likely that this was a typo. It’s relatively rare that the programmer actually wants an empty block, and even less likely that it’s a good idea