<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Dimagog Blog</title>
 <link href="http://dimagog.github.io/" rel="self"/>
 <link href="http://dimagog.github.io"/>
 <updated>2026-09-08T07:50:35+00:00</updated>
 <id>http://dimagog.github.io</id>
 <author>
   <name>Dmitry Kakurin</name>
   <email>dmitry.kakurin@gmail.com</email>
 </author>

 
 <entry>
   <title>Clojure All The Way - Deep Knockout</title>
   <link href="http://dimagog.github.io/blog/clojure/clojurescript/2013/07/31/clojure-all-the-way-deep-knockout"/>
   <updated>2013-07-31T00:00:00+00:00</updated>
   <id>http://dimagog.github.io/blog/clojure/clojurescript/2013/07/31/clojure-all-the-way-deep-knockout</id>
   <content type="html">&lt;p&gt;This is a fourth and final article in mini-series. The goal of mini-series is to create a Client-Server environment
where Clojure data structures are pervasive and we don’t have to deal with JSON and JavaScript objects 
in Clojure/ClojureScript land (as much as possible).&lt;/p&gt;

&lt;p&gt;Building up on the [previous post][] we will achieve much deeper integration of Clojure data structures with
&lt;a href=&quot;http://knockoutjs.com/&quot;&gt;Knockout.js&lt;/a&gt;. But it comes with a price …&lt;/p&gt;

&lt;h2 id=&quot;our-goal&quot;&gt;Our Goal&lt;/h2&gt;

&lt;p&gt;By the end of the [previous post][] we’ve implemented &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;observable-ref&lt;/code&gt; that completely hides
Clojure-to-JavaScript conversion call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clj-&amp;gt;js&lt;/code&gt; function, but &lt;em&gt;we know&lt;/em&gt; it’s still there.&lt;/p&gt;

&lt;p&gt;Maybe it’s silly to worry about it, but I still do. So what if we set our mind to get rid of it completely,
and have “turtles all the way down”? That’s my goal for this post and it’s up to the reader
to decide if it is achieved or not :-).&lt;/p&gt;

&lt;h2 id=&quot;know-the-enemy&quot;&gt;Know the Enemy&lt;/h2&gt;

&lt;p&gt;Let’s have a detailed look at what our Clojure data structures are and what our “enemy” (for this post)
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clj-&amp;gt;js&lt;/code&gt; does for us.&lt;/p&gt;

&lt;p&gt;The data we are rendering (headers of HTTP request) is a Clojure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; of 2-element &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vectors&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strings&lt;/code&gt;.
In type-safe language like C# or Java it would be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Vector&amp;lt;Vector&amp;lt;string&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clj-&amp;gt;js&lt;/code&gt; function recursively converts our Clojure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vectors&lt;/code&gt; into
JavaScript &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Arrays&lt;/code&gt;. I.e. not only outer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; is converted, but each element of it
(inner &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strings&lt;/code&gt;)
is also converted to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array&lt;/code&gt;. The recursion stops there because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; representation is the same
across ClojureScript and JavaScript and no conversion is needed.&lt;/p&gt;

&lt;h2 id=&quot;the-easy-part---inner-vectors&quot;&gt;The Easy part - Inner vectors&lt;/h2&gt;

&lt;p&gt;Later in this post it will become clear why this is the easy part, but let’s start with inner &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vectors&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Code samples include only interesting parts, &lt;a href=&quot;#src&quot;&gt;full source code is available below&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;shallow-outer-vector-conversion&quot;&gt;Shallow outer vector conversion&lt;/h3&gt;
&lt;p&gt;We want to stop converting inner &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vectors&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Arrays&lt;/code&gt;. I.e. we don’t need a deep recursive conversion of outer
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clj-&amp;gt;js&lt;/code&gt; provides. Instead we want to convert outer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array&lt;/code&gt; and leave its elements intact.
The result of this step should become &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vectors&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strings&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is easy, we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into-array&lt;/code&gt; function in place of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clj-&amp;gt;js&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;observable-ref&lt;/code&gt; function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;observable-ref&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ko/observable&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;into-array&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add-watch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obs&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;obs&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;into-array&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The only changes to this function compared to the [previous post][] are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into-array&lt;/code&gt; calls in &lt;em&gt;lines 2 and 3&lt;/em&gt; where
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clj-&amp;gt;js&lt;/code&gt; calls used to be.&lt;/p&gt;

&lt;p&gt;Of cause if we try to render HTML now it won’t work because our &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; bindings look like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;td&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-bind=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text: $data[0]&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;td&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-bind=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text: $data[1]&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$data[0]&lt;/code&gt; access syntax does not work for Clojure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vectors&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;accessing-persistentvector-elements-from-javascript-code&quot;&gt;Accessing PersistentVector elements from JavaScript code&lt;/h3&gt;

&lt;p&gt;If we examine &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt;’s “class” &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PersistentVector&lt;/code&gt; from pure JavaScript perspective we’ll see the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nth&lt;/code&gt; method that
we want to call to get &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt;’s elements. But it looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;cljs$core$IIndexed$_nth$arity$2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;coll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We certainly &lt;em&gt;can&lt;/em&gt; call it from JavaScript, and it works:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cljs$core$IIndexed$_nth$arity$2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;but it’s not very user-friendly to say the least.&lt;/p&gt;

&lt;p&gt;Fortunately JavaScript is a very flexible and dynamic language. We can easily extend &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PersistentVector&lt;/code&gt; with
helper &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get&lt;/code&gt; method that we need:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;aset&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;aget&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;__proto__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;get&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;this-as&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nth&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We use empty vector &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[]&lt;/code&gt; in &lt;em&gt;line 1&lt;/em&gt; to get to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PersistentVector&lt;/code&gt;’s &lt;em&gt;prototype&lt;/em&gt;. And add a new method
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get&lt;/code&gt; that takes an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;index&lt;/code&gt; and returns element at that index for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this&lt;/code&gt;.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this-as&lt;/code&gt; in &lt;em&gt;line 4&lt;/em&gt; gives us access to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this&lt;/code&gt; from ClojureScript.&lt;/p&gt;

&lt;p&gt;Now we can change our &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; bindings in HTML file to use our new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get&lt;/code&gt; method:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;td&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-bind=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text: $data.get(0)&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;td&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-bind=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text: $data.get(1)&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Not too bad, and rather straight-forward. At this point our Client works again and we can see the table
of HTTP headers rendered correctly.&lt;/p&gt;

&lt;h2 id=&quot;the-hard-part---outer-vector&quot;&gt;The Hard part - Outer vector&lt;/h2&gt;

&lt;p&gt;The only piece of data conversion logic we have left is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into-array&lt;/code&gt; calls that convert our outer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt;
into JavaScript &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array&lt;/code&gt;. If we get rid of it - we’ve reached our goal.&lt;/p&gt;

&lt;h3 id=&quot;why-its-hard&quot;&gt;Why it’s hard&lt;/h3&gt;

&lt;p&gt;But this is where it becomes tricky. The problem is that we use &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt;’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foreach&lt;/code&gt; binding to iterate
over our collection of headers:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;n&quot;&gt;&amp;lt;tbody&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data-bind=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foreach: $root&quot;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foreach&lt;/code&gt; expects it to be JavaScript &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array&lt;/code&gt;. &lt;strong&gt;Period.&lt;/strong&gt; No kidding.&lt;/p&gt;

&lt;p&gt;I’ve tried to teach &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; to iterate over custom collection, and &lt;a href=&quot;https://groups.google.com/forum/#!topic/knockoutjs/P2XXc9q6k04&quot;&gt;I’ve asked KO group&lt;/a&gt;.
It’s not possible for now.&lt;/p&gt;

&lt;h3 id=&quot;should-we-give-up&quot;&gt;Should we give up?&lt;/h3&gt;

&lt;p&gt;At this point we still have achieved a tangible improvement: the &lt;em&gt;elements&lt;/em&gt; of our collection are
not converted anymore, so even when we create a copy of outer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; it is a shallow copy:
only the “skeleton” is copied, but elements are reused. And they potentially have a bigger memory
footprint.&lt;/p&gt;

&lt;p&gt;However there is a saying:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;If the mountain will not come to Muhammad, then Muhammad will go to the mountain.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In our case: if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foreach&lt;/code&gt; would not take anything but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array&lt;/code&gt; then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; should become an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array&lt;/code&gt;.
Or at least pretend to be one.&lt;/p&gt;

&lt;p&gt;Now how do we pretend? The access pattern from &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; is to read &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;length&lt;/code&gt; property first and then
read fields &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0], [1] ... [length-1]&lt;/code&gt;. We can easily add all these fields to our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; but
it defeats the purpose: we would copy all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; elements into fields &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;, etc.
It’s no better than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into-array&lt;/code&gt; call.&lt;/p&gt;

&lt;p&gt;If only there was a way to intercept field access calls in JavaScript …&lt;/p&gt;

&lt;h3 id=&quot;warning-danger-zone&quot;&gt;WARNING: Danger Zone&lt;/h3&gt;

&lt;p&gt;To the best of my knowledge there is no portable way to intercept field access in JavaScript.
So we’ll have to use &lt;strong&gt;JavaScript “Experimental Features”&lt;/strong&gt; that are already implemented by some
modern browsers (Firefox and Chrome support what we need), but are not standard yet and may not even be enabled by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is why the rest of this post is not practical [for now] but hopefully still entertaining.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you are willing to proceed and use Chrome, you must navigate to &lt;a href=&quot;chrome://flags&quot;&gt;chrome://flags&lt;/a&gt;
URL (enter it manually in address bar, Chrome blocks navigation to special pages
from random web sites :-), find &lt;strong&gt;“Enable Experimental JavaScript”&lt;/strong&gt;
feature and enable it.&lt;/p&gt;

&lt;h3 id=&quot;ecmascript-6-proxy-api&quot;&gt;ECMAScript 6 Proxy API&lt;/h3&gt;

&lt;p&gt;ECMAScript 6 draft specifies &lt;a href=&quot;http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies&quot;&gt;Direct Proxies&lt;/a&gt; - a mechanism to create a proxies that:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;… enable ES programmers to represent virtualized objects (proxies). In particular,
to enable writing generic abstractions that can intercept property access on ES objects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Exactly what we need!&lt;/p&gt;

&lt;h3 id=&quot;wrapping-outer-vector-in-a-proxy&quot;&gt;Wrapping outer vector in a Proxy&lt;/h3&gt;

&lt;p&gt;A new helper function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector-as-array&lt;/code&gt; makes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; sort-of look like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array&lt;/code&gt; in a narrow sense
required by &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt;. This is by no means a full proxy to emulate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Arrays&lt;/code&gt;, just a bare minimum
required for our purposes.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; only needs 2 things from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array&lt;/code&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;length&lt;/code&gt; field and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;, etc. fields. Well, we can give it
what it wants:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector-as-array&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Creates JS Proxy around Clojure vector to make it look like JS array,
  without copying data&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.create&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;js/Proxy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
           &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;js-obj&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
             &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;get&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
               &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                   &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;length&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                   &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
             &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;getPropertyDescriptor&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
               &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.getOwnPropertyDescriptor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;js/Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;js/Array&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get&lt;/code&gt; function &lt;em&gt;(lines 7-11)&lt;/em&gt; checks if accessed property name is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;length&lt;/code&gt; and returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;count&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v&lt;/code&gt; if it is
&lt;em&gt;(line 10)&lt;/em&gt;.
Otherwise &lt;em&gt;(line 11)&lt;/em&gt; it simply delegates to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt;’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get&lt;/code&gt; function to fetch individual element.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getPropertyDescriptor&lt;/code&gt; &lt;em&gt;(lines 12-14)&lt;/em&gt; is required for when &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; does “reflection” on our “array”
(like checking if “length” property exists) and simply delegates calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;js/Array&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;the-finish-line&quot;&gt;The Finish Line&lt;/h3&gt;

&lt;p&gt;The last change is to modify &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;observable-ref&lt;/code&gt; once again, this time replacing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into-array&lt;/code&gt; calls
with our newly-created &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector-as-array&lt;/code&gt; function:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;observable-ref&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ko/observable&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vector-as-array&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add-watch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obs&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;obs&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vector-as-array&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And it’s hard to believe, but &lt;strong&gt;IT WORKS!&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Here is a quick summary of our accomplishments:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We’ve marshaled Clojure data structure created on the Server all the way to the Client using &lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;edn encoding&lt;/a&gt;
which is a natural textual representation for Clojure data.&lt;/li&gt;
  &lt;li&gt;We’ve received this data on the client using core.async to make our code look sequential&lt;/li&gt;
  &lt;li&gt;Then we’ve &lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;edn-decoded&lt;/a&gt; response and called regular Clojure functions on received data to extract and sort the headers&lt;/li&gt;
  &lt;li&gt;We’ve animated our HTML page by manipulating only Clojure data structures&lt;/li&gt;
  &lt;li&gt;Finally we’ve created &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; bindings directly to Clojure data without EVER converting it to JavaScript.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Granted, the final step required sacrifices (using experimental JavaScript features), and this is why
I’ve mentioned above that it depends on reader’s point of view if final goal was achieved or not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I’ve certainly achieved my goal of learning new interesting technologies and I had lots of fun along the way!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And if anyone ever reads this, I hope you did too :-).&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;--source-code&quot;&gt;&lt;a name=&quot;src&quot;&gt; &lt;/a&gt; Source code&lt;/h2&gt;
&lt;p&gt;Full source code &lt;a href=&quot;https://github.com/Dimagog/dimagog.github.io/tree/ClojureAllTheWay4&quot;&gt;can be found on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to build and run it locally, execute:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/Dimagog/dimagog.github.io.git -b ClojureAllTheWay4 --single-branch ClojureAllTheWay4
cd ClojureAllTheWay4
lein ring server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>Clojure All The Way - Knockout</title>
   <link href="http://dimagog.github.io/blog/clojure/clojurescript/2013/07/22/clojure-all-the-way-knockout"/>
   <updated>2013-07-22T00:00:00+00:00</updated>
   <id>http://dimagog.github.io/blog/clojure/clojurescript/2013/07/22/clojure-all-the-way-knockout</id>
   <content type="html">&lt;p&gt;This is a third article in mini-series. The goal of mini-series is to create a Client-Server environment
where Clojure data structures are pervasive and we don’t have to deal with JSON and JavaScript objects 
in Clojure/ClojureScript land (as much as possible).&lt;/p&gt;

&lt;p&gt;This time we’ll continue building on [previous post][] and will integrate ClojureScript
with &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;Knockout.js&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;where-we-are&quot;&gt;Where we are&lt;/h2&gt;

&lt;p&gt;We start where we left off in the [previous post][]: we have a Server
that implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;echo&lt;/code&gt; HTTP API and calling it returns &lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;edn-encoded&lt;/a&gt; data.&lt;/p&gt;

&lt;p&gt;And we have a Client capable of calling this API, receiving data, and &lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;edn-decoding&lt;/a&gt; it.
But it displays the data (headers of our HTTP request) in a very primitive way
by simply setting text of DOM element.&lt;/p&gt;

&lt;h2 id=&quot;our-goal--clojurescript--knockout&quot;&gt;Our Goal = ClojureScript + Knockout&lt;/h2&gt;

&lt;p&gt;We’d like to nicely format received headers as HTML table.
We can of cause write ClojureScript code to build HTML for it using &lt;a href=&quot;https://github.com/weavejester/hiccup&quot;&gt;Hiccup&lt;/a&gt;-like library.
But where is fun in that!&lt;/p&gt;

&lt;p&gt;It would be more entertaining to use some JavaScript data-binding library.
First, because I like &lt;a href=&quot;http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller&quot;&gt;MVC&lt;/a&gt;-based approach. But more importantly because it will allow
us to explore ClojureScript integration with existing JavaScript framework.&lt;/p&gt;

&lt;p&gt;We’ll use &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;Knockout.js&lt;/a&gt; &lt;em&gt;(abbreviated &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; for the rest of this post)&lt;/em&gt; as it happens to be my favorite
&lt;a href=&quot;http://addyosmani.com/blog/understanding-mvvm-a-guide-for-javascript-developers/&quot;&gt;MVVM&lt;/a&gt; framework for JavaScript. And also &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; claims that 
it is very smart and highly optimized in minimizing DOM modifications, so I expect it to be efficient as well.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;There is an excellent 20-min &lt;a href=&quot;http://channel9.msdn.com/Events/MIX/MIX11/FRM08&quot;&gt;Knockout.js demo video&lt;/a&gt; on &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; web site. If you completely new to &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt;
I’d recommend to watch it first. It will make material below easier to understand, plus it’s a
truly &lt;a href=&quot;http://channel9.msdn.com/Events/MIX/MIX11/FRM08&quot;&gt;masterfully-done demo&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;naive-knockout-integration&quot;&gt;Naive Knockout integration&lt;/h2&gt;

&lt;p&gt;Let’s see what is the minimal effort required to integrate our code with &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt;, and then we’ll
improve on it.&lt;/p&gt;

&lt;h3 id=&quot;preparing-input-data&quot;&gt;Preparing input data&lt;/h3&gt;

&lt;p&gt;First we need to massage our data: headers are represented as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; but &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; requires it to be array’ish
collection if we want to use its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foreach&lt;/code&gt; binding. Easy enough: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; converted to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;seq&lt;/code&gt; is actually
a sequence of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vectors&lt;/code&gt;, each &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; being a key-value tuple. While we at it let’s sort it by header
name as well:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/api/echo&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get-edn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:headers&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sort-by&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sort-by&lt;/code&gt; is the only addition to our previous code. It converts &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;seq&lt;/code&gt; and also
sorts it by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;first&lt;/code&gt; element of each tuple, i.e. by header name.&lt;/p&gt;

&lt;p&gt;The last step is converting Clojure data to plain JavaScript data that &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; understands.
We do it by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clj-&amp;gt;js&lt;/code&gt; function that will recursively convert our Clojure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vector&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vectors&lt;/code&gt; into
JavaScript &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Arrays&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;clj-&amp;gt;js&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I know the whole premise of the series is to &lt;strong&gt;avoid&lt;/strong&gt; such explicit conversion. Please bear with me,
we’ll deal with it in following sections.&lt;/p&gt;

&lt;h3 id=&quot;adding-knockout-bindings-to-html&quot;&gt;Adding Knockout bindings to HTML&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Note: Code samples include only interesting parts, &lt;a href=&quot;#src&quot;&gt;full source code is available below&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We need to change our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;default.html&lt;/code&gt; as follows (only relevant parts are shown):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;app.js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;table&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;&lt;/span&gt;Header&lt;span class=&quot;nt&quot;&gt;&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;&lt;/span&gt;Value&lt;span class=&quot;nt&quot;&gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/thead&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;tbody&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-bind=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foreach: $root&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;td&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-bind=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text: $data[0]&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;td&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;data-bind=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text: $data[1]&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/tbody&amp;gt;&lt;/span&gt;
...
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;First we add reference to &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; itself in &lt;em&gt;line 2&lt;/em&gt;. Then we create a table &lt;em&gt;(line 7)&lt;/em&gt; with static headers &lt;em&gt;(line 8)&lt;/em&gt;
and &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt;-bound body &lt;em&gt;(line 9)&lt;/em&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foreach&lt;/code&gt; in &lt;em&gt;line 9&lt;/em&gt; iterates over &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$root&lt;/code&gt; binding &lt;em&gt;(not explained yet)&lt;/em&gt; expecting
it to be an array and replicates its HTML body for each element while binding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$data&lt;/code&gt; to it.&lt;/p&gt;

&lt;p&gt;In our case each element is a key-value tuple for each header represented as a 2-element array.
So &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;td&lt;/code&gt;s in &lt;em&gt;lines 11-12&lt;/em&gt; simply extract first element for the header name and second for the value.&lt;/p&gt;

&lt;h3 id=&quot;applying-root-knockout-binding&quot;&gt;Applying root Knockout binding&lt;/h3&gt;

&lt;p&gt;Now to connect our ClojureScript data to &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; bindings in HTML we just need to call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ko/applyBindings&lt;/code&gt;.
And our final code for this step looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/api/echo&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get-edn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:headers&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sort-by&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ko/applyBindings&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;clj-&amp;gt;js&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We obtain the data and massage it in &lt;em&gt;line 2&lt;/em&gt;. Then convert Clojure data to JavaScript using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clj-&amp;gt;js&lt;/code&gt;
and pass it as a root binding to &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ko/applyBindings&lt;/code&gt; in &lt;em&gt;line 3&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And viola!&lt;/strong&gt; Our headers are shown in a nice-looking table (with little CSS help):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://bufa.build/assets/table1.png&quot; alt=&quot;table1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now readers familiar with &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; are probably shaking their head in disgust:
no observables, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;applyBindings&lt;/code&gt; should be called only once (not from some potentially reusable
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt;-routine).&lt;/p&gt;

&lt;p&gt;And let’s not forget about explicit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clj-&amp;gt;js&lt;/code&gt; call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fear not! we’ll take care of it right away!&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;using-computed-observables&quot;&gt;Using computed observables&lt;/h2&gt;

&lt;p&gt;My first (but not final) improvement attempt is to use &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt;’s [computed observable] to do automatic
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clj-&amp;gt;js&lt;/code&gt; translation.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; documentation says that &lt;a href=&quot;http://knockoutjs.com/documentation/extenders.html&quot;&gt;extenders&lt;/a&gt;
could be a better fit, but I’m more familiar with computed observables.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First we create a helper function to build our [computed observable][]:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;observable&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ko/computed&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ko/observable&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;clj-&amp;gt;js&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;js-obj&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;read&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;write&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;clj-&amp;gt;js&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ko/computed&lt;/code&gt; observable &lt;em&gt;(line 2)&lt;/em&gt; takes a JavaScript object created in &lt;em&gt;line 4&lt;/em&gt; that specifies &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;write&lt;/code&gt;
functions. The actual state is kept in regular &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ko/observable&lt;/code&gt; created in &lt;em&gt;line 3&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; observables are functions. Calling it with no arguments returns current value and calling it
with one arguments sets its value. So &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(state)&lt;/code&gt; in &lt;em&gt;line 5&lt;/em&gt; gets the current &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;state&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(state (clj-&amp;gt;js new))&lt;/code&gt; in &lt;em&gt;line 6&lt;/em&gt; sets it (after converting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt; to JavaScript representation).&lt;/p&gt;

&lt;p&gt;Now our main code looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view-model&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;observable&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ko/applyBindings&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view-model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
 
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/api/echo&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get-edn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:headers&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sort-by&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;view-model&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We create our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;view-model&lt;/code&gt; in &lt;em&gt;line 1&lt;/em&gt; using our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;observable&lt;/code&gt; helper, and set it to empty vector first.
Then we bind it in &lt;em&gt;line 2&lt;/em&gt;, this needs to be done only once. And when we obtain our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;headers&lt;/code&gt; in &lt;em&gt;line 5&lt;/em&gt; we set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;view-model&lt;/code&gt; observalble
in &lt;em&gt;line 6&lt;/em&gt; (remember - observables are functions). This in turn triggers DOM update.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: using global &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vars&lt;/code&gt; like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;view-model&lt;/code&gt; is not recommended in good Clojure code,
but will do for our sample code.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Great!&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clj-&amp;gt;js&lt;/code&gt; conversion is nowhere to be seen in our main code and we adhere to good &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; practices, &lt;strong&gt;but …&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;whats-wrong-with-it&quot;&gt;What’s wrong with it?&lt;/h3&gt;

&lt;p&gt;First, getting/setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;view-model&lt;/code&gt; by calling it as a function is not very &lt;em&gt;Clojury&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Second, and more importantly, if we read &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(view-model)&lt;/code&gt; we’ll get JavaScript-converted objects, not
the original. The original is “lost in translation”. Which means that if we want to modify our
view model in ClojureScript we need to keep it separately somewhere.&lt;/p&gt;

&lt;p&gt;And where do we usually keep changing data in Clojure? &lt;strong&gt;In &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;refs&lt;/code&gt; of cause!&lt;/strong&gt; At this point
a light bulb should begin hovering above your head: the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;refs&lt;/code&gt; in Clojure have watchers, so they can notify
whoever is interested when they change.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;refs&lt;/code&gt; sound suspiciously familiar to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ko/observables&lt;/code&gt;: both track changing state and both send notifications
when change happens. Can we somehow bridge the two? We certainly can!&lt;/p&gt;

&lt;h2 id=&quot;using-observable-refs&quot;&gt;Using Observable refs&lt;/h2&gt;

&lt;p&gt;Let’s create a helper function to create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ko/observable&lt;/code&gt; tracking Clojure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ref&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;observable-ref&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ko/observable&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;clj-&amp;gt;js&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add-watch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obs&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;obs&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;clj-&amp;gt;js&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;observable-ref&lt;/code&gt; takes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ref&lt;/code&gt; as parameter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;r&lt;/code&gt; (the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ref&lt;/code&gt; itself, not its value!).
We create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ko\observable&lt;/code&gt; named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;state&lt;/code&gt; in &lt;em&gt;line 2&lt;/em&gt; with initial value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;r&lt;/code&gt; converted to JavaScript.
Then in &lt;em&gt;line 3&lt;/em&gt; we add a watcher for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;r&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The watcher &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn&lt;/code&gt; takes 4 parameters, but we only care about 2:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;obs&lt;/code&gt; is our observable &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;state&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt; is the new value of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ref&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;r&lt;/code&gt;. Then we simply convert &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new&lt;/code&gt;
value to JavaScript representation and put it into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;obs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And finally we return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;state&lt;/code&gt; observable from the function so that it can be passed to &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our main code now changes to this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view-model&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;atom&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ko/applyBindings&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;observable-ref&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view-model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/api/echo&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get-edn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:headers&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sort-by&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;reset!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view-model&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Notice that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;view-model&lt;/code&gt; created in &lt;em&gt;line 1&lt;/em&gt; is now a Clojure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ref&lt;/code&gt; (in this case an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;atom&lt;/code&gt;). And we don’t even save
the observable returned by our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;observable-ref&lt;/code&gt; helper, we just pass it directly to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ko/applyBindings&lt;/code&gt;
in &lt;em&gt;line 2&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And modifying our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;view-model&lt;/code&gt; &lt;em&gt;(line 6)&lt;/em&gt; is as simple as modifying any other Clojure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;atom&lt;/code&gt;, yet DOM immediately
reflects the changes!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Isn’t it nice!&lt;/strong&gt; Let’s have some fun with it …&lt;/p&gt;

&lt;h2 id=&quot;animating-our-table&quot;&gt;Animating our table&lt;/h2&gt;

&lt;p&gt;Just for fun, let’s pretend that our Internet connection is very slow and headers are received one by one,
slooowly. We can emulate this by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conj&lt;/code&gt;ing headers to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;view-model&lt;/code&gt; one at a time with delay:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/api/echo&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get-edn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:headers&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sort-by&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;doseq&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;swap!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view-model&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;conj&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then we’ll delay for a second and pretend that terrible computer virus eats our headers one at a time:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view-model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;swap!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view-model&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;rest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now delay for another second to keep the suspense, and finally restore our headers table to calm down the user:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;reset!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view-model&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Pure Clojure data manipulation code, yet &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;KO&lt;/a&gt; faithfully reflects all our changes in the DOM!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mission accomplished!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or is it? &lt;em&gt;I have tentative plans for another post in the series, but it requires a little more research.&lt;/em&gt;
I’ll keep you posted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; Keeping you posted, here is the &lt;a href=&quot;http://bufa.build/blog/clojure/clojurescript/2013/07/31/clojure-all-the-way-deep-knockout&quot;&gt;next post&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;one-last-thing-optimized-builds&quot;&gt;One last thing: optimized builds&lt;/h2&gt;

&lt;p&gt;Unlike Steve Job’s famous “one last things” this one is boring, &lt;strong&gt;but important&lt;/strong&gt;. If we try to build
our ClojureScript code with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:advanced&lt;/code&gt; optimization it will not work. This is because
Google Closure compiler minifies all names in produced .js file including names like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ko&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;observable&lt;/code&gt;. Certainly not what we want.&lt;/p&gt;

&lt;p&gt;The solution is to add so-called [externs file] and feed it to Google Closure compiler, so it would
know which names it is not supposed to touch.&lt;/p&gt;

&lt;p&gt;Conceptually the [externs file][] is similar to C/C++ .h headers files, or .asmmeta files for C#. Ours
is called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ko.externs.js&lt;/code&gt; and looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ko&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;ko&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;applyBindings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;ko&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;observable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;ko&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;computed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Just declarations, no code. And after adding it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project.clj&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;no&quot;&gt;:externs&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cljs/ko.externs.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;… we can build our optimized code, and it will work correctly:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lein cljsbuild once opt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you are wondering how big is produced optimized &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app.js&lt;/code&gt; file (I sure was), it is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;118&apos;871 bytes&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;--source-code&quot;&gt;&lt;a name=&quot;src&quot;&gt; &lt;/a&gt; Source code&lt;/h2&gt;
&lt;p&gt;Full source code &lt;a href=&quot;https://github.com/Dimagog/dimagog.github.io/tree/ClojureAllTheWay3&quot;&gt;can be found on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to build and run it locally, execute:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/Dimagog/dimagog.github.io.git -b ClojureAllTheWay3 --single-branch ClojureAllTheWay3
cd ClojureAllTheWay3
lein ring server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>Clojure All The Way - The Client</title>
   <link href="http://dimagog.github.io/blog/clojure/clojurescript/2013/07/18/clojure-all-the-way-the-client"/>
   <updated>2013-07-18T00:00:00+00:00</updated>
   <id>http://dimagog.github.io/blog/clojure/clojurescript/2013/07/18/clojure-all-the-way-the-client</id>
   <content type="html">&lt;p&gt;This is a second article in mini-series. The goal of mini-series is to create a Client-Server environment
where Clojure data structures are pervasive and we don’t have to deal with JSON and JavaScript objects 
in Clojure/ClojureScript land (as much as possible).&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://bufa.build/blog/clojure/2013/07/14/clojure-all-the-way-the-server&quot;&gt;previous post&lt;/a&gt; dealt with the Server part, now let’s look at the Client side.&lt;/p&gt;

&lt;h2 id=&quot;starting-point&quot;&gt;Starting Point&lt;/h2&gt;

&lt;p&gt;We start where we left off in the &lt;a href=&quot;http://bufa.build/blog/clojure/2013/07/14/clojure-all-the-way-the-server&quot;&gt;previous post&lt;/a&gt;: we have a Server
that implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;echo&lt;/code&gt; HTTP API and calling it returns &lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;edn-encoded&lt;/a&gt; data.&lt;/p&gt;

&lt;p&gt;And we have a Client capable of calling this API and receiving data, but it still
treats it as text, and not as structured Clojure data. The client was actually explained
not in the last post, but in &lt;a href=&quot;http://bufa.build/blog/clojure/clojurescript/2013/07/12/making-http-requests-from-clojurescript-with-core.async&quot;&gt;post before that&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;first-small-improvement-to-get-function&quot;&gt;First, small improvement to GET function&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Note: Code samples include only interesting parts, &lt;a href=&quot;#src&quot;&gt;full source code is available below&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET&lt;/code&gt; function in previous &lt;a href=&quot;http://bufa.build/blog/clojure/clojurescript/2013/07/12/making-http-requests-from-clojurescript-with-core.async&quot;&gt;client post&lt;/a&gt; was implemented using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(&amp;gt;! ch ...)&lt;/code&gt; 
inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt;-routine &lt;em&gt;(line 6)&lt;/em&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;chan&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;xhr/send&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.-target&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.getResponseText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&amp;gt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;close!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In comments to &lt;a href=&quot;http://bufa.build/blog/clojure/clojurescript/2013/07/12/making-http-requests-from-clojurescript-with-core.async&quot;&gt;that post&lt;/a&gt; Alexander Solovyov suggested using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;put!&lt;/code&gt; instead.
It’s a good idea (thanks Alexander!) since we don’t care when channel write completes.
Here is the change:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;chan&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;xhr/send&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;put!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.-target&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.getResponseText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;close!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;the inner &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;let&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt; blocks are gone and we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;put!&lt;/code&gt; in &lt;em&gt;line 5&lt;/em&gt; instead.&lt;/p&gt;

&lt;p&gt;Now back to our main topic …&lt;/p&gt;

&lt;h2 id=&quot;getting-clojure-data-from-server-response&quot;&gt;Getting Clojure data from Server response&lt;/h2&gt;

&lt;p&gt;Let’s add a new function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get-edn&lt;/code&gt; that uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET&lt;/code&gt; function above to get data from the Server, and then
converts it to Clojure data structures, i.e. &lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;edn-decodes&lt;/a&gt; it. It is actually very simple, all we need
to do is call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read-string&lt;/code&gt; function from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cljs.reader&lt;/code&gt; namespace.&lt;/p&gt;

&lt;p&gt;And in addition to being useful for our purposes it will also show how async functions compose.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get-edn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read-string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Let’s look at it from inside out. In &lt;em&gt;line 3&lt;/em&gt; we call our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET&lt;/code&gt; that returns a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;channel&lt;/code&gt; that will eventually
contain result (text). In &lt;em&gt;line 4&lt;/em&gt; we read the value from this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;channel&lt;/code&gt; potentially “parking” this activity, but not blocking.
This is why we need this code wrapped in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt;-routine. And then in &lt;em&gt;line 5&lt;/em&gt; we pass returned text to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read-string&lt;/code&gt; that 
&lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;edn-decodes&lt;/a&gt; it and returns Clojure data structure (let’s call this value &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;result&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;But what happens next? How is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;result&lt;/code&gt; propagated to the caller of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get-edn&lt;/code&gt;? To answer that we need to understand
what &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get-edn&lt;/code&gt; returns. Following normal Clojure rules &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get-edn&lt;/code&gt; returns the value returned by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt; form.
This is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;channel&lt;/code&gt;, now who writes to this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;channel&lt;/code&gt;? The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt; form does. Here is how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt; works:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;first it creates a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;channel&lt;/code&gt; and promptly returns it to the caller&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;eventually&lt;/em&gt; it evaluates all statement inside, potentially “parking” this activity when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;!&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;!&lt;/code&gt; forms are encountered&lt;/li&gt;
  &lt;li&gt;it writes the value of the last statement to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;channel&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;close!&lt;/code&gt;es the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;channel&lt;/code&gt; and completes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our case the last and only statement inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt; is our “conveyor” producing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;result&lt;/code&gt; defined two paragraphs ago,
i.e. decoded response. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt; form writes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;result&lt;/code&gt; to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;channel&lt;/code&gt; it has created and this is how it gets to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get-edn&lt;/code&gt; caller.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And this is how async functions compose!&lt;/strong&gt; Notice that we didn’t even have to create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;channel&lt;/code&gt; explicitly in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get-edn&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;The reason we had to create &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;channel&lt;/code&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET&lt;/code&gt;
function is because we were converting callback-based API to asynchronous one. The caller of our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn&lt;/code&gt; in there was not async-aware,
and actually ignored the return value. So we had to propagate it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET&lt;/code&gt; caller thru manually-created &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;channel&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ch&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;calling-get-edn-function&quot;&gt;Calling get-edn function&lt;/h2&gt;

&lt;p&gt;To prove to ourselves that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get-edn&lt;/code&gt; returns Clojure map let’s call some function on it before displaying it,
for example let’s extract only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:headers&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dom/set-text!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sel1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:#log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;get-edn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/api/echo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                     &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                     &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The whole block is wrapped in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt; routine because we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;!&lt;/code&gt; (read channel) form.
We call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get-edn&lt;/code&gt; in &lt;em&gt;line 3&lt;/em&gt; that returns a channel, we read from it in &lt;em&gt;line 4&lt;/em&gt;, potentially “parking” (but again, not blocking) this activity.
Then we call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:headers&lt;/code&gt; in &lt;em&gt;line 5&lt;/em&gt; to get only headers portion of respose proving that result is actually a Clojure map.&lt;/p&gt;

&lt;p&gt;And if you run the sample code, you’ll see the headers displayed.&lt;/p&gt;

&lt;p&gt;Now this is nice, but the way they are displayed is kind of lame. We’ll do something about it in the
&lt;a href=&quot;http://bufa.build/blog/clojure/clojurescript/2013/07/22/clojure-all-the-way-knockout&quot;&gt;next post&lt;/a&gt;, while staying on topic of
using Clojure data structures as much as possible.&lt;/p&gt;

&lt;h2 id=&quot;--source-code&quot;&gt;&lt;a name=&quot;src&quot;&gt; &lt;/a&gt; Source code&lt;/h2&gt;
&lt;p&gt;Full source code &lt;a href=&quot;https://github.com/Dimagog/dimagog.github.io/tree/ClojureAllTheWay2&quot;&gt;can be found on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to build and run it locally, execute:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/Dimagog/dimagog.github.io.git -b ClojureAllTheWay2 --single-branch ClojureAllTheWay2
cd ClojureAllTheWay2
lein ring server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>Clojure All The Way - The Server</title>
   <link href="http://dimagog.github.io/blog/clojure/2013/07/14/clojure-all-the-way-the-server"/>
   <updated>2013-07-14T00:00:00+00:00</updated>
   <id>http://dimagog.github.io/blog/clojure/2013/07/14/clojure-all-the-way-the-server</id>
   <content type="html">&lt;p&gt;This is a first article in mini-series. The goal of mini-series is to create a Client-Server environment
where Clojure data structures are pervasive and we don’t have to deal with JSON and JavaScript objects 
in Clojure/ClojureScript land (as much as possible).&lt;/p&gt;

&lt;p&gt;In this post we’ll develop a Web server in Clojure (using &lt;a href=&quot;https://github.com/ring-clojure/ring&quot;&gt;Ring&lt;/a&gt; and &lt;a href=&quot;https://github.com/weavejester/compojure&quot;&gt;Compojure&lt;/a&gt;) that exposes
simple API to serve Clojure data structures in their natural text representation
(fancy term for this is &lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;edn-encoded&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id=&quot;the-basics-are-not-covered&quot;&gt;The Basics are not covered&lt;/h2&gt;
&lt;p&gt;The basics of creating &lt;a href=&quot;https://github.com/ring-clojure/ring&quot;&gt;Ring&lt;/a&gt;+&lt;a href=&quot;https://github.com/weavejester/compojure&quot;&gt;Compojure&lt;/a&gt; Web server are covered very well on Interwebs.
In this post I’ll only focus on creating API returning &lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;edn-encoded&lt;/a&gt; Clojure data.&lt;/p&gt;

&lt;h2 id=&quot;serving-the-site-itself-static-files&quot;&gt;Serving the site itself (static files)&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Note: Code samples include only interesting parts, &lt;a href=&quot;#src&quot;&gt;full source code is available below&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s start with vanilla web server that simply serves static files:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defroutes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;file-response&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;default.html&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:root&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:root&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;not-found&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;h1&amp;gt;404 Page not found&amp;lt;/h1&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;line 2 returns (not redirects to) &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;default.html&lt;/code&gt; when server root is accessed&lt;/li&gt;
  &lt;li&gt;line 3 serves static files from “html” directory&lt;/li&gt;
  &lt;li&gt;line 4 is only hit if static file is not found and returns 404&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;adding-echo-api&quot;&gt;Adding Echo API&lt;/h2&gt;

&lt;p&gt;Now let’s add an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;echo&lt;/code&gt; API that simply echoes back the client’s HTTP request.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;To be precise:&lt;/em&gt; upon receiving HTTP &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET /api/echo&lt;/code&gt; request the server will respond with
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;200 OK&lt;/code&gt; and body containing &lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;edn-encoded&lt;/a&gt; Clojure representation of request (a map of maps, strings and numbers).&lt;/p&gt;

&lt;p&gt;Of cause we are not going to do heavy-lifting ourselves - that’s the whole point of &lt;a href=&quot;https://github.com/ring-clojure/ring&quot;&gt;Ring&lt;/a&gt;.
To paraphrase Apple’s commercials “there is a &lt;em&gt;middleware&lt;/em&gt; for that”.
And it’s called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ring.middleware.format-response&lt;/code&gt;. Let’s use it:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defroutes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/api/echo&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
       &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:status&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:body&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
             &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wrap-clojure-response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app&lt;/code&gt; was renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handler&lt;/code&gt; &lt;em&gt;(line 1)&lt;/em&gt; and new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app&lt;/code&gt;
wraps this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handler&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wrap-clojure-response&lt;/code&gt; &lt;em&gt;(lines 8-9)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The new &lt;a href=&quot;https://github.com/weavejester/compojure&quot;&gt;Compojure&lt;/a&gt; route &lt;em&gt;(lines 3-5)&lt;/em&gt; simply takes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;request&lt;/code&gt; (a Clojure map) and builds a
200-response from it setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:body&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;request&lt;/code&gt; (still a Clojure map).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wrap-clojure-response&lt;/code&gt; &lt;em&gt;middleware&lt;/em&gt; is the one converting Clojure map &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:body&lt;/code&gt; returned
by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handler&lt;/code&gt; to &lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;edn-encoded&lt;/a&gt; textual representation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is one problem with this code: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:body&lt;/code&gt; of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;request&lt;/code&gt; that we are sending back is not
a Clojure data structure. It’s a Java object of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HttpInput org.eclipse.jetty.server.HttpInput&lt;/code&gt; type.
That’s not good: it cannot be &lt;a href=&quot;https://github.com/edn-format/edn&quot;&gt;edn-encoded&lt;/a&gt; and Client won’t be able to decode it anyway.
A small tweak removes it from the response we are sending &lt;em&gt;(call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dissoc&lt;/code&gt; in line 3)&lt;/em&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/api/echo&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
       &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:status&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:body&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dissoc&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)})&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;/h2&gt;
&lt;p&gt;To test our Server we can use a slightly modified client from my &lt;a href=&quot;http://bufa.build/blog/clojure/clojurescript/2013/07/12/making-http-requests-from-clojurescript-with-core.async&quot;&gt;earlier post&lt;/a&gt;.
And sure enough it shows client’s request returned back to us.&lt;/p&gt;

&lt;p&gt;But ClojureScript Client still treats response as text (not structured Clojure data).
We’ll deal with it in the &lt;a href=&quot;http://bufa.build/blog/clojure/clojurescript/2013/07/18/clojure-all-the-way-the-client&quot;&gt;next post&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;--source-code&quot;&gt;&lt;a name=&quot;src&quot;&gt; &lt;/a&gt; Source code&lt;/h2&gt;
&lt;p&gt;Full source code &lt;a href=&quot;https://github.com/Dimagog/dimagog.github.io/tree/ClojureAllTheWay1&quot;&gt;can be found on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to build and run it locally, execute:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/Dimagog/dimagog.github.io.git -b ClojureAllTheWay1 --single-branch ClojureAllTheWay1
cd ClojureAllTheWay1
lein ring server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>Making HTTP requests from ClojureScript with core.async</title>
   <link href="http://dimagog.github.io/blog/clojure/clojurescript/2013/07/12/making-http-requests-from-clojurescript-with-core.async"/>
   <updated>2013-07-12T23:40:00+00:00</updated>
   <id>http://dimagog.github.io/blog/clojure/clojurescript/2013/07/12/making-http-requests-from-clojurescript-with-core.async</id>
   <content type="html">&lt;p&gt;I’ve always been a big fan of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async/await&lt;/code&gt; feature in C# (long before it was publicly available).
So, naturally, I was very excited to read the &lt;a href=&quot;http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html&quot;&gt;announcement&lt;/a&gt; about Clojure &lt;a href=&quot;https://github.com/clojure/core.async&quot;&gt;core.async&lt;/a&gt; library. 
Even more so after I’ve learned that it works for ClojureScript as well.&lt;/p&gt;

&lt;p&gt;Here is an example of using &lt;a href=&quot;https://github.com/clojure/core.async&quot;&gt;core.async&lt;/a&gt; to convert callback-based &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;goog.net.XhrIo&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;send&lt;/code&gt; API to
sequential-looking one.&lt;/p&gt;

&lt;h2 id=&quot;leningen-config-boring-stuff&quot;&gt;Leningen config (boring stuff)&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Note: Code samples include only interesting parts, &lt;a href=&quot;#src&quot;&gt;full source code is available below&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;defproject&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:repositories&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sonatype-oss-public&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://oss.sonatype.org/content/groups/public/&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:dependencies&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;org.clojure/clojure&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.5.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;org.clojure/clojurescript&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0.0-1820&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;org.clojure/core.async&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0.1.0-SNAPSHOT&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We need Sonatype because it is hosting SNAPSHOTs, and there is no release version of &lt;a href=&quot;https://github.com/clojure/core.async&quot;&gt;core.async&lt;/a&gt; available yet.
Also I’m not using the latest version of ClojureScript because &lt;a href=&quot;http://www.lighttable.com/&quot;&gt;Light Table&lt;/a&gt; does not like it.&lt;/p&gt;

&lt;h2 id=&quot;defining-get-function-cool-stuff&quot;&gt;Defining GET function (cool stuff)&lt;/h2&gt;
&lt;p&gt;First the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ns&lt;/code&gt; header:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ns&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:require&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goog.net.XhrIo&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:as&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cljs.core.async&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:as&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:refer&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chan&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:require-macros&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cljs.core.async.macros&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;no&quot;&gt;:refer&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alt!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It’s not idiomatic to have all uppercase function names in Clojure, but since this function mimics
http GET method we’ll make an exception for it.&lt;/p&gt;

&lt;p&gt;The idea is to return a channel from GET function that will have a result of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;send&lt;/code&gt; call
when it completes. The callback simply extracts the result and writes it to the channel:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;chan&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;xhr/send&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.-target&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.getResponseText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&amp;gt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;close!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We create channel &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ch&lt;/code&gt; of size 1 (default is 0) because there is no reason to block callback until reader arrives.
Instead it writes the response once it becomes available and disappears.&lt;/p&gt;

&lt;p&gt;You may think that callback could be simplified as:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;c1&quot;&gt;; WARNING: Broken code&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&amp;gt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.-target&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.getResponseText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;close!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;but that does not work&lt;/strong&gt;. This version tries to extract result from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;event&lt;/code&gt; inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go&lt;/code&gt;
routine which will execute &lt;em&gt;eventually&lt;/em&gt;. By the time it runs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;event&lt;/code&gt; does not have the result anymore.&lt;/p&gt;

&lt;p&gt;Also it’s a good idea to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;close!&lt;/code&gt; the channel &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ch&lt;/code&gt; after we write the result &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;res&lt;/code&gt;, so if anyone tries
to read from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ch&lt;/code&gt; again by mistake, they will get &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nil&lt;/code&gt; returned immediately.&lt;/p&gt;

&lt;h2 id=&quot;using-get-function-even-cooler-stuff&quot;&gt;Using GET function (even cooler stuff)&lt;/h2&gt;
&lt;p&gt;Let’s define a helper &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;log&lt;/code&gt; function first:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;defn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.log&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;js/console&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And now we can call our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET&lt;/code&gt; function and print the result:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-clojure&quot; data-lang=&quot;clojure&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;go&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://dimagog.github.io/sitemap.txt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We have sequential-looking code that looks like it’s blocking, but it’s not. It is fully asyncronous!&lt;/p&gt;

&lt;h2 id=&quot;--source-code&quot;&gt;&lt;a name=&quot;src&quot;&gt; &lt;/a&gt; Source code&lt;/h2&gt;
&lt;p&gt;Full source code &lt;a href=&quot;https://github.com/Dimagog/AsyncGET&quot;&gt;can be found on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to build and run it locally, execute:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/Dimagog/AsyncGET.git
cd AsyncGET
lein ring server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>About Me</title>
   <link href="http://dimagog.github.io/blog/personal/2013/07/12/about-me"/>
   <updated>2013-07-12T22:40:00+00:00</updated>
   <id>http://dimagog.github.io/blog/personal/2013/07/12/about-me</id>
   <content type="html">&lt;p&gt;I work for &lt;a href=&quot;http://microsoft.com/jobs&quot;&gt;Microsoft&lt;/a&gt; on &lt;a href=&quot;http://www.windowsazure.com&quot;&gt;Windows Azure&lt;/a&gt; team where I (mostly) program in C#.
And in my spare time I love to play with new and interesting languages and technologies
inside and outside of “Microsoft stack”
such as Clojure, Haskell, Erlang, F#, Scala, Riak, Datomic, Storm, Akka, Hierarchical State Machines, ANTLR, etc.&lt;/p&gt;

&lt;p&gt;I tend to forget a lot of what I learn, so I’ve decided to start this Blog
where I can keep and share my notes as well as practice technical writing.&lt;/p&gt;

&lt;p&gt;Hopefully others will find something useful here as well. Comments and suggestions are certainly welcome!&lt;/p&gt;

&lt;p&gt;I share links that I find interesting on &lt;a href=&quot;https://plus.google.com/109391987177502206351/posts&quot;&gt;Google+&lt;/a&gt;
and on &lt;a href=&quot;https://www.facebook.com/dmitry.kakurin.9&quot;&gt;Facebook&lt;/a&gt;. &lt;br /&gt;
My Twitter is &lt;a href=&quot;https://twitter.com/DimaPhone&quot;&gt;@DimaPhone&lt;/a&gt; (not dimagog),
and here is &lt;a href=&quot;http://www.linkedin.com/pub/dmitry-kakurin/1/272/a2a&quot;&gt;my LinkedIn page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;- Dmitry Kakurin &lt;em&gt;(dimagog)&lt;/em&gt;&lt;/p&gt;

</content>
 </entry>
 
 
</feed>