-
-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alternative Approach: Implementing Safe Assignment Without ?= Operator #24
Comments
Also see #9 |
@anacierdem I reviewed the discussion in issue #9 before this, which effectively addresses potential problems with the ?= operator and explores alternative solutions. While that discussion focuses on the risks and possible workarounds, my issue emphasizes that we can achieve the same goals with current JavaScript features, without needing any new additions to the language. If the intent is to simplify error handling, we already have robust patterns available that don't introduce extra complexity. |
Important note: While the idea of using an assignment operator like ?= for error handling is intriguing, I believe error management should be handled at a higher level than what the interpreter or compiler directly manages. Typically, assignment operators are focused on straightforward value assignment, whereas error handling involves more complex logic. Keeping these responsibilities separate helps maintain clarity and avoid overcomplicating the language. By placing error handling in its own layer, we can maintain cleaner, more maintainable code without burdening basic language constructs. |
A lot of words that don't make sense without a specific context. There are a lot of languages with operators related to errors, Rust's |
As it was said before in several other issues, I don't think that the fact that something can be achieved with current constructs should be a blocker for something to work better with a new construct. Several things can be achieved just using JS, array/object grouping, set operators (intersect, union, etc) but still, they've made in as proposals. IMHO, the whole goal of a proposal is to improve on existing syntax, so things we do often should be improved on by creating constructs around the language that make those things more ergonomic. |
The TC39 technical committee will carry out a rigorous analysis. I leave you with aspects that I believe they will review: #33 |
I’ll join @khaosdoctor on this. Just because a feature already exists doesn’t mean we can’t try to improve it. Before async/await, there were Promises, which were more difficult to understand than the new syntax. Now everyone uses async/await and, I agree, sometimes still has to fall back to the old Promise model in some rare cases to handle old API callback patterns. That said, the new syntax is much more maintainable and faster. With this proposal, we can write in one line what previously took several lines. Even though try/catch makes the errors more visible than a simple ?: operator, it has a flawed design in terms of scoping. This often forces developers to write the whole code inside the try block because it depends on a value declared within it, which could throw something else, so the try catch is more like a global "please, prevent my code from crashing in production", than a real tool as it was designed for. try {
const result = await fetch(...);
/* logic here that could throw something else */
} catch {
/* handle more than one thrown error */
} Sometimes, it becomes even worse in terms of readability, as people start to:
|
@TheUniqueMathemagician @arthurfiorette @anacierdem @khaosdoctor You will always need to:
What options do you have for this?
The Promise So, it is a misconception that "safe assignment" #32 is safe. Assignment is always safe. And I think it is too much responsibility for an operator. The first question that the TC39 committee asks, and it is a requirement that they ask you, is if what you are trying to add can already be solved with what already exists. According to the rules:
When you start to let your imagination fly, many alternatives appear (complying with ECMA): // 1. inline solution
try let result = await fetch(...) catch err
try result = await fetch(...) catch err
try result = await fetch(...)
let result = await fetch(..) catch err
// ...
// 2. catch like switch-case
try:
// ...
catch err:
// ...
finally: // (or finally; / break; to finish...)
// ...
// 3. catch for any ECMA blocks (anonymous,, functions, cases, classes, if, ...)
{ .... } catch (err) { } finally { ... }
function foo() { } catch (err) { } finally { ... }
if (...) { } catch { } finally { ... }
class Person { ..... } catch (err) { ... } finally { ... } // if something happens inside the class .... I want to go back inside the block!!! But when you think about it you end up asking yourself: is it worth it? Would it be better to continue using the current try catch? You can also think about improving the current In the end, what is there is probably more than enough and there is no need to create problems where there are none. The traditional try-catch is a proven solution. An assignment operator should not have the responsibility of handling exceptions. If you want a weird solution that is semantically understood as "safe assignment", do something like this and you won't need an catch(response = await fetch(...)) {
// response is an exception here
// ... return!
}
// MAYBE response is not an exception here The challenge I see is that if you don't get out with a return in the catch, you always have to ask down below if there was an error or not. When you review all those alternatives and find problems you end up concluding that try-catch already solves it. |
You could argue that callbacks are also a proven solution, and yet, we have promises, which are also another proven solution with then/catch, and yet, we have async/await. We can go even further, assembly is a proven solution, yet we have C (another proven solution), yet we have CPP, Go, Rust, and JavaScript. If proven solutions moved the world, we would be discussing C headings here on our SVN servers from our Telex machines. Clinging on the idea that "if it works leave the way it is" is really not what drives innovation, and certainly not (at least for me) the way the JS community has been behaving since forever. We have multiple examples of "good enough" solutions that were replaced by incredible solutions (jQuery, MooTools, Lodash, Underscore), much of those not only inspired but were literally copied into the spec. There's always room for improvement, even in proven solutions.
But here's the thing, there won't be two ways. If we look at #4, using People can use both of them the same way Node has Do you wonder about why are there three completely different paradigms to handle data in JS very often? I really don't, and I don't believe other users will do so because of try/catch (which is already considered a bad pattern).
So the problem is the Your points are valid, but they're not strong enough for me to justify ditching this improvement. Especially since other languages like Go already implement the same pattern and are proven solutions |
I was just giving some additional considerations. But my arguments from the beginning are 2:
Both arguments will be raised by the TC39 committee. For this reason I thought of valid language alternatives such as control structures, not assignment operators. |
Yes I see your point and it’s totally valid! I’m not saying you’re wrong,
and it’s important to bring those points here so we can handle those.
But both of those points, in my opinion, are weak to justify the rejection
of this proposal. Not only because of all the points I mentioned both here
and on #33 but also because the current state of the spec already has this
in place, and there are plenty of previous art that were implemented in the
spec. And these issues are a good discussion to prove that
|
I have created an issue #37 dedicated to the critical point in question. I am closing this one because I believe everything has been addressed and it is up to the developers and TC39 to resolve it. |
Hi everyone,
First of all, I appreciate the effort and thought that has gone into the proposal for the
?=
operator. It's clear that the intention is to simplify and standardize error handling in JavaScript, which is an important goal.However, I believe that this proposal might not be necessary given that we can achieve similar results using existing JavaScript features. Specifically, we can handle errors and return results in a concise and readable way by using simple wrapper functions. Here's an example of how this can be done:
Moreover, if we use our imagination, we can extend these functions to return not just tuples, but also objects or any other robust structures that might suit the specific needs of a given application. This flexibility allows developers to tailor their error handling to the exact requirements of their projects, without being constrained to a single approach. For example, we could return an object with additional metadata, logs, or context about the error and the operation, providing a more comprehensive solution.
Sync example
Async example
Key Points:
Conclusion:
While the
?=
operator is an interesting idea, it's important to consider whether introducing a new operator is justified when we can already accomplish the same goals with existing language features. The above functions provide a simple, readable, and effective way to handle errors without adding complexity to the language.I'd love to hear thoughts from the community on this approach and whether it might be a sufficient alternative to the proposed operator.
Thanks for considering my input!
The text was updated successfully, but these errors were encountered: