top | item 43749617

(no title)

jackjeff | 10 months ago

Checking for errors after every line (like in Go) is the worst. Used to do that in c/c++ calling win32 APIs. Know what happened when sloppy developers come along? They don’t bother checking and you have really bizarre impossible to debug problems because things fail in mysterious ways. At least with an exception if you “forget” to catch it blows up in your face and it’ll be obvious

Sure monads are cool and I’d be tempted to use them. They make it impossible for forget to check for errors and if you don’t care you can panic.

But JS is not Rust. And the default is obviously to use exceptions.

You’ll have to rewrap every API under the moon. So for Monads in JS to make sense you need a lot of weird code that’s awkward to write with exceptions to justify the costs.

I’m not sure the example of doing a retry in the API is “enough” to justify the cost. Also in the example, I’m not sure you should retry. Retries can be dangerous especially if you pile them on top of other retries: https://devblogs.microsoft.com/oldnewthing/20051107-20/?p=33...

discuss

order

stickfigure|10 months ago

Monadic style or not, the `if err != nil return err` pattern destroys critical information for debugging. `try/catch` gives you a complete stacktrace. That stacktrace is often more valuable than the error message itself.

9rx|10 months ago

> the `if err != nil return err` pattern destroys critical information for debugging.

Funny enough, your code looks like it is inspired by Go, and Go experimented with adding stack traces automatically. Upon inspecting real-world usage, they discovered that nobody ever used the stack traces, and came to learn that good errors already contains everything you'd want to know, making stack traces redundant.

Whether or not you think the made the right choice, it is refreshing that the Go project applies the scientific method before making a choice. The cool part is that replication is the most important piece of the scientific method, so anyone who does think they got it wrong can demonstrate it!

sethammons|10 months ago

That is why everyone says to wrap your errors in Go. %w ftw

Naked err returns can be a source of pain.

WorldMaker|10 months ago

An advantage to the Monad approach is that it sugars to the try/catch approach and vice-versa (try/catch desugars to monads). JS Promises are also already "Either<reject, resolve>". In an async function you are writing try/catch, but it desugars to monadic code. You could write an alternative to a library like "neverthrow" that just wraps everything in a Promise and get free desugaring from the async and await keywords (including boundary conditions like auto-wrapping synchronous methods that throw into Promise rejections). You could similarly write everything by hand monadically/pseudo-monadically directly with `return Promise.reject(new Error())` and `return Promise.resolve(returnValue)` and everything just works with a lot of existing code and devs are quite familiar with Promise returns.

It might be nice for JS to have a more generic sounding/seeming "do-notation"/"computation expression" language than async/await, but it is pretty powerful as-is, and kind of interesting seeing people talk about writing Monadic JS error handling and ignoring the "built-in" one that now exists.

This is also where I see it as a false dichotomy between Monads and try/catch. One is already a projection of the other in existing languages today (JS Promise, C# Task, Python Future/Task sometimes), and that's probably only going to get deeper and in more languages. (It's also why I think Go being intentionally "anti-Monadic" feels like such a throwback to bad older languages.)

sethammons|10 months ago

Moving from try:catch to errors as values was so refreshing. Same company, same developers, but suddenly people were actually _thinking_ of their errors. Proper debugging details and structured logging became default.

I assert that try:catch encourages lazy error handling leading to a worse debugging experience and longer mean time to problem discovery.

peterashford|10 months ago

Checked exceptions also force people to think of their errors

jayy-lmao|10 months ago

Nice thing about Monads in JS with tools like neverthrow is that you can create the Monad boundary where you like.

It becomes very similar to try-catch exception handling at the place you draw the boundary, then within the boundary it’s monad land.

If you haven’t wrapped it in a monad, chances are you wouldn’t have wrapped it in a try-catch either!

rad_gruchalski|10 months ago

Don’t accept sloppy development practices regardless of what programming language you’re going to use.