4 ms·
The article claims to be about the power of Applicative (and/or spreadsheets?), but I've been writing Haskell for about a year and am comfortable with all of th
by thinkpad20 12y ago
The article claims to be about the power of Applicative (and/or spreadsheets?), but I've been writing Haskell for about a year and am comfortable with all of the canonical Haskell abstractions including `Applicative`, and this made basically zero sense to me. Beyond familiarity with Applicative, the author also assumes the reader has facility with Controller, Fold, Managed, View, the Pipes library, Lens, and a host of functions I had never seen, such as last (not the Prelude version), stdinLines, tick, and runMVC. Assuming this, he throws out the definition of Updatable on top of that like it makes perfect sense ("just a Fold sitting in front of a Managed Controller". Oh, well then.). Basically, two or three paragraphs in and I am already completely lost. I don't even know what problem it is we're trying to solve, and I have no idea what it has to do at all with spreadsheets.
This is one of the downsides of Haskell; with so much emphasis on abstraction, code often ends up being just that: so damn abstract that it's practically inscrutable except to the very few who are familiar with what's going on. I guess this article was written for an audience with very broad and detailed knowledge of some complicated Haskell libraries -- meaning it's not so important that anyone else be able to make head or tails out of what he's talking about. Which is ok, but it does add to the impression that Haskell is an exclusive club.
Also, this part sticks out as confusing: The type signature of `example` does not include IO (unless Updatable has IO on under the hood), and yet the language above suggests that it will change, i.e. that it is mutable:
> example will update every time lastLine or seconds updates, caching and reusing portions that do not update. For example, if lastLine updates then only the first field of Example will change. Similarly, if seconds updates then only the second field of Example will change.
Can someone clear this up for me?
- gcv 12y agoI confess that I also do not understand the code in the article. (But I am still only a student of Haskell.) I can only guess, based on my own work with this idea of Cells-type programming, that the author means the following: Suppose you have three data nodes, or cells: A, B, C, and D. A holds the value 5, B holds 3, C is defined as A+B, and D is defined as B*C. In a spreadsheet, changing cell A will automatically update C, because C directly depends on A. It will also update D because it transitively depends on B through C, and C has changed. This library (and the Clojure one I mentioned in my other post) lets you define data structures which behave the same way. In a pure environment, you can emulate this using only functions. In a non-pure environment, automatically updating values can be quite nice. You use this to implicitly trigger linked behaviors. In a UI, this could mean changing the state of several elements in response to some input without having to explicitly say updateElementA(), updateElementB(), and so on.
- thinkpad20 12y agoThanks, yeah that's really helpful in getting a sense of the problem this is attempting to address. I can definitely see why it's nice to have a simple (to use) and compact API behind this. I wish that Gabriel had taken a similar approach in explaining this library (start with a description of the problem, then a high-level idea for a solution, then some specifics, etc). But regardless, I have the utmost respect for Gonzalez, and give him props for what looks like a(nother) great library.
- Gabriel439 12y agoIf you want to familiarize yourself more with my `mvc` and `foldl` library, you can find the blog posts describing them here: http://www.haskellforall.com/2014/04/model-view-controller-haskell-style.html http://www.haskellforall.com/2014/04/model-view-controller-h... http://www.haskellforall.com/2013/08/composable-streaming-folds.html http://www.haskellforall.com/2013/08/composable-streaming-fo... It might seem like too much abstraction until you realize that the alternative would be the following obtuse type: data Updatable a = forall x y . Updatable (forall r . ((x, x -> y -> x, x -> a, STM (Maybe y)) -> IO r) -> IO r)) That's what you get if you completely expand out the implementation of `Updatable`. This is why I build up these abstractions from smaller composable pieces (i.e. `Fold` and `Managed` and `Controller`), each of which is intrinsically useful in isolation. However, I think if you are trying to understand how `Managed` and `Controller` and `Fold` work all in one go, you're going about it the wrong way. Haskell lends itself really well to abstracting over the implementation by specifying mathematical equations inspired by category theory that the implementation obeys. This is not the fake kind of abstraction that other languages promise but never actually deliver (i.e. abstractions that leak and forces you to read source code, often times several layers deep). Rather, everything you need to know about the abstraction layer immediately underneath you is completely summarized by a succinct set of equations that you can then use to prove a new set of equations for the immediately following layer. This post gives an example of this layered proof process: http://www.haskellforall.com/2013/12/equational-reasoning.html http://www.haskellforall.com/2013/12/equational-reasoning.ht... By composing these small, correct-by-construction layers of equations you can grow to arbitrary complexity while always preserving correctness. More importantly, you never need to reason about more than a single layer at a time since you've decoupled each layer's correctness proofs from each other. Contrast this with other languages where you often have to reason simultaneously over many layers of abstractions to debug difficult issues or prove correctness. To answer the meat of your question, all you really need to know to understand how `Updatable` works is that: * `Fold e` is an `Applicative`, for all `e` * `Managed (Controller e)` is a `Monoid`, for all `e` * `onLeft` and `onRight` are `Applicative` homomorphisms (this detail is noted in the library source code but I omitted it from the blog post) Those four properties concisely summarize everything you need to know about every abstraction underneath `Updatable`. If you approach this correctly, there is no need to dig into their source code further to understand how they work. Truthfully, I would love if you were to dig into their source code to learn how they work, but if you really want to level up as a programmer then you need to start thinking more abstractly, layer-by-layer, instead of trying to fit the entire programming stack into your head all at once.