4 ms·
Python encodes structure in only one way, using indentation. There is no redundant signal that can be checked for a discrepancy that could indicate a problem. G
by kazinator 2y ago
Python encodes structure in only one way, using indentation. There is no redundant signal that can be checked for a discrepancy that could indicate a problem. GCC and Clang can diagnose when indentation is "misleading" because it doesn't match what the braces are saying.
Python's choice of representation is such that two different Python programs show zero differences under a white-space-suppressed diff.
The white-space suppressed diff is a useful tool for comparing programs when some sections of code have changed indentation but are otherwise the same; yet we cannot rely on it if we are using Python.
Python's syntax design is objectively poor on several purely technical points. In its favor, there are only handwaving pop psych arguments.
- thoutsnark 2y agoI strongly agree with your main point that pythons syntax design is objectively poor, but content that even the grace you seek to extend to it is wrong >Python encodes structure in only one way, using indentation Except when you write a multiple line string using """ notation. Or when you put things inside parenthesis, which i have seen as the preferred solution for method chaining. Point is, python claims indentation is all that is needed, and then very quickly breaks it's own rule.
- necovek 2y agoOpen parentheses and "multi-line" strings are simply Python's way to allow a single statement to span multiple lines in a nicer way: incomplete expressions continue across the newline (you can also do that with a common Unix way of escaping the newline — backslash right before you start the new line). FWIW, even """ notation does not require a string to be multi-line — it mostly allows using less escaping for things like newlines but also quotes. A preferred way to chain methods is to store values in descriptively named intermediate variables: it would also ease debugging as you'll get a direct pointer to the line that is problematic. Though, TBH, that's probably bad API design (I know it's common with DB query syntax, but that's attempting to turn SQL query construction into objects when they really aren't). Python, like most languages, doesn't really stop you from doing crazy stuff. But also like most languages, it can be done really well.
- sverhagen 2y ago> two different Python programs show zero differences under a white-space-suppressed diff. This must surely be a bad thing? How would this signal an unfortunate indentation change between: if foo: bar() bar2() And: if foo: bar() bar2() ???
- necovek 2y ago> Python encodes structure in only one way, using indentation. There is no redundant signal that can be checked for a discrepancy that could indicate a problem. GCC and Clang can diagnose when indentation is "misleading" because it doesn't match what the braces are saying. I've seen both misplaced braces (akin to mis-indenting blocks in Python), indentation not matching braces and other problems of the same sort in non-Python code. Readers of the code would misunderstand the code when badly indented, and might introduce bad braces as well (not everybody uses automatic formatters and linters either, esp as they will sometimes "quickly" edit code in their non-usual dev environment). Not to mention that some "braced" languages allow having single-line blocks without braces. It's also not true that this is the only way Python encodes structure: new blocks generally only start with a ":", and you've got control flow keywords that allow for new blocks to start. One could argue that's a great feature disallowing you from introducing confusing spacing without actually having a new block started. While I am fond of applying many of double-entry-accounting principles in programming to increase trust in what we write, I believe that's much better done with unit-tests, which can more clearly demonstrate the expectations for any code and read more like documentation. Do you think all syntax in programming languages should have some sort of extra validation built-in? Eg. you should type in a constant twice (declare it as `const int a = 5` and then you have to set the value later as `a = 5` or you get an error?)? As I said above, people will always find an "objective" excuse why their preference is better. But I've seen bad-block-boundaries in Python as much as I've seen it in other languages which use explicit block boundaries like braces (and I've done more Python over the last ~20 years). I've heard this argument a gazillion times, but hundreds of bugs due to that have simply failed to materialize while working on large projects with tens and hundreds of people. Getting indentation right is _really_ not that hard, just like getting braces right is not that hard. I've yet to find someone who prefers their code to not be indented at all, and only rely on braces — at least not in a team setting where you can't simply reformat all of it.
- kazinator 2y ago> But I've seen bad-block-boundaries in Python as much as I've seen it in other languages You have to consider ones you have not seen: the ones that are valid syntax, and thus invisible. > (declare it as `const int a = 5` and then you have to set the value later as `a = 5` or you get an error?)? For that, it would be more like assert (a == 5). It's not commonly done for constants. Neither the definition nor assertion are perturbed by significant whitespace, so it isn't the same. If the constant only exists for clarity and not configuration (so the code cannot conceivably work with any other value), then the assertion would be warranted: assert(a == 5); // Did you read the comment about not changing a?
- arcxi 2y ago>The white-space suppressed diff is a useful tool for comparing programs when some sections of code have changed indentation but are otherwise the same; yet we cannot rely on it if we are using Python. yes, because in Python two programs with different indentation are not the same. what's the problem that you can't use tools intended for code without significant whitespace with code in Python?
- xigoi 2y ago> There is no redundant signal that can be checked for a discrepancy that could indicate a problem. What’s the problem with having no redundancy? By the same logic, we should require numerals to be spelled out in words so the compiler can check if the programmer didn’t accidentally write a different number. def fahrenheit_to_celsius(x): { return (x - 32 [thirty two]) * 5 [five] / 9 [nine]; }
- kazinator 2y agoIf we primarily relied on a whitespace representation of numbers, it would help to have digits there for the machine to look at and possibly diagnose against the whitespace.
- necovek 2y ago(Almost) Every programmer in the world depends on whitespace to understand code: are you claiming that's not true? If humans can do it, why wouldn't computer programs like interpreters do it?
- kelipso 2y agoRedundancy reduces likelihood of bugs. Your numbers example would too but it's obviously too much work for not enough benefit.
- xigoi 2y agoBraces are also too much work for not enough benefit.
- kelipso 2y agoGiven the chronic inconvenience of significant whitespace, absolutely not.
- necovek 2y agoThat's an opinion that is largely disproven by the amount of working Python code in the world. Why is it so hard to accept that this is your personal preference and is really not an "objective" statement?
- Too 2y agoMost diff tools default to not suppressing leading whitespace. Trailing whitespace should be automatically removed and enforced by your code formatting tools, leaving no reason to suppress it. As someone who has been diffing endless amounts of python through various diff tools, this is totally a non issue.