Sasa author here, thanks for the nice write up! I have a lot more posts coming. My goal is to write one post a day on average, until every abstraction in the v0.9.4 release is covered, then v0.9.4 final will be released. It's been a long time coming.
While parser combinators can be expressed functionally on .NET, even in C#, after having written a few such combinator libraries I've found that
Pratt parsers strike a better balance between simplicity and performance on the CLR. Pratt parsers also naturally handle operator precedence, while parser combinator libraries require more complicated structures to express these relationships. The extensible
parser in the above link will be available in an upcoming release of my open source Sasa class library, so check it out if you're interested in this domain.
(this is a response to people who are befuddled by purely functional programming)
I can answer your questions with a thought experiment:
If it's ok for a function to return arbitrary values when you call it with the same parameters, how does this affect the behaviour of other functions? Should 1+1 always = 2? Should Console.WriteLine("Foo") print "bar"? If functions don't behave only according
to the parameters you pass in, how do you specify how the function should behave? In other words, how do you program? Further, how can you ever hope to reason about or debug code that changes behaviour arbitrarily?
This is why current languages provide a mix of purely functional behaviour (like integer addition), and "impure" behaviour which is harder to reason about. The more "pure" the behaviour, the more predictable and deterministic the program is, which means it's
easier to understand and debug, and you can gain a higher confidence in its correctness.
I wrote a post about a number of advanced languages features which I think most people misunderstand or downplay the value of: