Settings

Theme

Safe Assignment

nalanj.dev

23 points by commondream a year ago · 14 comments

Reader

zarzavat a year ago

It seems that the proposal itself has given up on the syntax in the article and will be proposing try expressions instead. The ?= syntax would never fly given that there's already a ??= operator that does something else.

Given that the (much simpler) throw expressions have been stuck in bureaucratic hell for 7 years, I look forward to seeing try expressions some time around the heat death of the universe.

spankalee a year ago

Since the proposal is moving to try expressions, my main criticism there is that I don't usually just want the error as a value, as then I still need to check it and write a branch to handle the error case. It's nice that I could use const on the value variable instead of let, but that's such a small gain.

What I really want for the expression to return the value, but give a branch for the error case:

    // We still get a catch block to handle errors in
    const value = try foo() catch (e) {
      throw new MyError('Error trying to foo');
    };
Otherwise we have to write this to handle the error:

    const [value, error] = try foo();

    if (error) {
      throw new MyError('Error trying to foo');
    }
And it's far to easy to forget the error handling code altogether, resulting in silent failures.

edit: removed a brain-fart on a case that's already handled by JS :O

spankalee a year ago

The real safe assignment that I want to see is for optional chaining to be valid in LHS of assignments:

    foo?.bar = 42;
This would not perform the assignment if an optionally chained value was nullish. It downlevels to

    foo == null ? undefined : foo.bar = 42;
Given that the assignment is a SyntaxError now, this should be possible.
  • nuxi a year ago

    You can avoid the SyntaxError by abusing boolean expressions a bit:

      > obj = {}
      {}
      > obj != null && (obj.bar = 42)
      42
      > obj
      { bar: 42 }
    
    Not as pretty as your LHS case, but it works.
    • Wingy a year ago

      With the length of that you might as well do:

          if (obj) obj.bar = 42
  • gqcwwjtg a year ago

    Would it evaluate the RHS? It feels like it shouldn’t, but somehow that seems weird too.

Animats a year ago

It's syntactic sugar for try/catch blocks. No new functionality.

Try/catch and exceptions seem to be tough for programmers to handle. You have to have disciplined unwinding for exception propagation to work well when an unwind goes through multiple calls.

Rust's rather simple "?" operator, which I once thought was underpowered, seems to be a workable solution. It's just syntactic sugar for return on error, but because there's a standard error trait, that usually works out well.

The lesson from this is to get your error objects right early in the history of a language, because you can't retrofit them. Once you have that right, how to report errors becomes sane, and the mechanism becomes less important.

recursive a year ago

I don't think we'll ever see this. At least I hope we won't. Even specifying its behavior seems to be a nightmare. And you can basically just write it yourself.

    [val, err] ?= maybeThrow(); // instead of this
    [val, err] = wrapErr(maybeThrow); // you can write wrapErr yourself and use it forever
    [val, err] = wrapErr(maybeThrow, arg1, arg2); // you can even provide args
khffaydfsjd a year ago

This may be unorthodox for JS, but I treat exceptions like panics and use error values if I care about them. This also gives me type checking in TypeScript.

brundolf a year ago

This would make certain things more convenient, but wouldn't be very versatile and would feel terrible in terms of overall language semantics

Try expressions (mentioned in other comments) seem significantly better, but still feel like they're trying to tack on something that fits awkwardly into the original language design (though that's kind of the history of JavaScript)

Anyway, I'd use those all the time if they landed

timwis a year ago

Hah, thought this looked familiar… I had a similar idea back in 2017 and published a little 5-line library to get this type of syntax ([err, result] for async): https://github.com/timwis/eres

hyperhello a year ago

Is try really meant for casual flow control, or should it be last ditch error recovery? ?: makes sense, forEach() makes sense, but not every kind of block needs a backup syntax.

  • tbrownaw a year ago

    That will depend on language features (for example, multilevel/labelled `break`), performance (exceptions may or may not be slow or interfere with some kinds of optimizations), and personal preference (similar to the disagreement over whether or not it's bad practice to allow multiple `return` statements in one procedure).

chipsrafferty a year ago

"To access errorMsg outside of the try/catch block using const or let you have to define it outside of the block."

Just use var, then.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection