None-coalescing operator and null‑coalescing assignment

Fair point. It won’t magically fix concurrency. Two threads can still race to the same ??=.

But it closes the tiny window between the check and the assign that the manual if version leaves open. That’s all. For real safety, you’d still need a lock.

Why is that of value? What problem is that solving?

Without atomicity, two threads could both see None and both compute expensive_default(), wasting CPU. Worse, if default has side effects (logging, state change), they could happen twice unexpectedly.

With ??=, only the first thread computes the default; the second sees the value already set. That’s the value.

We are back to the question of why ??= needs to be atomic and += is not.

And in the context of GIL vs. freethreading python.

Great question. The difference is conditionality.

+= always performs the read-modify-write, regardless of the current value. It doesn’t need to be atomic because the operation itself doesn’t change based on a condition.

??= only writes if the current value is None. The atomicity ensures that two racing threads don’t both see None and then both compute/assign the default. That prevents duplicate work.

Under the GIL, it’s still valuable (prevents double computation in rare but real races). Under a free‑threading build, the bytecode would need proper locking to preserve the same semantics – but that’s an implementation detail. The language semantics define it as atomic; implementations must follow.

It sounds to me like having ??= be atomic is only going to confuse people, given that other operators like += are not. People who are using threads are going to have to learn to think about atomicity anyway, so why is having one operator be atomic better than having a consistent picture that’s easier to learn?

2 Likes

But a += 1 will not leave a with the correct value if two threads run the code at the same time. That is not different from test and set for ??= in principle. Both are race conditions that lead to the wrong answer.

@pf_moore @barry-scott You’ve convinced me.

The atomicity argument adds complexity and raises consistency questions without enough real-world benefit. I’ll drop it from the proposal.

??= remains as pure syntactic sugar for if x is None: x = default, with no atomicity guarantee. That keeps it consistent with += and other augmented assignments.

Thanks for the push — the proposal is stronger without this claim.

1 Like

Question - are you using an LLM to create your responses? The discussion feels frustratingly like debating with an LLM, rather than with a person who has thought through their proposal and is willing to defend it because they believe it’s correct.

13 Likes

Right, := does not suffer from any race condition. Also, if ?? and ??= behave differently, they should not.


I share the same concern as @pf_moore, particularly regarding response speed.

Fair point. I sometimes use an LLM to help phrase things because English isn’t my first language and I want to be clear. But the ideas are mine.

I dropped atomicity because your arguments made sense — it wasn’t worth the complexity. Thanks for the honest feedback.

Yeah, it doesn’t have.
But the value of these operators is to be simple and clear.
And my speed - my first language isn’t English, so I should spend more time than you to understand your opinions, and sometimes use LLM to make my opinion clearer.
But I promise, ideas are mine.

You did not do so in post 25; you wrote 107 words in under two minutes, which is about 1–2 words per second.

1 Like

You’re right about the timing. I had already thought through that response.

I do use tools to help with phrasing sometimes, but I’m not going to keep defending how I write. Let’s focus on the proposal — do you have any technical feedback on ?? and ??=?

1 Like

I’ll try to express by myself, unless I really can’t express it.

Could you please explain this example?

Wait, I seem too make a mistake.

Good point. I’ve fixed it.
Are there any errors I haven’t found?

Given that you’ve abandoned atomicity, this thread doesn’t seem to add anything new, and as @cdce8p is already preparing a PEP, I don’t think there’s anything more worth discussing here.

3 Likes

Thank you for your time.
But I still think it’s a useful design.
I really want it to join Python, even though it’s already without atomicity.
You’re right.

1 Like