What prompted me to write Zelkova? The short answer is curiosity and gut feeling. The long answer:
I consider core.async (and CSP in general) to be an excellent low-level abstraction for coordinating concurrency, but I feel like it relies way too much on mutating operations for me to want to use it much directly in application code. Like any other mutating code, I want to push it to the edges as much as possible. Along those lines, I had previously explored using core.async with JS promises [1] and "async futures" [2]. Promises and futures are great (pseudo-?)immutable constructs for representing single "eventual values", but don't really help at all with values that change over time. So I wanted to build an FRP library based on core.async, which seemed like an obviously strong foundation for FRP that was surprisingly under-explored as such. At first I made some initial stabs at modelling a system after Bacon.js, which at the time I considered more attractive than Elm's style of FRP. However, I was fighting too much with core.async to make it work, and it just felt like the wrong direction. I decided to read Evan Czaplicki's 2012 thesis on Elm to understand that different perspective better, and the more I understood it the more compelling I found that approach. I had a very similar experience with the paper as Eric Normand recently described [3], and that Concurrent ML code was just begging to be ported to core.async :) The fact that Elm's signal graphs are static does present some challenges, but it also brings real benefits (as Evan outlines well in his talk that I linked in the original post). People are still figuring out how best to structure larger applications in Elm, but I see a lot of potential. At its best, Elm code is some of the clearest code I've seen, with almost zero "baggage" (read: incidental complexity). Furthermore, Zelkova brings its own advantages by being embedded in and implemented entirely in Clojure/ClojureScript. You can reach outside the strictness of the signal graph whenever you need to, and continue using the same nice language as when you're working "from within" a graph. Needless to say, development in Clojure also helps immensely with implementing the library itself. [1]: https://github.com/jamesmacaulay/cljs-promises [2]: https://github.com/jamesmacaulay/async-tools/blob/master/test/cljx/jamesmacaulay/async_tools/core_test.cljx#L62-L82 [3]: http://www.lispcast.com/elm-frp-clojure-core-async On Saturday, 6 December 2014 07:01:30 UTC-5, eric wrote: > > Hi, > > May I ask what prompted you to write this? A coding exercise or some > real-world need? I'm asking because I've been keeping an eye on FRP for a > while. From what I understand it's conceptually not ready for anything > other than toy problems yet. Like Elm's restriction on static flow graphs. > It's like programming without 1st class functions, you don't get very far. > > eric > > On Monday, October 20, 2014 11:56:45 AM UTC+11, James MacAulay wrote: >> >> I've just published an FRP library based on Elm[1]: >> >> https://github.com/jamesmacaulay/zelkova >> >> Here's what the app code looks like: >> >> >> https://github.com/jamesmacaulay/zelkova/blob/4b06c49678e11e3af7b1eda7a18929a512f7753d/examples/mario/src/mario/core.cljs#L118-L133 >> >> Right now Zelkova includes ports of Elm's Signal, Mouse, Keyboard, and >> Window libraries, plus part of its Time library[2]. Zelkova's signal >> namespace works in both Clojure and ClojureScript, but the rest only have >> implementations for ClojureScript in the browser. >> >> Elm-style FRP is a bit different from other flavours like those of Rx or >> Bacon.js. In particular, Elm's signal graphs are static (can't be >> reconfigured once they start running) and don't allow for >> signals-of-signals. >> >> Zelkova is the same way, but its signal functions actually return >> "recipes" for signals which don't start processing values until a "live" >> graph gets spawned from one of them. This allows multiple live graphs to >> run concurrently while sharing logical structure, and should make some >> things easier in the future (like porting Elm's time-travelling debugger). >> Theoretically this should also make it possible to compile some kinds of >> signal graphs into transducers instead of running them as networks of >> core.async channels. >> >> If you're interested in the differences and tradeoffs between the >> different forms of FRP out there, Evan Czaplicki gave an excellent talk on >> the subject at Strange Loop this year: >> >> https://www.youtube.com/watch?v=Agu6jipKfYw >> >> Cheers, >> James >> >> [1] http://elm-lang.org >> [2] >> https://github.com/jamesmacaulay/zelkova/tree/master/src/cljx/jamesmacaulay/zelkova >> >> -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.