A new operator `or=`

I suggest adding a new operator to simplify setting default for a variable which holds a False value.
Currently we write:
my_object.some_important_value = my_object.some_important_value or default_value
I suggest instead:
my_object.some_important_value or= default_value
or:
my_object.some_important_value ?= default_value
or:
my_object.some_important_value ||= default_value

The most relevant discussion I found when searching is PEP531 (Existence checking operators) which was withdrawn.

We can consider a similar and= operator.

Another discussion from last May.

3 Likes

PEP 505 is similar to this, but specific to None rather than using truthiness. Worth a read; why did that proposal NOT use truthiness, and do you disagree?

2 Likes

The related section explains how this proposal (or something resembling it) fails to solve the problem the PEP tries to address, but that does not prevent this proposition, or mine, to have its own merits. The two are not that similar, in purpose at least, and I think that’s what the PEP rightfully points out.

1 Like

Thanks for the feedback @Stefan2, @Rosuav and @Gouvernathor.
I think that the or= which is typically used currently as x = x or default is very useful in many cases, and I see it in lots of places. While current version is readable for a simple variable assignment, it is less readable for lengthier assignment as in my example above. To me or= is very clear as other python assignment operators, and it improves the readability.
I understand that this does not address the full None related operators and the issue of None vs. truthiness, but for or= the case is simple, it is well understood and readable.

On the other hand, I find the combination of letters and symbols in a single operator to be jarring, and I don’t think it improves readability enough to warrant a change in the grammar.

Also, an augmented assignment operator at least implies the possibility of in-place modification of the target. I struggle to imagine an occurrence of foo = foo or bar where the original value of foo is not simply being replaced with the value of bar.

2 Likes

Other than the simple syntactic sugar, augmented assignments usually allow to reuse and mutate the existing object instead of creating a new one, case in point : dict.__or__ creates a new dict when dict.__ior__ mutates it.
However, some types such as int are totally exempt from that behavior, so the fact that, as you pointed out, no type will implement mutation with these new operators, is not that new or problematic in my opinion.

That being said, there is a further optimization to be had with this new syntax.
a = a or b() implements a short-circuit in that if a has a false value, the b() call will not happen.
But regardless, the assignment will still happen.
In fact, even with d |= d2, d is mutated and then reassigned to itself, because of the fact that __ior__ is not guaranteed to return d itself.
But with the boolean short-circuits, the assignment can be skipped in those cases since there is no dunder.

1 Like

Thanks everyone who responded here. I still feel there is value in a new or= operator, but I also understand that it may not be enough to justify it.
I am not sure how to continue, this is my first time here, how do you recommend to continue here? I am OK with closing this as well as consulting with additional people that we can turn to or any other suggestion you may have.