14 ms·
Railway oriented programming
- bbcbasic 10y agoIt's a monad tutorial that's too embarrassed to admit it.
- edgyswingset 10y agoNo it's not. This is a tutorial on error handling that happens to be monadic. The emphasis is on handling errors, not talking about monads.
- bbcbasic 10y agoIt can be more than one thing at a time.
- edgyswingset 10y agoEmphasis mine: > It's a monad tutorial that's too embarrassed to admit it. This is not a correct interpretation of the blog post. This is not a monad tutorial, this is a tutorial on error handling that happens to be monadic.
- justinpombrio 10y ago> This is not a monad tutorial, this is a tutorial on error handling that happens to be monadic. And is, for that very reason, a great tutorial on monads, even if it's not a monad tutorial.
- signa11 10y ago> It's a monad tutorial... this would be closer to Haskell arrows than monads no ?
- marcosdumay 10y agoThis is one of the tutorials that made monads click for me (the other was the actual explanation at Learn You a Haskell). It's the Either monad, plain and simple.
- Roboprog 10y agoAnd here I was thinking it's about a practice of returning & accepting a tuple of ( primary-result xor dead-already-cuz ) and morphing the (primary) result type as the "f * g * h of x" pipeline cascades.
- piaste 10y agoHighly relevant: https://fsharpforfunandprofit.com/about/#banned https://fsharpforfunandprofit.com/about/#banned Seriously! As I make clear on the home page, this site is not targeted at mathematicians or Haskell programmers. It is targeted at the vast numbers of C#, VB and Python programmers who are coming to functional programming for the first time. F# is a fantastically accessible language for the average enterprise programmer, but mathematical jargon puts a lot of people off ("a monad is a monoid in the category of endofunctors, what's the problem?"), and I think it is much better to explain F# with concepts from within its native environment, rather than using terminology that originated elsewhere and is often not applicable. For example, treating F# computation expressions like Haskell monads can often make things more confusing. Doing this also helps to bypass the "how can you get anything done in language X? It doesn't even have y." debate and focus on what F# can do well.
- bbcbasic 10y agoYes. On the opposite end of the spectrum is any Reddit answer or blog post by Edward Kmett but I for some reason I love reading his answers even if I have no idea what he is talking about! However his audience would be advanced Haskellers or researchers.
- cheepin 10y ago(2013)
- Animats 10y agoThe gyrations needed for error handling in functional programming are painful. As Rust libraries become more functional, Rust is getting more of those problems. The problems created by not having exceptions are tougher than the problems created by having exceptions.
- techdragon 10y agoErlang style "fail noisily and let the supervisor handle it" is quite a solid way to deal with "exception handling bloat" in any paradigm, functional or otherwise... The hard part is finding a way to create effective layers of supervision.
- hvidgaard 10y agoAn exception is a noisy failure, and the supervisor is whatever try/catch that it bubles up to. Still, Erlang style has it's own complexities. It is in essence a network of micro services, and creating that overlay network and manuvering in it isn't simple.
- aangjie 10y agoYep.. with python assert statements + supervisorctl has been a very good setup for scaling a low latency, clean chat filtering app.
- hvidgaard 10y agoF# has exceptions. It's a tool that has it use at times, but they are in essence a goto
- brian_cloutier 10y agoEvery single control flow tool you've ever used is in essence a goto. Every conditional, every loop, every function call. Many modern function calls are in some respects _worse_ than gotos ever were, you don't even know which code you're going to jump to. It's not goto's that were so painful, it was unstructured gotos. Calling exceptions gotos is not a reasonable criticism. They have some very well-defined structure, and additional benefits like separating your happy-path code from your error-handling code, making both simpler.
- transfire 10y agoThis is a tutorial on how to get a nose bleed.
- enricosada 10y agoI really think that's an useful tutorial for all languages with exceptions ( that's an exceptional event ) and normal control flow ( application error, validation, retry ). Like that code become really simple, but more expressive than returning an int error code each function. A function can return an error with messages or message+data or message+retrycount etc. With F# (can be done in other languages obv) it's really easy to have different success/failure return types ( amazing type inference ) without writing too much code or having issues with maintenance ( the compiler does his job for us ). Like that, it's easy to create simple pure function, easier to test and reason about.
- logicallee 10y ago>for all languages with exceptions ( that's an exceptional event ) Unless, like me, you expect the unexpected. // if we're still here, guess it worked! return retval; }
- novaleaf 10y agoFYI, this "railway" approach is basically the way Promises work.
- thinkMOAR 10y agoEvery programming i do or language i use where there are linked lists i already have to think of trains :)
- jarcane 10y agoIronically, it was accidentally trying to reinvent this pattern in Elm that simultaneously made me give up on Elm and finally understand what good monads are. This is a really cool tutorial, I look forward to sinking my teeth into it.
- agumonkey 10y agoPardon the unwise bit of word play http://www.calcentral.com/~monadrailway/Monad/Welcome.html http://www.calcentral.com/~monadrailway/Monad/Welcome.html To be combined with Amtrak logo obviously. ps: Dan Pinoni had an implementation running on ascii http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html http://blog.sigfpe.com/2006/08/you-could-have-invented-monad...
- pyrale 10y agoThere's one thing I don't understand in the following signature provided for bind : val bind : ('a -> Result<'b,'c>) -> Result<'a,'c> -> Result<'b,'c> The author says that it takes one parameter, a function and returns another function, but then why are there 3 args in the signature ? I would have expected something like this : val bind : ('a -> Result<'b,'c>) -> (Result<'a,'c> -> Result<'b,'c>) for something that takes a function and returns another function adapted to the input, or something like this : val bind : ('a -> Result<'b,'c>) -> Result<'a,'c> -> Result<'b,'c> for a function that takes a function G and an input I and applies G to I if possible ad returns the eventual result (curried, Haskell-style). What am I missing about F# ?
- elros 10y agoI don't know much about F#, but in a language with currying, such distinction does not exist, given f(x, y) == f(x)(y)
- pyrale 10y agoMy puzzlement came from the fact that : f(in -> out)(in') -> out == f((in -> out), in') -> out and f(in -> out) -> (in' -> out) are similar. But thinking some more about it, I don't see a good reason for which this would be a problem. This simply means that any function defined to take [] elements is also able to take [:x] and return a function taking [x:]... I hadn't thought about this particular thing until now, but this kind of halfway-through computation is interesting.
- grndn 10y agoYou are on the right track (no pun intended). Your second and third function signatures are actually the same thing in F# (and any other language with curried functions by default). Similar functions such as "map" and "filter" can be thought of the same way. A big benefit of currying by default is that all functions can be treated as one parameter functions -- a very powerful tool for function composition. Also, providing only some of the parameters (e.g. the first) and leaving some to be provided later is the technique known as "partial application" -- another key tool in functional programming. If you think these things look interesting, you should for sure look into F#/OCaml/Haskell/Elm/etc.
- hatsunearu 10y agoHow is a binary "good vs. bad" result going to work? Don't you think it is necessary to have many many "bad" conditions--i.e. errortypes? You're just going to have to hide that away and that just drives this paradigm moot.