As the author says, there's quite a lot of imperative stuff in this design. I'm still on the fence about whether that's the best way to build large applications with GUIs, network access, etc.
With the imperative approach, you make liberal use of the IO monad. There's a lot of explicit reading from and writing to mutable storage. If you're doing this approach right, you mostly just use the IO monad for actual IO and threading; most of the real logic of the program is kept pure. This approach has the advantage of being familiar. And more importantly, it just plain works. It's how I tend to do things.
Yet I can't help but wonder if there's a better way. The above approach, while comfortable, leaves me with a bad taste in my mouth, like I'm somehow fighting against the language. I've often heard functional reactive programming (FRP) described as the best alternative. Though I remain skeptical. I'd be interested in opinions about the future of FRP.
Seems like FRP is catching on in other languages (as steveklabnik's sibling comment mentions, Javascript, and in C# and Objective C) but in Haskell it still seems to be a wash; there are a bunch of competing frameworks and, as far as I can tell, no clear leader. I used reactive-banana to do a school project last year, and it was ok but not on the level of Rx or ReactiveCocoa as far as I can tell. There are a half-dozen or so other frameworks, and some of them are implemented differently from others as the research moves in different directions (different ways of representing events/signals, using arrows, etc). Of course, for this specific use case (GUIs) there are similar issues in terms of implementations of GUI toolkits in Haskell (GTK? wx? some other half baked ones? and so on)
But back to your other point, sure you can write imperatively in Haskell and use IO and so on, but to really take advantage of the strengths of Haskell you need to write declaratively (i.e. functionally) and take advantage of the ways that helps you write things like GUIs (which are naturally declarative).
I dont think you need FRP to do that. In ReactJS, view code is pure, dom event callbacks just return new states[0], and all IO (ajax data access), async pipelines etc stay at the very top of your application at the root of the view hierarchy. Business logic is just functions of data values and/or appstate values. Which is exactly how I imagine the idiomatic haskell solution would look.
[0] dom callbacks actually swap! the nextState value so there are effects down there at the bottom of the view hierarchy, but that's react's fault for not letting you return the next state. e.g.
Not sure if "Architecture" is the right word here. More like, "How I built a Real World Haskell Application".
When I read about how to "architect" something I'm think about how to structure my Cabal file (a common pattern in my apps is a "library" of types, parsers, and utilities that are jointly used by multiple executables of the same program). I also think about structuring my tests, the naming and structure of module directory hierarchies, maybe also how to structure the program around the Main entry point.
I think there may also be a more interesting couple of "sub-articles" in this article: "How I built a server daemon in Haskell" and "How I built a GUI client in Haskell".
If architecture in the computing world consists of a system’s elements; the relationships between those elements; the attributes of the elements; and the attributes of the relationships, then architecture is not a timeline, process or stack description.
> it could benefit from the lens library, but last time I tried it did have problems with compilation with profiling information
In my experience, template haskell does not play well with profiling. If you were deriving lenses with TH, you could try writing them out yourself. That might solve this issue.
The industry appears to be very risk-averse (even though they have their reasons), so I'd be surprised to see a modern, functional language being used for critical tasks. However, C++ sometimes is used for those tasks, which boggles the mind.
Very cool to see Haskell being used more in the space space. I've recently built a command line tool in Haskell with a subset of these features for my team's testing:https://github.com/dangirsh/Auto
I agree that the existing tools are pretty limited
[+] [-] jarrett|12 years ago|reply
With the imperative approach, you make liberal use of the IO monad. There's a lot of explicit reading from and writing to mutable storage. If you're doing this approach right, you mostly just use the IO monad for actual IO and threading; most of the real logic of the program is kept pure. This approach has the advantage of being familiar. And more importantly, it just plain works. It's how I tend to do things.
Yet I can't help but wonder if there's a better way. The above approach, while comfortable, leaves me with a bad taste in my mouth, like I'm somehow fighting against the language. I've often heard functional reactive programming (FRP) described as the best alternative. Though I remain skeptical. I'd be interested in opinions about the future of FRP.
[+] [-] jcurbo|12 years ago|reply
But back to your other point, sure you can write imperatively in Haskell and use IO and so on, but to really take advantage of the strengths of Haskell you need to write declaratively (i.e. functionally) and take advantage of the ways that helps you write things like GUIs (which are naturally declarative).
[+] [-] steveklabnik|12 years ago|reply
[+] [-] marcosdumay|12 years ago|reply
I'm looking at a very similar problem (in form, not area), and literaly wondering that...
[+] [-] dustingetz|12 years ago|reply
[0] dom callbacks actually swap! the nextState value so there are effects down there at the bottom of the view hierarchy, but that's react's fault for not letting you return the next state. e.g.
[+] [-] ixmatus|12 years ago|reply
When I read about how to "architect" something I'm think about how to structure my Cabal file (a common pattern in my apps is a "library" of types, parsers, and utilities that are jointly used by multiple executables of the same program). I also think about structuring my tests, the naming and structure of module directory hierarchies, maybe also how to structure the program around the Main entry point.
I think there may also be a more interesting couple of "sub-articles" in this article: "How I built a server daemon in Haskell" and "How I built a GUI client in Haskell".
[+] [-] Spearchucker|12 years ago|reply
If architecture in the computing world consists of a system’s elements; the relationships between those elements; the attributes of the elements; and the attributes of the relationships, then architecture is not a timeline, process or stack description.
[+] [-] egonschiele|12 years ago|reply
In my experience, template haskell does not play well with profiling. If you were deriving lenses with TH, you could try writing them out yourself. That might solve this issue.
[+] [-] z3phyr|12 years ago|reply
I would love to read more about mainstream functional language being used in scientific domains like CERN, ESA, NASA or SpaceX.
[+] [-] outworlder|12 years ago|reply
Then again, that might just be a wrong impression I got from reading, among other things, "Lisping at JPL" (http://www.flownet.com/gat/jpl-lisp.html)
[+] [-] Raphael|12 years ago|reply
[+] [-] dangirsh|12 years ago|reply
I agree that the existing tools are pretty limited
[+] [-] unknown|12 years ago|reply
[deleted]