[HN Gopher] Safe Assignment
___________________________________________________________________
Safe Assignment
Author : commondream
Score : 14 points
Date : 2024-09-10 15:46 UTC (3 days ago)
(HTM) web link (nalanj.dev)
(TXT) w3m dump (nalanj.dev)
| zarzavat wrote:
| 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.
| hyperhello wrote:
| 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 wrote:
| 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).
| spankalee wrote:
| 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 wrote:
| 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 wrote:
| With the length of that you might as well do:
| if (obj) obj.bar = 42
| recursive wrote:
| 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
| spankalee wrote:
| 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
| Animats wrote:
| 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.
| timwis wrote:
| 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
___________________________________________________________________
(page generated 2024-09-13 23:01 UTC)