loading...

re: Nested Conditional Operators VIEW POST

TOP OF THREAD FULL DISCUSSION
re: I leave you with this: const a = {toString: Math.random, valueOf: ()=>false}, {log} = console log(String(a)) log(1 / a) log('' + a) log(Boole...

@joelnet Why shouldn't you use switch(true){case binaryexp: return stuff}? It's the same control flow as if(){} else if(){} else if(){} or if you are always returning if() return; if() return; if() return. What could go wrong? Fallthrough?

When given multiple ways to write something, I always prefer writing an expression over statements.

So I wouldn't use a switch or an if when I could use a ternary

I bet you're all about those throw expressions, aren't you? ;)

Hmm. Well, I have used function expressions to throw, so this would be an improvement.

But since we're on the subject of Exception, I'll use this opportunity to rant about Exceptions.

Unless your intent is to halt the program, an Exception should not be thrown.

If your function can result in an exception, return it. This would follow a similar pattern as Promises.

const failed = Promise.resolve('success')
  .then(data => {
    return Promise.reject('Uh oh!')
  })

failed
  .then(data => console.log('data', data))
  .catch(err => console.log('err', err))

And also similar to a callback:

const myAction = (input, callback) =>
  input !== 'good' ? callback(Error('uh oh')) : callback(null, 'YES!')

myAction('bad', (err, data) => console.log({ err, data }))
myAction('good', (err, data) => console.log({ err, data }))

Example:

const myAction = (input) =>
  input !== 'good' ? { err : Error('uh oh') } : { data: 'YES!' }

myAction('bad') //=> { err: [Error: uh oh] }
myAction('good') //=> { data: 'YES!' }

The benefits are:

  • All return types are handled the same way. (with throw you have to handle an exception being returned with a try-catch).
  • Exceptions are a valid result of a function. This forces the user of the function to be aware of such return values.

Yeah, Result<Err, Val> is an awesome datatype, but it's not the norm in JS, unfortunately.
How great would Promise<Err, Val> = Future<Result<Err, Val>> be :)

Instead, they integrated with exceptions, which makes throwing inside an async function great, but makes awaiting a fallible promise pretty ugly.

That's the difficulty is going opposite of the norm. It really works out well when your entire application is designed that way, but can be odd when you inject it into an existing application.

Consistency across the application is more important. So I will do these things with a new app, but code in the same style as existing apps just for consistency.

Code of Conduct Report abuse