Let me split my case into two points: 1) The intuition that the right-hand side of `a | b` is a fallback value 2) The claim that `a |= b` is a common idiom to assign defaults About 2) It appears that the idiom in 2) is less common than I assumed. My expectations were shaped by working with a C++ codebase where the `|=` operator was sometimes overloaded in such a way (since there is no `||=` operator in this language). Unfortunately, I have not found similar uses of `|=` elsewhere (e.g. in Boost). To illustrate this with a specific case nonetheless, that C++ codebase had a generic data type modelled after Haskell's Maybe. In Haskell, `Maybe a` is a type which can be empty (`Nothing`) or hold a value (`Just a`). In the C++ implementation, the operation `a |= b` would assign `just(b)` iff `a` was not empty. About 1) I still believe that there is an intuition that the right operand of `|` is a fallback value, and this intuition may lead people to wrong use of dict unions. To make this intuition more explicit: Consider other operations that behave like OR in a Boolean algebra, such as logical OR, and set union. Conceptually, these operations perform one or multiple checks on the left operand, and only consider the right operand if the check "failed". - With logical OR, short-circuit semantics are widespread (cf. C, UNIX shell, or Python itself). The right operand is only evaluated if the left operand evaluates to false in a Boolean context. - With set union, implementations typically start by copying the left operand, and add entries from the right operand if they are not already present in the copy. This is also what CPython does in `set_union` (via `set_add_entry`). As another case in point, overriding items from the right operand is already provided by `dict.update`. A `|=` operator which provides for the complementary operation of filling in missing items would have made for a more orthogonal set of operations. When formulated in terms of `|`, the two operations only differ in the order of operands.
Here's our current proposal for docs. Is there anything you'd like to add? https://github.com/python/cpython/pull/18659/files
I find this quite clear. It already points out the behaviour in question. To conclude, different semantics for dict union would have been preferable in my view, but I guess that ship has sailed. Other than changing dict union semantics I don't think there is anything actionable left here. Maybe my input still has some value in clarifying expectations some users may have for this new feature. Thank you for your openness about this late input to the discussion. On Thu, 27 Feb 2020 at 10:35, Kyle Stanley <aeros167@gmail.com> wrote:
So I've also never come across "|=" being used for this purpose.
IIRC, the JavaScript implementation of "|=" can potentially be used in the way Claudio described it, instead it's based on the truthiness of the left-hand operand rather than it being "unset". But it works in that context because "null" and "undefined" are considered falsey [1]. For example:
var value = null; var other = 2; value |= other; console.log(value); 2
So it effectively works like "value | other", but also sets "value" to "other" iff "value" is falsey. When the left-hand operand is truthy, it effectively does nothing.
var value = 3; var other = 2; value |= other; console.log(value); 3
Also worth noting, since "value |= other" translates to "value = value | other", it works as a bitwise OR operator; not as a catch-all for assigning a default value:
var value = null; var other = "test"; value |= other; console.log(value); 0
Instead, you'd have to use the standard OR operator, like this "value = value || other" (since "||=" is invalid syntax):
var value = null; var other = "test"; value = value || other; console.log(value); test
FWIW, I have very rarely seen "|=" used as an operator in JS, but I've seen "value = value || other" used a decent amount.
---
[1] - https://developer.mozilla.org/en-US/docs/Glossary/Falsy
On Wed, Feb 26, 2020 at 6:26 PM Nick Coghlan <ncoghlan@gmail.com> wrote:
On Thu., 27 Feb. 2020, 2:03 am Guido van Rossum, <guido@python.org> wrote:
On Wed, Feb 26, 2020 at 7:43 AM Claudio Jolowicz <cjolowicz@gmail.com> wrote:
In my experience, the expression `value |= other` is a common idiom across programming languages to provide a default for `value` if it is "unset".
Interesting. Can you point to specific examples of this? In what other languages have you seen this? (Not that it would make us change PEP 584, but if this appears common we could probably warn about it prominently in docs and tutorials.)
I was thinking that bash scripting might be an example, but I double checked, and that's spelled 'VAR="${$VAR:-default value}" '
make has 'VAR ?= "default value"'
C# uses "??=" for null coalescence on assignment.
So I've also never come across "|=" being used for this purpose.
Cheers, Nick.
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/HMKYUZP5... Code of Conduct: http://python.org/psf/codeofconduct/