Apfelmus writes Haskell tutorials on lazy evaluation, finger trees, monoids, and the operational monad.
Commenters call the lazy evaluation series a substantive, unusually well-crafted tutorial, and HN links it for explaining Haskell concepts clearly.
First, going straight to "How do I understand Monads?" is not a good idea. I remeber when this article showed up on the web, and I remember wishing it had been written before I started learning Haskell:
https://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/
If you want to understand monads, start hacking and watch for patterns.
> But, just to be super honest -- and possibly completely wrong -- the terminology is really off-putting. At a glance it just feels super complex, academic and completely divorced from practical coding. I get vibes of enterprise java class hierarchies looking at this stuff.
Yeah, and here's my take on why it looks like that:
First, the terminology is all borrowed from mathematics, hence the academic tone. People can debate on the merits of this; I think it makes more sense when you're making tools for folks who are already familiar with the usual notation, but e.g. if you're not dealing with people who are already accustomed to the way physisicts talk about things, "p" is probably not the best variable name for momentum, traditional as it may be.
The authors of that document seem to have gone even farther in that direction than the Haskell folks -- Setoid? really? It's just fing equals! even Haskell calls it Eq. At least they kept Ord.
Also, the design looks to be basically transliterated from Haskell. There's been no attempt to adapt it to either javascript's strengths or its weaknesses. For example:
…
Because so far noöne has figured out the set of extensibility points needed for a language-agnostic one that doesn’t result in horrible bloat and sprawling API surfaces. The original language-agnostic IDE—Emacs—is probably the simplest, and it’s still quite complex. Acme[2] is interesting, but Spartan when it comes to actual IDE-ish features, and its UI always rubbed me the wrong way.
I feel this is somewhat related to the fact that noöne has figured out how to do extensible widget toolkits or scene graphs either. (Yes, Electron does in fact solve an actual problem, if in a profoundly unsatisfying way.) Actually, just a text input box that could handle the complexities of the world’s writing systems (RTL, complex font shaping, arbitrary input methods, autocorrect, all that with at least one cursor or selection) and was capable of supporting the facts vs rumors approach from FRP[1] would be a significant advancement re toolkits. As for scene graphs, I don’t actually know of any viable general approaches to assembling an interface out of independent parts (that doesn’t work by presupposing a large substrate of features in the host “shell” and providing a separate extension point for each of shortcut, menu item, toolbar button, sidebar, dialog, ...).
Actually, now that I’ve written all of that out, it seems that another way to put my second point is that the language-agnostic IDE problem is a proper superset of the composable GUIs problem, and nobody knows how to solve that…
This is where "event switching" comes in. Unfortunately, I have not used Elm or FlapJax, so I am not sure if the terminology is the same there.
Traditional FRP has two main concepts: behaviors, which are values that can change continually, and stream of events. Scanning over this blog post, these ideas correspond roughly to Properties and EventStreams respectively in Bacon.js.
Event switching is just having an event stream that itself contains behaviors. There's a great blog post[1] about this using Reactive Banana and Haskell.
[1]: http://apfelmus.nfshost.com/blog/2012/09/03-frp-dynamic-event-switching-0-7.html
Most of the post is fairly Haskell-specific, talking about the type system, but the basic idea should be applicable here as well.
The running example is a bar tab. You want to be able to create new entries in the tab, which are just text entries that give you a price. So you would create something like
entries :: Event [Behavior Price]
That is, you have a stream of events that contains behaviors corresponding to each text entry widget you've added. This makes calculating things like the sum of all the widgets relatively easy.
I'm not sure how other libraries support this dynamic event switching though. My understanding is that it is somewhat tricky to implement efficiently.
I'm happy to see finger trees got mentioned. Finger trees[0] are extremely useful and general data structure that can be used to implement persistent sequences, priority queues, search trees and priority search queues. (Haskell's Data.Sequence[1] uses specialized 2-3 finger trees internally) They can form the basis of all sorts of interesting custom structures by supplying the appropriate monoid[3], but this does make them harder to approach if you are not familiar with the abstractions.
[3] A monoid is any structure that has members that can combine associatively. In addition, it must have an element that can combine with any other element and result in the other element. Some examples: (strings, string concatenation, the empty string); (integers, addition, 0); (natural numbers, max, 0); (booleans, and, True); (functions, composition, the identity function). The functional pearl[2] that describes the design of Haskell's diagrams library[4] goes into much more detail if you are interested in their application to programming.
[0] http://apfelmus.nfshost.com/articles/monoid-fingertree.html
[1] http://hackage.haskell.org/package/containers-0.5.4.0/docs/Data-Sequence.html
[2] http://www.cis.upenn.edu/~byorgey/pub/monoid-pearl.pdf
[4] http://projects.haskell.org/diagrams/
If you want to work in an environment where a lot of people are thinking like this routinely, instead of a few lone voices in a vast sea of otherwise uninterested people, the Haskell community is doing a lot of work in this area, and able to move much faster since it's so much easier in Haskell than C++ templates (which isn't really a criticism of C++ templates, a lot of their capabilities are accidental rather than intended). This is why the Haskell community talks so much about monoids and applicatives and semigroups and a variety of other interesting structures in that area (and no, I did not forget to say monad, that structure is actually uninteresting here because it is too powerful). I believe the Fortress language is also doing some work here.
A sample of the interesting sort of algorithm work that you can do when you think this way: http://apfelmus.nfshost.com/articles/monoid-fingertree.html
Edit: See also the Typeclassopedia: http://www.haskell.org/haskellwiki/Typeclassopedia And if you're really interested and want to take it hardcore, Edward Kmett's video on his lens library walks through how you can derive it with this sort of logic: http://youtu.be/cefnmjtAolY?hd=1
Hmm. HN likes substantive articles and dislikes sketchy tactics. Those two almost never conflict. When they do, though, we tend to favor the substantive article, which this one clearly is. It's an elementary tutorial, yes, but an unusually well-crafted one, and had it appeared on the author's website (http://apfelmus.nfshost.com/blog.html), there'd be no question.
Perhaps the positive reinforcement of seeing what actually works to get on the HN front page—solid content—will combine with earlier negative reinforcement—prior sketchy tactics have gotten this site penalized—to induce a change in behavior. I know that sounds unicorny, but the last time something like this came up on HN, a different site actually cleaned up its ways. Maybe lightning will strike twice.