
On Apr 18, 2020, at 05:16, Alex Hall <alex.mojaki@gmail.com> wrote:
Is there anything else similar in the language? Obviously there are cases where the same text has different meanings in different contexts, but I don't think you can ever refactor an expression (or text that looks like an expression) into a variable and change its meaning while keeping the program runnable.
I suppose it depends on where you draw the “looks like an expression”, line, but I think there are cases that fit. It’s just that there are _not many_ of them, and most of them are well motivated. Each exception adds a small cost to learning the language, but Python doesn’t have to be perfectly regular like Lisp or Smalltalk, it just has to be a lot less irregular than C or Perl. Most special cases aren’t special enough, but some are. A subscription looks like a list display, but it’s not. Mixing them up will only give you a syntax error if you use slices, ellipses, or *-unpacking in the wrong one, and often won’t even give you a runtime error. And the parallel isn’t even useful. But this is worth it anyway because subscription is so tremendously important. A target list looks like a tuple display, but it’s not. Mixing them up will only give you a syntax error if you try to use a tuple display with a constant or a complex expression in it as a target list. Mixing them up in other ways will only give you at best an UnboundLocalError or NameError at runtime, and at worst silently wrong behavior. But the parallel here is more helpful than confusing (it’s why multiple-value return looks so natural in Python, for one thing), so it’s worth it. **{a, b, c} is a special case in two ways: **-unpacking is no longer one thing but two different things, although with a very useful and still pretty solid parallel between them, and set display syntax now has two meanings, with a somewhat useful and weaker parallel. Even added together, that’s not as much of a learning burden as subscription looking like list displays. But it also isn’t as important a benefit. The magic ** mode switch only pushes two complicated and already-not-quite-parallel forms a little farther apart, which is less of a cost. The keyword= is similar but even less so, especially since anywhere it could be confused is a syntax error. The dict display ::value doesn’t cause any new exceptions or break any existing parallels at all, so it’s even less of a cost. But there are plenty of other advantages and disadvantages of each of the four (and the minor variations on them in this thread); that’s just one factor of many to weigh.