During a recent HN discussion about the walrus operator I came to realize yet another advantage of notation. I used APL professionally for about ten years, which made it an obvious source of inspiration for an example that, in my opinion, demonstrates why the Python team missed a very valuable opportunity to take this wonderful language and start exploring the judicious introduction of notation as a valuable tool for thought (borrowing from Ken Iverson's APL paper with that title [0]). To simplify, I'll define the desire for this walrus operator ":=" as "wanting to be able to make assignments within syntax where it was previously impossible": if x = 5 # was impossible # and now if x := 5 # makes is possible A more elaborate example given in the PEP goes like this: Current: reductor = dispatch_table.get(cls) if reductor: rv = reductor(x) else: reductor = getattr(x, "__reduce_ex__", None) if reductor: rv = reductor(4) else: reductor = getattr(x, "__reduce__", None) if reductor: rv = reductor() else: raise Error( "un(deep)copyable object of type %s" % cls) Improved: if reductor := dispatch_table.get(cls): rv = reductor(x) elif reductor := getattr(x, "__reduce_ex__", None): rv = reductor(4) elif reductor := getattr(x, "__reduce__", None): rv = reductor() else: raise Error("un(deep)copyable object of type %s" % cls) At first I thought, well, just extend "=" and be done with it. The HN thread resulted in many comments against this idea. The one that made me think was this one [1]: These two are syntactically equal and in Python there's no way a linter can distinguish between these two: if reductor = dispatch_table.get(cls): if reductor == dispatch_table.get(cls): A human being can only distinguish them through careful inspection. The walrus operator not only prevents that problem, but makes the intent unambiguous. Which is a perfectly valid point. I get it. Still, the idea of two assignment operators just didn't sit well with me. That's when I realized I had seen this kind of a problem nearly thirty years ago, with the introduction of "J". I won't get into the details unless someone is interested, I'll just say that J turned APL into ASCII soup. It was and is ugly and it completely misses the point of the very reason APL has specialized notation; the very thing Iverson highlighted in his paper [0]. Back to Python. This entire mess could have been avoided by making one simple change that would have possibly nudged the language towards a very interesting era, one where a specialized programming notation could be evolved over time for the benefit of all. That simple change would have been the introduction and adoption of APL's own assignment operator: "←" In other words, these two things would have been equivalent in Python: a ← 23 a = 23 What's neat about this is that both human and automated tools (linters, etc.) would have no problem understanding the difference between these: if reductor ← dispatch_table.get(cls): if reductor == dispatch_table.get(cls): And the larger example would become this: if reductor ← dispatch_table.get(cls): rv ← reductor(x) elif reductor ← getattr(x, "__reduce_ex__", None): rv ← reductor(4) elif reductor ← getattr(x, "__reduce__", None): rv ← reductor() else: raise Error("un(deep)copyable object of type %s" % cls) This assignment operator would work everywhere and, for a period of time, the "=" operator would be retained. The good news is that old code could be updated with a simple search-and-replace. In fact, code editors could even display "=" as "←" as an option. The transition to only allowing "←" (and perhaps other symbols) could be planned for Python 4. Clean, simple and forward-looking. That, to me, is a good solution. Today we have "=" and ":=" which, from my opinionated perspective, does not represent progress at all. [0] http://www.eecg.toronto.edu/~jzhu/csc326/readings/iverson.pd... [1] https://news.ycombinator.com/item?id=21426338