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.

Reply via email to