&&= and ||=

Typescript 4.0 is introducing two new operators:

In Rust:

fn main() {
    let mut a = true;
    a &&= true;
    a ||= false;
}

In rare circumstances I wished to use this.

1 Like

Oddly enough, I wanted this here: https://github.com/rust-analyzer/rust-analyzer/pull/4587/files#diff-2d3440bb91de25b42566a44695daf55cR135

1 Like

Yes, it's not a super-common need, but once in a while I find a use for those operators. But I'm curious to know why Rust doesn't have them :slight_smile:

Operators like += are required to implement operations efficiently for non-primitive types like bigints, where a += b can be more efficient than a = a + b. But for || and &&, the first operand is necessarily a bool, so ||= is not as important to have as +=. My point is that although they can save typing an identifier in some cases, I don't think these operators would carry their weight.

5 Likes

Just for comparison: Rust does have &= and |= operators which work with bool, as well as numeric types and user-defined types. Of course, these don't have the short-circuiting behavior of && and ||, so they are usually not appropriate when the RHS is expensive to evaluate. (For example, you can't use them to simplify @matklad's example, above.)

3 Likes

As with any time people suggest a new punctuation token:

Unfortunately, this would be breaking for some macros (at least without "interesting" compat hacks between the actual token model and macro_rules!). (Or a new statement type <place> && = <expr> which would work but would also be.. "interesting.")

So I doubt the small motivation outweighs the cost of adding the new token (or otherwise making it work). At the very least it'd be a "next edition" kind of thing.

4 Likes

Well, if the LHS is costly to compute (e.g. it is a long expression) then this will save a lot. Normal compiled languages have common sub-expression elimination that can probably lift out the common LHS and just use a pointer to the location to mutate. However, JavaScript is not compiled.

I would be interested to see how this is implemented though, especially when LHS &&= RHS; where LHS involves property access that can potentially have side effects because the equivalent LHS = LHS && RHS is going to trip those side effects twice.

Maybe this is why it takes so long to show up.

1 Like

I guess that it creates a new variable if necessary, e.g.

a.b().c &&= d();
// becomes
const _temp = a.b();
_temp.c && (_temp.c = d());

If c is a property, both its getter and its setter might be called.

1 Like

There is a note in the announcement that says beware of property access with side effects.

It also says it is smart enough to handle complicated expressions on the LHS...

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.