Hacker News new | past | comments | ask | show | jobs | submit login

You're very polite. I'm going to be more frank.

Monads like this are very problematic in the JavaScript world. I say this as an F# programmer, and our community is not unfamiliar with Railway Oriented Programming (https://fsharpforfunandprofit.com/rop/)

Unlike F# or any other decent functional language, JavaScript doesn't have very good constructs to guide and ensure the programmer is using these constructs properly, let alone using alongside with existing error propagating constructs.

What happens when you mix these with promises, or RxJs, or something else?

My advice would to be avoid using constructs like this for general purpose error handling and use tried and true constructs for Exceptions, which should be exceptional.

Something like this isn't entirely useless, sometimes its useful to encode errors in an abstract type when the errors become an integral part of the problem domain. Sometimes errors aren't exceptional and you need a way to deal with them that's somewhat performant. Even if that's the case, you need to be careful with constructs like this because it's easy to use them wrong, which might lead to scenarios where errors aren't properly thrown and propagated.

I'm not saying to never use them. I'm just heeding you should tread carefully.




Exceptions are for exceptional stuff, that is, something you do not normally expect. Their purpose is cleanup after a non-catastrophic failure.

OTOH you totally expect I/O errors and parsing errors while reading a CSV file. You totally expect a mismatch when matching a regexp. Using exceptions here is discouraged even by Martin Fowler, of all luminaries [1].

[1]: https://martinfowler.com/articles/replaceThrowWithNotificati...


Huh, I thought it was the opposite:

>we use the term exception for expected but irregular situations at runtime and the term error for mistakes in the running program that can be resolved only by fixing the program. https://wiki.haskell.org/Error_vs._Exception


If you start a thread and it gets killed by OS, it's an exception. You cannot predict when or where it happens, and normally it won't happen; there is no error in your code that leads to this. You can still try to gracefully react on a thread death situation in your code by catching an exception.

OTOH if you wrote a non-total function and it fails to proceed given some arguments, this is an error. You should not try to somehow continue if it happens; you should fix your program.


> If you start a thread and it gets killed by OS, it's an exception. You cannot predict when or where it happens, and normally it won't happen; there is no error in your code that leads to this. You can still try to gracefully react on a thread death situation in your code by catching an exception.

I don't see how this is different from when a file that's supposed to exist doesn't. I guess it's a matter of degrees.


Which are errors that you don't expect but you think you still can handle gracefully? I'm not a fan of exceptions but curious where you draw the line.


not finding the requested record is a perfect case for an Either, or something that is potentially (legitimately) null. Thats not an exception generally.


That sounds like the perfect place for a single if (val === null) { handle that very predicable case and return }

That whole example in the linked article displays coding style that surely makes sense but I can't imagine having that as a theme in my codebase. It's fringe and not native to the language, which makes onboarding others to that codebase a pain.


I dont disagree - where things like either, maybe or result really shine is when its baked into the stdlib _and_ there is machinery built into the language to make using them easy (like pattern matching, and them being in scope by default). I have used and written several libraries trying to make them work in js/ts and while they are beneficial around my custom domain specific code, you still spend a bunch of time wrapping things coming from libraries or other code you dont have control over.

But the benefit of them over a check against null is that you can write a pipeline of functions that dont have to handle those cases and you know that its always safe to do so. This other article by the same author as the OP I think illustrates it well https://jrsinclair.com/articles/2016/marvellously-mysterious...


Unlike F# or any other decent functional language, JavaScript doesn't have very good constructs to guide and ensure the programmer is using these constructs properly, let alone using alongside with existing error propagating constructs.

Javascript has at least two mature type checkers you can use that will let you use these constructs just as safely as in F#.

What happens when you mix these with promises

In my either library I added rightMapThen and leftMapThen, and called it a day. worked absolutely fine. I think I also have rightFlatMapThen and leftFlatMapThen. Works flawlessly, and I have everything I enjoyed about the equivalent in F# (where I first encountered the concept).




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: