That said, it's not something to actually make use of if you're trying to make your code readable, since the keywords are so tightly coupled to the LINQ use case.
I would almost never recommned doing something like this given the maintenance issues and how long it takes to bring the average C# programmer up to speed, but this was three fairly advanced FP folks working on the application. It was probably some of the cleanest C# I've gotten to work with.
My use case was basically filters: you have three dropdown lists that change based on the ones you select previously. Power BI and MS Excel filtering is good enough to solve the problem.
I wonder if there is something written about how MS Excel handles filtering internally; maybe it is something like a directed graph?
fx {
val (x) = action() // A<B>, where Monad<A>
val y = x + 5 // "pure" function
y
}
The block evaluates to a value of type A<B>. It's going the get even better when Arrow meta is ready for prime time. Arrow is like a neat functional backdoor language hidden inside what seems to be just Java 2.0.It is therefore incumbent upon Haskellers to make the superiority of powerful abstractions like the monad abundantly clear through the propagation of high-quality software using said abstraction. :)
Those languages that choose to use options or results with ?. instead of null or exceptions are already choosing to avoid impure functions and use static typing. Monads work fine with strict evaluation (indeed we see post-Haskell languages e.g. Idris using a strict evaluation model).
I am not a fan of them, as I prefer working with Haskell/purescript do's, but the people I work with enjoy them.
Instead of dedicated syntax and language features like try-catch exceptions for things that can go wrong, ? for potentially absent values, just use a single, consistent abstraction that covers all use cases and doesn't require any syntax or language features at all. (=monads)
It's a general-purpose programmable syntax similar to do-notation that supports monadic, applicative, and other operations.
.. first from google search https://github.com/pelotom/burrido
I haven't actually seen anyone use this in practice though.
Rust is inspired by PL staples like Haskell and OCaml (borrowing concepts and syntax from them), and was partially designed by PL researchers. The lineage of the borrow-checker in Rust goes back a long way to lots of academic works in region-based memory management and linear logic.
I'm also fond of of the data generation DSLs in property testing libraries, which tend to lean heavily on monads.
I continue to find that, outside of lazy functional programming, where you need them to live, monads are at their best when they're used in understated ways where the pattern may not even be mentioned by name. All too often, they end up feeling more like something Rodney Dangerfield's character from Caddyshack would use to play code golf.
I don't think this analogy sets up anyone for success. For a long time now I've wanted to do a series on "FP for OOP folks".
If a semicolon is programmable it obviously can also decide not to execute later computation. Otherwise it wouldn't actually be customizable.