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/HMKYUZP5T6HTURG46GU3L72KANB65MLQ/
Code of Conduct: http://python.org/psf/codeofconduct/