arthurfiorette / proposal-safe-assignment-operator

Draft for ECMAScript Error Safe Assignment Operator
https://arthur.run/proposal-safe-assignment-operator/
MIT License
1.49k stars 16 forks source link

How does this improve upon Promises? #40

Open JamesRamm opened 3 months ago

JamesRamm commented 3 months ago

I am struggling to see how this:

  const [requestError, response] ?= await fetch(
    "https://api.example.com/data"
  )

  if (requestError) {
    handleRequestError(requestError)
    return
  } 
  handleResponse(response)

is an improvement upon

 fetch("https://api.example.com/data")
   .then(handleResponse)
   .catch(handleError)

Can you expand upon this? IMO the first two stated goals - Simplified Error Handling and Enhanced Readability are already addressed by the superior Promises API.

I can understand the motivation for this, if I approach from the angle of someone who has much more experience with async/await and not using Promises.

I also don't see how it improves security. You can equally overlook implementing checking the error response - if (requestError) - as omitting to implement a catch block. Furthermore, your proposal seems to indicate that errors will no longer be thrown - they are 'swallowed' by the assignment operator and returned as a value. This means that if you do overlook checking the return value, you do not got a bunch of 'uncaught exception' warnings in the console, linters etc... Granted there are ways of swallowing exceptions with try/catch and promises, but forgetting to implement a catch block in most standard use cases will result in such warning. So, I actually see this proposal as a regression with regards to security in that respect.

otaxhu commented 3 months ago

This is not only for Promises, it aims any kind of function (synchronous and asynchronous) or expressions (see #5)

In Promises regards, it solves "callback hell", callback indentation readability, try block indentation readability (if using await syntax), and error as values have been proven to be popular among developers.

Operator ?= has been replaced over try-expression syntax (see #4 #5)

garretmh commented 2 months ago

The proposal seems primarily useful for synchronous code. Promises can be turned into "result tuples" trivially:

const [error, value] = await fetch("https://api.example.com/data").then(
  (value) => [undefined, value],
  (error) => [error, undefined]
)

// With a wrapper function:
const result = (promise) => promise.then((val) => [undefined, val], (err) => [err, undefined])
const [error, value] = await result(fetch("https://api.example.com/data"))
arthurfiorette commented 2 months ago

The proposal seems primarily useful for synchronous code

For async code as well because it would provide a standard way of converting errors as values.

Arlen22 commented 2 months ago

The one improvement for Promises is the ability to type check the tuple types after they are decoupled, if Typescript allows that at all. And it removes an extra .then(e => [undefined, e], e => [e]). That's all.