<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://swannodette.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://swannodette.github.io/" rel="alternate" type="text/html" /><updated>2026-01-24T17:18:11+00:00</updated><id>https://swannodette.github.io/feed.xml</id><title type="html">dosync</title><author><name>David Nolen</name></author><entry><title type="html">Not Slop</title><link href="https://swannodette.github.io/2026/01/24/not-slop/" rel="alternate" type="text/html" title="Not Slop" /><published>2026-01-24T00:00:00+00:00</published><updated>2026-01-24T00:00:00+00:00</updated><id>https://swannodette.github.io/2026/01/24/not-slop</id><content type="html" xml:base="https://swannodette.github.io/2026/01/24/not-slop/"><![CDATA[<h1 id="year-in-review">Year in Review</h1>

<p>A list of things that didn’t qualify as slop in 2025. There’s a loose thread of conviviality running through some of the things here that I would like to explore further in 2026.</p>

<h1 id="not-tech">Not Tech</h1>

<h2 id="books">Books</h2>

<h3 id="the-last-samurai"><a href="https://en.wikipedia.org/wiki/The_Last_Samurai_(novel)">The Last Samurai</a></h3>

<p>I can’t say that I’ve ever read anything quite like it. Both stunningly beautiful, laugh out loud funny, and full of fresh formal hijinks.</p>

<h3 id="benito-cereno"><a href="https://en.wikipedia.org/wiki/Benito_Cereno">Benito Cereno</a></h3>

<p>Melville saw clearly into the dark soul of America in a way that still sparks wonder and dread. A real historical event shaped into a flawless gem about freedom and its inverse.</p>

<h3 id="the-once-and-future-king"><a href="https://en.wikipedia.org/wiki/The_Once_and_Future_King">The Once and Future King</a></h3>

<p>I’ve been meaning to read this since I was 10 years old. The first book was an absolute delight. The second book was a complete slog. The third redeemed the second one by considerable measure. I took a break after that.</p>

<h3 id="parable-of-the-sower"><a href="https://en.wikipedia.org/wiki/Parable_of_the_Sower_(novel)">Parable of the Sower</a></h3>

<p>Took way too long for me to get around to reading this. Reminded me of Cormac McCarthy’s The Road but way better and, you know, written thirteen years earlier. A very dark book and one to read closely in these interesting times.</p>

<h3 id="playing-in-the-dark-whiteness-and-the-literary-imagination"><a href="https://en.wikipedia.org/wiki/Playing_in_the_Dark">Playing in the Dark: Whiteness and the Literary Imagination</a></h3>

<p>Required reading for any lover of American literature. I don’t think about American writing in the same way on the other side of it.</p>

<h2 id="movies">Movies</h2>

<h3 id="unknown-pleasures"><a href="https://en.wikipedia.org/wiki/Unknown_Pleasures_(film)">Unknown Pleasures</a></h3>

<p>One for the hard core film buffs. Two young men with absolutely no prospects and their misadventures. High art this one.</p>

<h2 id="music">Music</h2>

<h3 id="cocteau-twins">Cocteau Twins</h3>

<p>I did listen to a bit of music this year but not nearly as much as I should have. One standout is that I went through a good chunk of the Cocteau Twins catalog. I’m sad I arrived at it so late but also happy it’s fresh to my ears.</p>

<h3 id="autechre-live">Autechre (Live)</h3>

<p>I’m not a big Autechre head but thoroughly enjoyed seeing them live. They played in complete darkness for an hour and a half.</p>

<h2 id="writings-tools">Writings Tools</h2>

<h3 id="sailor-pro-gear-fountain-pen-with-21k-f-nib"><a href="https://en.sailor.co.jp/topics/professional-gear-series/">Sailor Pro Gear Fountain Pen with 21K F nib</a></h3>

<p>I’ve tried a bunch of fountain pens (Preppy, Kakuno, Lamy, TWISBI, Faber Castell) but the Sailor Pro Gear (and Slim) line is the only one I had any real connection with.</p>

<h3 id="midori-b6-notebook"><a href="https://md.midori-japan.co.jp/en/products/mdnote/">Midori B6 Notebook</a></h3>

<p>After a year long flirt with the Hobonichi Cousin I decided it wasn’t for me. The paper and extra space is glorious but I take notes too sporadically and the planner format just wasn’t a good fit. The <a href="https://md.midori-japan.co.jp/en/products/mdnote/">Midori B6 Notebook</a> suits me better and the paper is glorious in its own way.</p>

<h1 id="music-tech">Music Tech</h1>

<h2 id="convivial-hardware">Convivial Hardware</h2>

<h3 id="dirtywave-m8-model-2"><a href="https://dirtywave.com">Dirtywave M8 Model 2</a></h3>

<p>A brilliant portable tracker labor of love created by one person. It recently got the ability to mount as a USB drive and stream 24 independent tracks of 24bit USB audio. It’s incredible what a 600mhz processor can do when there’s no cruft between you and your music.</p>

<h3 id="hordijk-modular-system-2020"><a href="https://youtube.com/playlist?list=PLAC347DE38ABA9E8D&amp;si=0xIS-zTBuA6jPiRh">Hordijk Modular System (2020)</a></h3>

<p>Year five of living with this beast of a modern modular synth built using
bespoke methods inspired by the original RA Moog Co. Factory. Nowhere near the bottom of this one. Rob Hordijk’s convivial approach to life and instrument building is something to strive for. He built his instruments so they could be learned and played over a lifetime.</p>

<h1 id="nerd-tech">Nerd Tech</h1>

<h2 id="hardware">Hardware</h2>

<h3 id="kinesis-advantage360-signature-wireless"><a href="https://kinesis-ergo.com/shop/advantage360-signature/">Kinesis Advantage360 Signature (Wireless)</a></h3>

<p>Best computer related hardware upgrade I’ve made in 15 years. The 360 can be programmed via ZMK, I use <a href="https://nickcoutsos.github.io/keymap-editor/">Nick Coustos’ handy editor</a>. One nice feature of a symmetrical keyboard is one-handed typing via mirroring. I’ve customized it so that holding down space presents the mirror layer.</p>

<p>The industrial design of the keyboard is a delight. I have two of them, one black with blank key caps and one black with steel blue key caps. I only need to charge the keyboard once every two months. Clearly built to last 10+ years, every bit of technology should be made this well.</p>

<h3 id="dxt-3-mouse"><a href="https://kinesis-ergo.com/shop/dxt-mouse-3-wireless/">DXT 3 Mouse</a></h3>

<p>I spent some time with the Logictech Vertical MX mouse before switching. While the MX felt good, I don’t think it was actually was doing anything positive for my hands and the Logictech configuration app was effectively buggy malware. The DXT 3 design encourages holding it more like a stylus with a very light grip. I have two so I can easily switch hands. I’ve charged them once 6 months ago.</p>

<h2 id="software">Software</h2>

<h3 id="steermouse"><a href="https://plentycom.jp/en/steermouse/download.php">SteerMouse</a></h3>

<p>A lovely Japanese app for configuring your mouse. Just works.</p>

<h3 id="aerospace"><a href="https://nikitabobko.github.io/AeroSpace/guide.html">Aerospace</a></h3>

<p>A year and a half ago I got fed up with Apple’s window/app “management” tools and switched to Amethyst. Conceptually I liked it but it was just too buggy and slow. I switched to Aerospace: configuration in a text file and much snappier.</p>

<h3 id="emacs"><a href="https://github.com/d12frosted/homebrew-emacs-plus">Emacs+</a></h3>

<p>I used IntelliJ + Cursive for Clojure dev for a decade. Powerful combo and I would still highly recommend it for Clojure folks looking for a comprehensive IDE experience. But I never gave up on Emacs, all my thinking happens inside of <a href="https://orgmode.org">org-mode</a>. IntelliJ’s support for Emacs key bindings is impressive, but I finally got fed up with the various situations where it breaks down. I wiped my <code class="language-plaintext highlighter-rouge">init.el</code> clean and started rebuilding with modern packages. The new packages are simpler and significantly more composable. For Clojure work I have a fine set up without LSP, just <a href="https://github.com/universal-ctags/citre#start-of-content">Citre</a> and <a href="https://github.com/borkdude/flycheck-clj-kondo">flycheck-clj-kondo</a>. I also picked up some new essential everyday tools: <a href="https://www.gnu.org/software/emacs/manual/html_mono/eww.html">eww</a>, <a href="https://github.com/abo-abo/avy">avy</a>, <a href="https://github.com/emacsmirror/elpher">elpher</a>, <a href="https://www.gnu.org/software/emacs/manual/html_mono/gnus.html">gnus</a>, <a href="https://github.com/rnkn/olivetti">olivetti</a>.</p>]]></content><author><name>David Nolen</name></author><summary type="html"><![CDATA[Year in Review]]></summary></entry><entry><title type="html">Aimless</title><link href="https://swannodette.github.io/2025/11/24/aimless/" rel="alternate" type="text/html" title="Aimless" /><published>2025-11-24T00:00:00+00:00</published><updated>2025-11-24T00:00:00+00:00</updated><id>https://swannodette.github.io/2025/11/24/aimless</id><content type="html" xml:base="https://swannodette.github.io/2025/11/24/aimless/"><![CDATA[<p>I’ve been doing Clojure long enough that I remember when Clojure was just a JAR provided in a ZIP file. As I much as I benefit from all the work around modern Clojure tooling, it was less ceremonious in the old days to play around without big plans in mind.</p>

<p>During the 2025 Conj Clojure Tooling Working Group meetup (coordinated by the awesome Christoph Neumann), Rich Hickey said that Clojure should be useful without needing to create a formal project. That struck a chord and reminded me of the simpler times.</p>

<p>It also got me thinking how even experienced Clojurists still find ClojureScript difficult or unnatural to setup. That’s really unfortunate as António Monteiro, Mike Fikes, myself and others put in an incredible amount of work over the years to make using ClojureScript more like using Clojure. Let’s see what I mean. Edit your <code class="language-plaintext highlighter-rouge">~/.clojure/deps.edn</code> to include the following:</p>

<div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="no">:aliases</span><span class="w">
 </span><span class="p">{</span><span class="no">:#cljs</span><span class="w"> </span><span class="p">{</span><span class="no">:extra-deps</span><span class="w">
          </span><span class="p">{</span><span class="n">org.clojure./clojurescript</span><span class="w"> </span><span class="p">{</span><span class="no">:mvn/version</span><span class="w"> </span><span class="s">"1.12.116"</span><span class="p">}}</span><span class="w">
          </span><span class="no">:main-opts</span><span class="w"> </span><span class="p">[</span><span class="s">"-m"</span><span class="w"> </span><span class="s">"cljs.main"</span><span class="w"> </span><span class="s">"-r"</span><span class="p">]}}}</span><span class="w">
</span></code></pre></div></div>

<p>That’s really all you need. No extra compiler flags, no build configuration EDN or files. Pick whatever global alias name makes sense for you. The idea is to not surprise yourself later. Go ahead and launch a ClojureScript REPL, it doesn’t matter where. Don’t worry, since we didn’t specify an output directory, ClojureScript will write to a <code class="language-plaintext highlighter-rouge">tmp</code> directory.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>clj -M:#cljs
</code></pre></div></div>

<p>A browser window will open. Type a few things at the REPL. Then make a file called whatever you want but ending in <code class="language-plaintext highlighter-rouge">.cljs</code>. <code class="language-plaintext highlighter-rouge">user.cljs</code> works if you’re not feeling inspired. Again, we’re just aimlessly exploring - how does the new proxy functionality in ClojureScript work? Add the following to your file:</p>

<div class="language-clojure highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">require</span><span class="w"> </span><span class="o">'</span><span class="p">[</span><span class="n">cljs.proxy</span><span class="w"> </span><span class="no">:refer</span><span class="w"> </span><span class="p">[</span><span class="n">builder</span><span class="p">]])</span><span class="w">

</span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="nb">proxy</span><span class="w"> </span><span class="p">(</span><span class="nf">builder</span><span class="p">))</span><span class="w">
</span><span class="p">(</span><span class="k">def</span><span class="w"> </span><span class="n">proxied-map</span><span class="w"> </span><span class="p">(</span><span class="nb">proxy</span><span class="w"> </span><span class="p">{</span><span class="no">:first</span><span class="w"> </span><span class="s">"Foo"</span><span class="w"> </span><span class="no">:last</span><span class="w"> </span><span class="s">"Bar"</span><span class="p">}))</span><span class="w">
</span></code></pre></div></div>

<p>Note we didn’t define a namespace. We don’t need to! Let’s load the file in the REPL with <code class="language-plaintext highlighter-rouge">(load-file "user.cljs")</code> or whatever name you came up with. Right-click on the browser REPL page to open the browser inspector (in Safari you’ll need to <a href="https://support.apple.com/guide/safari/use-the-developer-tools-in-the-develop-menu-sfri20948/mac">enable Developer tools</a>). Navigate to the Console. Try typing the following into the JavaScript Console:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">cljs</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">proxied_map</span><span class="p">[</span><span class="dl">"</span><span class="s2">first</span><span class="dl">"</span><span class="p">]</span>
<span class="nx">cljs</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">proxied_map</span><span class="p">[</span><span class="dl">"</span><span class="s2">last</span><span class="dl">"</span><span class="p">]</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">cljs</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">proxied_map</span><span class="p">)</span>
</code></pre></div></div>

<p>That’s it! No project, no namespaces - just experiments and explorations. You never know what might happen. I actually wrote the code that became <code class="language-plaintext highlighter-rouge">cljs.proxy</code> without concrete goals in mind in exactly this way.</p>]]></content><author><name>David Nolen</name></author><summary type="html"><![CDATA[I’ve been doing Clojure long enough that I remember when Clojure was just a JAR provided in a ZIP file. As I much as I benefit from all the work around modern Clojure tooling, it was less ceremonious in the old days to play around without big plans in mind.]]></summary></entry><entry><title type="html">Bury Buffer</title><link href="https://swannodette.github.io/2025/10/08/bury-buffer/" rel="alternate" type="text/html" title="Bury Buffer" /><published>2025-10-08T00:00:00+00:00</published><updated>2025-10-08T00:00:00+00:00</updated><id>https://swannodette.github.io/2025/10/08/bury-buffer</id><content type="html" xml:base="https://swannodette.github.io/2025/10/08/bury-buffer/"><![CDATA[<p>I’ve been spending a lot more time recently with Emacs. While I never gave up on <a href="https://orgmode.org/index.html">org-mode</a>, my Emacs usage had otherwise been in decline. A few months ago, I started experimenting with some “new” affordances: <a href="https://github.com/emacs-straight/vertico#verticoel---vertical-interactive-completion">vertico</a>, <a href="https://github.com/minad/marginalia#marginaliael---marginalia-in-the-minibuffer">marginalia</a>, <a href="https://github.com/oantolin/orderless#orderless">orderless</a>, <a href="https://github.com/minad/consult#consultel---consulting-completing-read">consult</a> and <a href="https://github.com/oantolin/embark#embark-emacs-mini-buffer-actions-rooted-in-keymaps">embark</a>. The combined UX of these tools was impressive, and unlike similar functionality in, say, IntelliJ, could be used in far more contexts. When it comes to mainstream software, not much has changed since I first played around with an Apple IIgs nearly 40 years ago - disjointed islands that the user must travel between over and over again. Emacs delivers a non-feudal vision of personal computing. Perhaps <a href="https://en.wikipedia.org/wiki/Canon_Cat">Jef Raskin was right all along</a>.</p>

<p>Coming back to everyday Emacs usage resurfaced one of my frustrations: Emacs window management. Without getting into the weeds, I devised a system that works for me both on large screens with many window splits, and on a MacBook Air where I have at most one split. The following snippet was arrived at with the help of Claude running in <a href="https://github.com/karthink/gptel#gptel-a-simple-llm-client-for-emacs">gptel</a>. I’m a Elisp noob, so I apologize in advance for any LLM vagaries.</p>

<div class="language-elisp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">defun</span> <span class="nv">my/get-display-window</span>
  <span class="p">(</span><span class="nv">source-window</span> <span class="k">&amp;optional</span> <span class="nv">create-if-needed</span><span class="p">)</span>
  <span class="p">(</span><span class="nv">save-excursion</span>
    <span class="p">(</span><span class="nv">goto-char</span> <span class="p">(</span><span class="nv">window-start</span> <span class="nv">source-window</span><span class="p">))</span>
    <span class="p">(</span><span class="nb">or</span>
      <span class="p">(</span><span class="nv">window-in-direction</span> <span class="ss">'right</span> <span class="nv">source-window</span><span class="p">)</span>
      <span class="p">(</span><span class="k">let</span> <span class="p">((</span><span class="nv">below-window</span> <span class="p">(</span><span class="nv">window-in-direction</span> <span class="ss">'below</span> <span class="nv">source-window</span><span class="p">)))</span>
        <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nb">and</span> <span class="nv">below-window</span>
                   <span class="p">(</span><span class="nb">not</span> <span class="p">(</span><span class="nv">window-minibuffer-p</span> <span class="nv">below-window</span><span class="p">)))</span>
          <span class="nv">below-window</span><span class="p">))</span>
       <span class="p">(</span><span class="nb">when</span> <span class="nv">create-if-needed</span>
         <span class="p">(</span><span class="nv">split-window</span> <span class="nv">source-window</span> <span class="no">nil</span> <span class="ss">'below</span><span class="p">)))))</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">(goto-char ...)</code> bit is necessary since the “right” window is the one to the right of the cursor not the current window. Without this bit you run into trouble if there is a horizontal split next to the current window.</p>

<p>Integrating this with a particular package eliminates the behavior of a “random” buffer being chosen for display. For example with <a href="https://magit.vc/">magit</a>:</p>

<div class="language-elisp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">defun</span> <span class="nv">my/magit-display-buffer</span> <span class="p">(</span><span class="nv">buffer</span> <span class="nv">alist</span><span class="p">)</span>
  <span class="p">(</span><span class="nv">when-let</span> <span class="p">((</span><span class="nv">target-window</span> <span class="p">(</span><span class="nv">my/get-display-window</span>
                              <span class="p">(</span><span class="nv">selected-window</span><span class="p">)</span> <span class="no">t</span><span class="p">)))</span>
    <span class="p">(</span><span class="nv">set-window-buffer</span> <span class="nv">target-window</span> <span class="nv">buffer</span><span class="p">)</span>
    <span class="nv">target-window</span><span class="p">))</span>

<span class="p">(</span><span class="nv">add-to-list</span> <span class="ss">'display-buffer-alist</span>
  <span class="o">'</span><span class="p">(</span><span class="s">"\\(magit-revision:\\|magit-diff:\\)"</span>
     <span class="p">(</span><span class="nv">my/magit-display-buffer</span><span class="p">)</span>
    <span class="p">(</span><span class="nv">inhibit-same-window</span> <span class="o">.</span> <span class="no">t</span><span class="p">)))</span>
</code></pre></div></div>

<p>This setup combined with binding <code class="language-plaintext highlighter-rouge">bury-buffer</code> makes using Emacs windows superior to pretty much anything else I have on my computer. What is <code class="language-plaintext highlighter-rouge">bury-buffer</code> you ask? Every window has its own list of buffers it has displayed, <code class="language-plaintext highlighter-rouge">bury-buffer</code> pushes the top buffer for a window to the bottom of the list. So if some unruly package displays a buffer in some undesirable window, you can just bury it to get back to where you were.</p>

<p>The three other tools I find useful for dealing with Emacs windows:</p>

<ul>
  <li><a href="https://github.com/abo-abo/avy#introduction">avy</a>, to jump to any location in any window quickly</li>
  <li><a href="https://github.com/abo-abo/ace-window#ace-window">ace-window</a>, to jump to any window + some useful commands</li>
  <li>tab bar mode, for managing a group of windows like ERC</li>
</ul>

<p>I have quite a bit more to say about Emacs, but there are some ClojureScript things afoot as well, stay tuned!</p>]]></content><author><name>David Nolen</name></author><summary type="html"><![CDATA[I’ve been spending a lot more time recently with Emacs. While I never gave up on org-mode, my Emacs usage had otherwise been in decline. A few months ago, I started experimenting with some “new” affordances: vertico, marginalia, orderless, consult and embark. The combined UX of these tools was impressive, and unlike similar functionality in, say, IntelliJ, could be used in far more contexts. When it comes to mainstream software, not much has changed since I first played around with an Apple IIgs nearly 40 years ago - disjointed islands that the user must travel between over and over again. Emacs delivers a non-feudal vision of personal computing. Perhaps Jef Raskin was right all along.]]></summary></entry><entry><title type="html">A Tool For Thought</title><link href="https://swannodette.github.io/2016/06/03/tools-for-thought/" rel="alternate" type="text/html" title="A Tool For Thought" /><published>2016-06-03T00:00:00+00:00</published><updated>2016-06-03T00:00:00+00:00</updated><id>https://swannodette.github.io/2016/06/03/tools-for-thought</id><content type="html" xml:base="https://swannodette.github.io/2016/06/03/tools-for-thought/"><![CDATA[<p><img width="590" src="/assets/images/tools.png" /></p>

<p>As <a href="http://clojurescript.org">ClojureScript</a> nears its fifth birthday
I find myself reflecting on its suitability as a
<a href="http://www.rheingold.com/texts/tft/">“tool for thought”</a>. Certainly
reading the
<a href="https://mitpress.mit.edu/sicp/full-text/book/book.html">Structure and Interpretation of Computer Programs</a>
nearly thirteen years ago painted an ideal image of Lisp as a truly
interactive and tangible approach to computing. That experience
eventually lead me to <a href="http://clojure.org">Clojure</a> and later
ClojureScript. Now that I use both for the day job, has that wonderful
image of computing that Sussman &amp; Abelson mapped out faded over the
ensuing years?</p>

<p>Looking around we see many compelling new languages with a
client story in the functional space especially of the typed
variety. Some of these are truly new endeavors and others are simply
old faces with JavaScript backends. <a href="http://elm-lang.org/">Elm</a> is
notably exciting with its principled stance on simplicity and
approachability while delivering on the benefits of static
typing. Whatever your opinions of <a href="http://www.scala-lang.org/">Scala</a>,
many programmers find it a comfortable train ride across the OOP / FP
border and <a href="https://www.scala-js.org/">Scala.js</a> means you can bring
your experiences to the client. <a href="http://purescript.org">PureScript</a>
has a strong following in the <a href="http://haskell.org">Haskell</a>
community and of course if you really just want Haskell or OCaml on the
client you have a <a href="https://github.com/ghcjs/ghcjs">few</a>
<a href="http://ocsigen.org/js_of_ocaml/">options</a> as well.</p>

<p>But frankly I don’t have any interest in any of these initiatives
beyond that of the language geek. For me
<a href="https://github.com/clojure/clojurescript/wiki/Source-maps">debugging and profiling</a>,
<a href="https://developers.google.com/closure/compiler/">advanced optimization</a>,
<a href="https://cursive-ide.com/">IDE support</a>,
<a href="https://www.youtube.com/watch?v=j-kj2qwJa_E">rich</a>
<a href="https://github.com/binaryage/cljs-devtools">tooling</a> across
<a href="https://github.com/drapanjanas/re-natal">all</a>
<a href="https://github.com/omcljs/ambly">desirable</a> JavaScript targets are
equally important considerations to weigh against static guarantees
when choosing the programming language for clients.</p>

<p>Still I’m not a staunch defender of the dynamic nor the static stance
and I think people with strong opinions either way are being more
than a bit dishonest to themselves about the realities of industrial
software development. Personally the thing I find most compelling
about statically typed languages is that well designed ones give you a
<em>tool for thinking</em>. As <a href="http://research.microsoft.com/en-us/people/simonpj/">Simon Peyton Jones</a> sez in
<a href="http://www.codersatwork.com/">Coders At Work</a>, it’s not about
correctness it’s about <em>crispness</em>.</p>

<p>As a Clojure(Script) programmer I would love to tap into that deep
well of crispness somehow. Unfortunately idiomatic Clojure code
presents many challenges to typing, just ask my buddy
<a href="https://www.youtube.com/watch?v=a0gT0syAXsY">Ambrose Bonnaire-Sergeant</a>.</p>

<p>As
Clojurists we live in a sea of lists, symbols, maps, keywords,
vectors, and sets and some of these structures represent data and
others represent code. I think it’s no small part of the attraction of
Lisps that the
<a href="https://en.wikipedia.org/wiki/Use-mention_distinction">use/mention distinction</a>
becomes at least slightly blurred. The problem as I think many of us
can attest is when things get so blurry you lose your way. This isn’t to
say that you can’t build big sophisticated programs
in this way, for example, ClojureScript itself:</p>

<p><img width="590" src="/assets/images/cloc.png" /></p>

<p>And while I’m sure <a href="http://www.cs.indiana.edu/~dyb/">Kent Dybvig</a>
<a href="https://github.com/cisco/ChezScheme">is nodding as well</a>, we
shouldn’t stop wondering if we can’t the move the goal post a little
bit closer.</p>

<p>I think
<a href="https://clojure.org/news/2016/05/23/introducing-clojure-spec">clojure.spec</a>
moves that goal post <em>a lot closer</em>.</p>

<h1 id="clojurespec">clojure.spec</h1>

<p>In my humble opinion clojure.spec is the most
<a href="http://www.vpri.org">VPRI-worthy</a> feature Rich Hickey has shipped
since delivering fast persistent data structures. Yes, yes you now have
<a href="https://github.com/plumatic/schema">Schema</a> like validations, but
this is but the tip of an iceberg. clojure.spec takes
<a href="http://matt.might.net/papers/might2011derivatives.pdf">Matt Might et. al. Parsing with Derivatives</a>
and really, really runs with it. By casting validation as fundamentally a
parsing problem (computer science!), we get a wonderfully expressive
language for <em>crisply describing</em> our Clojure programs without
changing how we <em>joyfully write them</em>.</p>

<p>So instead of thinking about typical application domain examples, lets
instead consider how we might spec our old friend <code class="language-plaintext highlighter-rouge">let</code>. Intuitively
we know <code class="language-plaintext highlighter-rouge">let</code> must be made of some obvious basic parts:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">require</span><span class="w"> </span><span class="o">'</span><span class="p">[</span><span class="n">cljs.spec</span><span class="w"> </span><span class="no">:as</span><span class="w"> </span><span class="n">s</span><span class="p">])</span><span class="w">

</span><span class="p">(</span><span class="nf">s/def</span><span class="w"> </span><span class="no">::let</span><span class="w">
  </span><span class="p">(</span><span class="nf">s/cat</span><span class="w">
     </span><span class="no">:name</span><span class="w">     </span><span class="ss">'#</span><span class="p">{</span><span class="k">let</span><span class="p">}</span><span class="w">
     </span><span class="no">:bindings</span><span class="w"> </span><span class="no">::bindings</span><span class="w">
     </span><span class="no">:forms</span><span class="w">    </span><span class="p">(</span><span class="nf">s/*</span><span class="w"> </span><span class="p">(</span><span class="nb">constantly</span><span class="w"> </span><span class="n">true</span><span class="p">))))</span><span class="w">
</span></code></pre></div></div>

<p>Ah wishful thinking! How we adore thee. We know the
first part of a <code class="language-plaintext highlighter-rouge">let</code> expression has to be the symbol <code class="language-plaintext highlighter-rouge">let</code> (Duh!),
we’re ignoring <code class="language-plaintext highlighter-rouge">::bindings</code> for now, and we know that we’ll have zero
or more forms after the bindings. After some hammocking we give
<code class="language-plaintext highlighter-rouge">::bindings</code> a go —</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">s/def</span><span class="w"> </span><span class="no">::bindings</span><span class="w">
  </span><span class="nb">vector?</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<p>Voila!</p>

<p>Let’s try it:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">s/conform</span><span class="w"> </span><span class="no">::let</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">x</span><span class="w"> </span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="p">)))</span><span class="w">
</span><span class="c1">;; {:name let, :bindings [x 1], :forms [(+ x y)]}</span><span class="w">
</span></code></pre></div></div>

<p>Shazam!</p>

<p>… hmm, actually not so fast.</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">s/conform</span><span class="w"> </span><span class="no">::let</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">x</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">y</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="p">)))</span><span class="w">
</span><span class="c1">;; {:name let, :bindings [x 1 y], :forms [(+ x y)]}</span><span class="w">
</span></code></pre></div></div>

<p>Ugh. That’s not right, <code class="language-plaintext highlighter-rouge">:bindings</code> must be an even number of forms:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">s/def</span><span class="w"> </span><span class="no">::bindings</span><span class="w">
  </span><span class="p">(</span><span class="nf">s/and</span><span class="w"> </span><span class="nb">vector?</span><span class="w"> </span><span class="o">#</span><span class="p">(</span><span class="nb">-&gt;</span><span class="w"> </span><span class="n">%</span><span class="w"> </span><span class="nb">count</span><span class="w"> </span><span class="n">even?</span><span class="p">)))</span><span class="w">
</span></code></pre></div></div>

<p>Let’s try again:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">s/conform</span><span class="w"> </span><span class="no">::let</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">x</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">y</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="p">)))</span><span class="w">
</span><span class="c1">;; :cljs.spec/invalid</span><span class="w">
</span></code></pre></div></div>

<p>That’s more like it but good tools for thinking should be a little bit
more forthcoming:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">s/explain</span><span class="w"> </span><span class="no">::let</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">x</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">y</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="p">)))</span><span class="w">
</span><span class="c1">;; In: [1] val: [x 1 y] fails spec: </span><span class="w">
</span><span class="c1">;;   :cljs.user/bindings at: [:bindings] predicate:</span><span class="w">
</span><span class="c1">;;   (-&gt; % count even?)</span><span class="w">
</span></code></pre></div></div>

<p>Nice.</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">s/conform</span><span class="w"> </span><span class="no">::let</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="mi">1</span><span class="w"> </span><span class="n">y</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="p">)))</span><span class="w">
</span><span class="c1">;; {:name let, :bindings [1 y], :forms [(+ x y)]}</span><span class="w">
</span></code></pre></div></div>

<p>Ah we’re not crisp enough yet. Let’s make a <code class="language-plaintext highlighter-rouge">::binding</code> spec to
control what can appear in the vector:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">s/def</span><span class="w"> </span><span class="no">::binding</span><span class="w">
  </span><span class="p">(</span><span class="nf">s/cat</span><span class="w">
    </span><span class="no">:name</span><span class="w">  </span><span class="nb">symbol?</span><span class="w">
    </span><span class="no">:value</span><span class="w"> </span><span class="p">(</span><span class="nb">constantly</span><span class="w"> </span><span class="n">true</span><span class="p">)))</span><span class="w">
</span></code></pre></div></div>

<p>That looks right, now let’s fix <code class="language-plaintext highlighter-rouge">::bindings</code> to use it:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">s/def</span><span class="w"> </span><span class="no">::bindings</span><span class="w">
  </span><span class="p">(</span><span class="nf">s/and</span><span class="w"> </span><span class="nb">vector?</span><span class="w">
         </span><span class="o">#</span><span class="p">(</span><span class="nb">-&gt;</span><span class="w"> </span><span class="n">%</span><span class="w"> </span><span class="nb">count</span><span class="w"> </span><span class="n">even?</span><span class="p">)</span><span class="w">
         </span><span class="p">(</span><span class="nf">s/*</span><span class="w"> </span><span class="no">::binding</span><span class="p">)))</span><span class="w">
</span></code></pre></div></div>

<p>Now let’s try it:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">s/conform</span><span class="w"> </span><span class="no">::let</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">[</span><span class="n">y</span><span class="w"> </span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="p">)))</span><span class="w">
</span><span class="c1">;; {:name let, :bindings [{:name y, :value 1}], :forms [(+ x y)]}</span><span class="w">
</span></code></pre></div></div>

<p>Yes I am trying to trick you into reimplementing ClojureScript from
scratch.</p>

<p>Obviously we could go further but the above should suffice to show how
much clojure.spec can help when thinking about the shape of the
problem.</p>

<h1 id="conclusion">Conclusion</h1>

<p>While the Clojurist loves to wax poetic about hammock driven
development, Clojure(Script) <em>the language</em> did not offer much in the
way of helping us really work through a design while sitting at a
keyboard. Without belittling the power of pencil and paper, the whole
point of a computer is to give us interactive ways of exploring our
thoughts in ways that pencil and paper can’t! So I think
clojure.spec gives us a pretty damn nice hammock away from the hammock
and I look forward to hearing more about it from the larger community.</p>

<p>Happy hacking!</p>]]></content><author><name>David Nolen</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">ClojureScript Year In Review</title><link href="https://swannodette.github.io/2015/12/23/year-in-review/" rel="alternate" type="text/html" title="ClojureScript Year In Review" /><published>2015-12-23T00:00:00+00:00</published><updated>2015-12-23T00:00:00+00:00</updated><id>https://swannodette.github.io/2015/12/23/year-in-review</id><content type="html" xml:base="https://swannodette.github.io/2015/12/23/year-in-review/"><![CDATA[<p>It’s been a very exciting year for ClojureScript. It’s clear that things
have been accelerating and here is a personal selection of highlights:</p>

<h2 id="cljsjs">CLJSJS</h2>

<p>While technically it appeared in late 2014,
<a href="http://cljsjs.github.io">CLJSJS</a> took off when ClojureScript landed
enhanced and standardized support for foreign dependencies in
January. Thanks to the tireless work of many contributors, the wider
community of ClojureScript users can now leverage the most popular
JavaScript libraries with minimal hassle. Many thanks to Martin Klepsch
and Juho Teperi for leading the charge.</p>

<h2 id="ambly">Ambly</h2>

<p>2015 kicked off with a near complete rewrite of the ClojureScript REPL
infrastructure. This was an admittedly painful transition, but now
that we are on the other side of the hump the considerable payoff is
self-evident.</p>

<p>Case in point, Mike Fikes’s
<a href="https://github.com/omcljs/ambly">Ambly REPL</a> delivers a seamless live
experience when developing iOS applications without requiring
tethering or XCode beyond the initial install. Using a slick
combination of Bonjour and WebDAV, the Ambly REPL sets a new bar.</p>

<p>Here’s a basic Ambly demo:</p>

<iframe style="border: 1px solid black; padding: 2px;" width="580" height="315" src="https://www.youtube.com/embed/TVDkYZJW2MY" frameborder="0" allowfullscreen=""></iframe>

<p>Ambly plays well with other cool JavaScriptCore integrations like
<a href="https://github.com/phoboslab/ejecta">Ejecta</a> which exposes both
JavaScript Canvas 2D and WebGL APIs to native iOS clients.</p>

<p>For example here’s Ambly being used to develop an Ejecta application
on <a href="https://developer.apple.com/tvos/?&amp;cid=wwa-us-kwg-tv">tvOS</a>:</p>

<p>&lt;iframe style=”border: 1px solid black; padding: 2px;”width=”420” height=”315”
src=”https://www.youtube.com/embed/eaWy5mliO38” frameborder=”0”
allowfullscreen&gt;&lt;/iframe&gt;</p>

<p>You can find out more <a href="https://github.com/omcljs/ambly">here</a>;</p>

<h2 id="react-native">React Native</h2>

<p>Facebook announced
<a href="https://github.com/facebook/react-native">React Native</a> further
solidifying the role of React as a critical part of the ClojureScript
ecosystem. ClojureScript React bindings abound and now the community
can easily reach the iOS and Android platforms using the same React
bindings we’ve all come to love over the past two years.</p>

<p>Here is another Mike Fikes video demonstrating React Native with
Reagent:</p>

<iframe style="border: 1px solid black; padding: 2px;" width="580" height="315" src="https://www.youtube.com/embed/4txql-1VXJk" frameborder="0" allowfullscreen=""></iframe>

<p>For getting up and running with React Native, look at
<a href="https://github.com/dmotz/natal">natal</a> and
<a href="https://github.com/drapanjanas/re-natal">re-natal</a> as well as the
collection of resources at <a href="http://cljsrn.org/">cljsrn.org</a>.</p>

<p>Suffice to say I see ClojureScript + React Native really taking off
in 2016.</p>

<h2 id="google-summer-of-code">Google Summer of Code</h2>

<p>The ClojureScript Google Summer of Code 2015 project was a smashing
success. Maria Geller dove deep into the problem of integrating
CommonJS, AMD, ES2015 modules as well as integrating popular
JavaScript compilation technology like Babel.js. There’s more work to
do but the future is bright for good integration with the wider
JavaScript ecosystem. You can read more about the project
<a href="http://mneise.github.io">here</a>.</p>

<p>Also Maria Geller gave a stunning talk about the ClojureScript
compiler internals at the Clojure/conj which is
<a href="https://www.youtube.com/watch?v=Elg17s_nwDg">well worth watching</a>.</p>

<h2 id="re-frame">Re-frame</h2>

<p><a href="https://github.com/reagent-project/reagent">Reagent</a> has become the
tool of choice for many people in the ClojureScript community. My
uninformed impression is that this has been further bolstered by the
appearance of <a href="https://github.com/Day8/re-frame">re-frame</a>, a very
well-considered architecture for Reagent applications.</p>

<p>If the other ClojureScript React bindings aren’t your speed, Reagent
and re-frame invite close assessment. The community is prolific,
active, and helpful.</p>

<h2 id="figwheel">Figwheel</h2>

<p>While <a href="https://github.com/bhauman/lein-figwheel">Figwheel</a> appeared
prior to 2015, it became clear with a slew of strong stable releases
that, Bruce Hauman is one of ClojureScript’s finest tooling
authors. In a very short window of time Figwheel has taken the
ClojureScript world by storm as the REPL of choice. The usefulness of
hot-code loading during UI work cannot be overstated.</p>

<iframe style="border: 1px solid black; padding: 2px;" width="580" height="315" src="https://www.youtube.com/embed/j-kj2qwJa_E" frameborder="0" allowfullscreen=""></iframe>

<p>This video should be watched in its entirety.</p>

<h2 id="devcards">Devcards</h2>

<p>Clearly Figwheel wasn’t enough for
Bruce. <a href="https://github.com/bhauman/devcards">Devcards</a> sets a new bar
for UI tooling. Devcards also came together prior to 2015 but the
adoption rate has skyrocketed of late and for good reason. Having
tried all kinds of UI tooling in my career, Devcards legitimately provides
something so obvious and simple it’s incredible it hasn’t been tried
before. As Alan Kay sez, a change of perspective is worth a
non-trivial amount of IQ points.</p>

<p>Combined with Figwheel, Devcards provides an interactive way to both
develop and view component states, radically simplifying the task of
testing your UI work:</p>

<iframe style="border: 1px solid black; padding: 2px;" width="580" height="315" src="https://www.youtube.com/embed/G7Z_g2fnEDg" frameborder="0" allowfullscreen=""></iframe>

<p>Again, this video must be watched in its entirety.</p>

<h2 id="self-compilation">Self Compilation</h2>

<p>With the appearance of reader conditionals in Clojure 1.7.0 I got the
bug over the summer to make ClojureScript self compile. While it may
seem like a feat to outsiders, ClojureScript was always ready for
self compilation and the work was pretty boring. The repercussions
however are only starting to be understood. Some great examples of the
power of optional bootstrapping are the winning
<a href="http://landofquil.we-do-fp.berlin">Clojure Cup entry</a> and a new
web based <a href="http://clojurescript.io">ClojureScript REPL</a>.</p>

<p>Some other neat bootstrapping projects follow after some brief words
on ClojureScript 1.7.X.</p>

<h2 id="clojurescript-17x">ClojureScript 1.7.X</h2>

<p>Shortly after bootstrapping we released ClojureScript 1.7.28. This was
the first release of ClojureScript with a proper version number. It
also signified a much slower pace for releases, much needed to avoid
tooling churn. Now that the fundamentals are in place expect 2016 releases
to be heavily focused on compiler performance and build
reliability. Master already includes exciting enhancements like
parallel builds (40 lines of code written during a 45 minute train
ride - thanks Clojure!). Users have reported 30-300% faster compile
times on their multi-core machines.</p>

<h2 id="planck">Planck</h2>

<p>Mike Fikes is clearly a tireless person, within what seemed like hours
of bootstrapping, Mike Fikes had a standalone ClojureScript REPL that
you can easily install with <a href="http://brew.sh">brew</a>.</p>

<iframe style="border: 1px solid black; padding: 2px;" width="580" height="315" src="https://www.youtube.com/embed/CC5jGO712cE" frameborder="0" allowfullscreen=""></iframe>

<p>If you want a ClojureScript REPL that starts fast for testing one
liners, look no further than Planck.</p>

<h2 id="replete">Replete</h2>

<p>Thanks to bootstrapping you can also use full blown ClojureScript on
your iPhone or iPad:</p>

<iframe style="border: 1px solid black; padding: 2px;" width="580" height="315" src="https://www.youtube.com/embed/GVVugX3qqF8" frameborder="0" allowfullscreen=""></iframe>

<p>If you had told me I would be running a robust dialect of Clojure on my
iOS device four years ago I would have laughed in disbelief.</p>

<h2 id="parinfer">Parinfer</h2>

<p>This one came out of the blue. Lisp is 58 years old and people are
still coming up with things that no one has tried before. With a
clever algorithm and some inference driven by indentation, Shaun
LeBron of <a href="http://cljs.info">cljs.info</a> has probably created the most
beginner friendly way to write Lisp the world has ever seen. The
<a href="https://shaunlebron.github.io/parinfer/">parinfer blog post is a jaw dropper</a>.</p>

<p>And of course Mike Fikes gets parinfer into Replete in short order:</p>

<iframe style="border: 1px solid black; padding: 2px;" width="580" height="315" src="https://www.youtube.com/embed/xdIwkPEnlFY" frameborder="0" allowfullscreen=""></iframe>

<p>If anything 2015 has been the year of network effects. It’s thrilling
to see all these individual efforts come together as part of a grand
shared vision.</p>

<h2 id="cursive">Cursive</h2>

<p><a href="https://cursive-ide.com/">Cursive IDE shipped</a>! If you’re looking for
a rich development environment for Clojure and ClojureScript, Cursive
delivers in spades. I’ve been using it exclusively for Clojure and
ClojureScript development since January and I can’t imagine life without
it.</p>

<h2 id="cider-010">Cider 0.10</h2>

<p><a href="https://github.com/clojure-emacs/cider/releases/tag/v0.10.0">Cider 0.10</a>
shipped with many, many enhancements for ClojureScript. If Emacs is
your tool of choice, the ClojureScript story has improved leaps and
bounds over the past year thanks to the tireless work of many
contributors.</p>

<h2 id="om-next">Om Next</h2>

<p>I also did a series of talks on Om Next this year. Whether or not you
adopt Om or the technologies that inspired it
(<a href="https://facebook.github.io/relay/">Relay</a>,
<a href="http://netflix.github.io/falcor/">Falcor</a>,
<a href="http://datomic.com">Datomic</a>), I am confident that Graph-Query-View
based UI architectures will gain steam in 2016. Kovas Boguta and I
gave a
<a href="http://www.infoq.com/presentations/domain-driven-architecture">high level talk at QCon</a>
and I delivered the
<a href="https://www.youtube.com/watch?v=MDZpSIngwm4">nitty gritty at Clojure/conj</a>.</p>

<h2 id="conclusion">Conclusion</h2>

<p>The amount of innovation and invention in the ClojureScript community
is nothing short of stunning. Hopefully this post gives you a sense of
what sets ClojureScript apart from pretty much every other
compile-to-JavaScript technology. As a group we are now thinking
far beyond programming language esoterica and have turned towards the
challenge of building the necessary <em>environmental infrastructure</em>
required for the construction of simpler and more robust software
systems.</p>

<p>Congratulations to all that have given to the evolution of
ClojureScript whether through adoption, contribution, or evangelism!</p>

<p>I suspect 2016 will be an even bigger one for ClojureScript.</p>

<p>Have a Happy New Year!</p>]]></content><author><name>David Nolen</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">ClojureScript Next</title><link href="https://swannodette.github.io/2015/07/29/clojurescript-17/" rel="alternate" type="text/html" title="ClojureScript Next" /><published>2015-07-29T00:00:00+00:00</published><updated>2015-07-29T00:00:00+00:00</updated><id>https://swannodette.github.io/2015/07/29/clojurescript-17</id><content type="html" xml:base="https://swannodette.github.io/2015/07/29/clojurescript-17/"><![CDATA[<link href="/assets/css/codemirror.css" rel="stylesheet" />

<link href="/assets/css/cljs-next/main.css" rel="stylesheet" />

<p><img width="590" style="border: 1px solid #ccc" src="/assets/images/lambdam.jpeg" /></p>

<p>I’ve been enamoured with languages in the Lisp family ever since I
first encountered
<a href="https://mitpress.mit.edu/sicp/full-text/book/book.html">The Structure and Interpretation of Computer Programs</a>
now more than a decade ago. At the time I was disappointed that such
beautiful systems found so little use in day to day programming. Lisp
seemed both deeply pragmatic (Objects!) and deeply sophisticated
(Meta-circular Interpreters!). But Java, bless its heart, was the
language of the day, and despite Steele’s characterization, it seemed
miles away from Scheme or anything like it.</p>

<p>For many years it seemed unlikely that Lisp would be more widely used
by the working programmer. So it’s with a constant sense of wonder
that I look around at a rapidly expanding
<a href="http://cljsjs.github.io/">ClojureScript</a>
<a href="http://cljs.info/cheatsheet/">community</a> that
<a href="https://github.com/clojure/clojurescript/wiki/Companies-Using-ClojureScript">shares</a>
the same love for simpler yet more expressive systems. It seems fair
to attribute this quickening pace of adoption to ClojureScript’s
steadfast dedication to pragmatism.</p>

<p>But always taking the practical route can cut off unforeseen avenues
and vistas.</p>

<p>Today ClojureScript embraces the less practical and “dream bigger”
side of Lisp.</p>

<p><em>ClojureScript can compile itself.</em></p>

<p>Yeah.</p>

<p>There’s a lot to talk about, but first a few words on another big
change.</p>

<h2 id="clojurescript-17">Clojurescript 1.7</h2>

<p>ClojureScript now has a version number. Enthusiastic
users have often asked <em>How long till 1.0?</em>. However 1.0 would not
correctly reflect the time, effort, and feature set that comes with
four years of very active development. Instead we’re adopting 1.7 as
this communicates the incredibly important relationship that
ClojureScript has with its parent language, Clojure.</p>

<p>This close relationship means the differences between Clojure and
ClojureScript are largely uninteresting. So much so that with the help
of
<a href="http://blog.cognitect.com/blog/2015/6/30/clojure-17">reader conditionals</a>
and some dedicated collaborative effort, self compilation came rather
quickly.</p>

<p>Enough ado, let’s get to it.</p>

<h2 id="say-hello-to-our-old-friend-eval">Say Hello To Our Old Friend, Eval</h2>

<p>The following is a simple ClojureScript program that creates a
definition and immediately invokes it. Click the <strong>EVAL</strong> button.</p>

<div class="eval-cljs">
    <textarea id="ex0" class="code"></textarea>
    <div class="eval-ctrl">
        <input id="ex0-out" type="text" />
        <button id="ex0-run" class="eval">EVAL</button>
    </div>
</div>

<p>The humble result hides the enormity of the event :) If you know
ClojureScript (or even if you don’t), feel free to modify the source
and evaluate whatever you like.</p>

<p>So what is happening here?</p>

<p>We grabbed a string out of <a href="https://codemirror.net/">CodeMirror</a>, read
it via <a href="https://github.com/clojure/tools.reader">tools.reader</a> into
persistent data structures, passed it into the ClojureScript analyzer,
constructed an immutable AST, passed that AST to the compiler, and
generated JavaScript source with inline source maps and eval’ed the
result.</p>

<p>All of this happened inside of your web browser.</p>

<p>To be very clear, <em>this is precisely the same ClojureScript compiler
that runs on the Java Virtual Machine running on Plain Old
JavaScript</em>.</p>

<p>For the unbelievers, open Chrome DevTools, open the Sources tab and
you should see something like the following:</p>

<p><img width="590" style="border: 1px solid #ccc" src="/assets/images/inline_source_maps.png" /></p>

<p>Let’s dig into details that enabled the humble result above.</p>

<h2 id="reading">Reading</h2>

<p>The first step is converting a string into a series of data
structures. What other languages call parsing is traditionally called
reading in Lisp. It’s important for this process to be fast. We’ve
spent years tuning ClojureScript code generation for modern JavaScript
JITs without catering to any specific engine (for a long time V8 was
king, but these days
<a href="https://www.webkit.org/blog/3362/introducing-the-webkit-ftl-jit/">JavaScriptCore is screaming ahead of the pack</a>).</p>

<p>So how long does it take to read the entire standard library (about
10,000 lines of code) into persistent data structures? Click the
following button. This will download the entire standard library and
then measure the time it takes to read all of it. Make sure to click
a few times and you will observe it get faster.</p>

<div class="eval-cljs">
    <div class="eval-ctrl">
        <input id="ex1-out" type="text" value="No Runs" />
        <button id="ex1-run">Read cljs.core!</button>
    </div>
</div>

<p>On my 3.5ghz iMac this takes ~60ms under WebKit Nightly, ~80ms
under Chrome Canary, and ~60ms under Firefox Nightly. These numbers
are only 1.5X to 2X slower than ClojureScript JVM performance.</p>

<p>A big shoutout to <a href="https://github.com/andrewmcveigh">Andrew Mcveigh</a>
and <a href="https://github.com/Bronsa">Nicola Mometto</a> for pushing the
ClojureScript port of tools.reader through.</p>

<p>Now let’s consider the next step, analysis.</p>

<h2 id="analysis">Analysis</h2>

<p>After successfully reading a form, that form is passed to the
analyzer. This step produces an AST. ClojureScript’s AST is composed
entirely of simple immutable values. Similar to the strategy taken by
many popular JavaScript parsers and compilers, a data oriented
representation means the AST can be manipulated easily without an API
of any kind.</p>

<div id="ana-cljs" class="eval-cljs">
    <div class="cols">
         <div class="left">
              <textarea id="ex2" width="290"></textarea>
         </div>
         <div class="right">
              <textarea id="ex2-out" width="290"></textarea>
         </div>
    </div>
</div>
<div class="eval-ctrl">
     <button id="ex2-run" class="eval">ANALYZE</button>
</div>

<p>A big shoutout to <a href="https://github.com/shaunlebron">Shaun LeBron</a> and
<a href="https://github.com/bostonou">Jonathan Boston’s</a> work on porting
<code class="language-plaintext highlighter-rouge">clojure.pprint</code> to ClojureScript so that we can see a pretty-printed
AST.</p>

<p>From the AST we can now generate JavaScript.</p>

<h2 id="compilation">Compilation</h2>

<p>The compiler generates JavaScript directly from the simple data
oriented AST:</p>

<div id="comp-cljs" class="eval-cljs">
   <div class="eval-cljs">
       <div class="cols">
           <div class="left">
               <textarea id="ex3" class="code"></textarea>
           </div>
           <div class="right">    
               <textarea id="ex3-out" class="code"></textarea>
           </div>
       </div>
    </div>
</div>
<div class="eval-ctrl">
    <button id="ex3-run" class="eval">COMPILE</button>
</div>

<p>Let’s show a less trivial example. The following includes a library
import. Users of bootstrapped ClojureScript have total control how
library names are resolved to actual sources. In this case we’ve
configured libraries to be fetched via a simple XMLHttpRequest. In
order to expand the macros we must first get the macros file, compile
it, eval it, and then continue to parse, analyze, and compile the
<code class="language-plaintext highlighter-rouge">foo.core</code> namespace.</p>

<div id="macro-cljs" class="eval-cljs">
   <div class="eval-cljs">
       <div class="cols">
           <div class="left">
               <textarea id="ex4" class="code"></textarea>
           </div>
           <div class="right">    
               <textarea id="ex4-out" class="code"></textarea>
           </div>
       </div>
    </div>
</div>
<div class="eval-ctrl">
    <button id="ex4-run" class="eval">COMPILE</button>
</div>

<p>This example demonstrates not only how pluggable the bootstrapped
compiler is, but how anything compilable by ClojureScript JVM is
compilable by ClojureScript JS.</p>

<h2 id="conclusion">Conclusion</h2>

<p>There’s little doubt that this feature enhancement will create an
avalanche of new innovation. You can already run ClojureScript on your
iPhone with <a href="https://github.com/mfikes">Mike Fikes’</a>
<a href="https://github.com/mfikes/replete">Replete</a>, build iOS apps with
<a href="https://github.com/omcljs/ambly/wiki/ClojureScript-React-Native-Quick-Start">React Native</a>,
and write fast starting shell scripts with
<a href="https://github.com/mfikes/planck">Planck</a> or with
<a href="https://github.com/kanaka/cljs-bootstrap">Node.js</a>. Suffice to say
we’ve only scratched the surface of an iceberg of potential.</p>

<p>To be clear, this is not something you want to use for the traditional
ClojureScript use case - building typical web applications. The output
file starting size is simply too large (~300K gzipped). But there are
now many new reachable targets where this cost is not a constraint as
in the examples previously enumerated.</p>

<p>After something this significant you think we would be done, but
there’s a lot more good stuff
coming. <a href="https://github.com/MNeise">Maria Geller’s</a> excellent
JavaScript module work should make it a breeze to integrate the
various module types you find in the wild including the new ES 2015
standard. Further out we’re looking into automatically generating
externs where possible.</p>

<p>You have an amazing tool for thought at your fingertips. You can play
with the
<a href="https://github.com/clojure/clojurescript">latest goodies today</a>. As I
said at EuroClojure:</p>

<p><em>Keep calm and try to take over the world</em>.</p>

<p>Happy hacking!</p>

<script type="text/javascript" src="/assets/js/cljs_next/main.js"></script>]]></content><author><name>David Nolen</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">In Stillness, Movement</title><link href="https://swannodette.github.io/2015/04/07/in-stillness-movement/" rel="alternate" type="text/html" title="In Stillness, Movement" /><published>2015-04-07T00:00:00+00:00</published><updated>2015-04-07T00:00:00+00:00</updated><id>https://swannodette.github.io/2015/04/07/in-stillness-movement</id><content type="html" xml:base="https://swannodette.github.io/2015/04/07/in-stillness-movement/"><![CDATA[<p>A while back I wrote about
<a href="http://swannodette.github.io/2015/02/23/hello-google-closure-modules/">Google Closure Modules</a>,
and talked a little bit about
<a href="http://en.wikipedia.org/wiki/Loop-invariant_code_motion">code motion</a>. A
few days ago I tried dog-fooding the discussed
<a href="http://clojurescript.org">ClojureScript</a> <code class="language-plaintext highlighter-rouge">:modules</code> functionality on
<a href="http://swannodette.github.io/mori/">Mori</a>, which exports
ClojureScript’s standard library for JavaScript usage. To my surprise
attempting to split Mori into base and extras modules resulted in
a fairly large base (~36K gzipped) and surprisingly small extras (~9K
gzipped). Cross module code motion did not appear to be kicking in.</p>

<p>I examined
<a href="https://developers.google.com/closure/compiler/">Closure Compiler</a>,
specifically
<a href="https://github.com/google/closure-compiler/blob/d0605bdbf71771fa5954da9b927f9edddb8041bc/src/com/google/javascript/jscomp/CrossModuleCodeMotion.java">CrossModuleCodeMotion.java</a>
looking for clues. This lead me to the intuitively named method
<a href="https://github.com/google/closure-compiler/blob/d0605bdbf71771fa5954da9b927f9edddb8041bc/src/com/google/javascript/jscomp/CrossModuleCodeMotion.java#L433-L477">canMoveValue</a>. The
comment for this method reads:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">canMoveValue</span><span class="o">(</span>
    <span class="nc">ReferenceCollectingCallback</span> <span class="n">collector</span><span class="o">,</span> <span class="nc">Scope</span> <span class="n">scope</span><span class="o">,</span> <span class="nc">Node</span> <span class="n">n</span><span class="o">)</span> <span class="o">{</span>
  <span class="c1">// the value is only movable if it's</span>
  <span class="c1">// a) nothing,</span>
  <span class="c1">// b) a constant literal,</span>
  <span class="c1">// c) a function, or</span>
  <span class="c1">// d) an array/object literal of movable values.</span>
  <span class="c1">// e) a function stub generated by CrossModuleMethodMotion.</span>
  <span class="k">if</span> <span class="o">(</span><span class="n">n</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">||</span> <span class="nc">NodeUtil</span><span class="o">.</span><span class="na">isLiteralValue</span><span class="o">(</span><span class="n">n</span><span class="o">,</span> <span class="kc">true</span><span class="o">)</span> <span class="o">||</span> 
      <span class="n">n</span><span class="o">.</span><span class="na">isFunction</span><span class="o">())</span> <span class="o">{</span>
    <span class="c1">// ...</span>
  <span class="o">}</span>
  <span class="c1">// ...</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Cross module code motion is very conservative, only obviously static
values will be moved and <code class="language-plaintext highlighter-rouge">c)</code> immediately jumped out at me as a
concern. For performance reasons multi-arity and variadic functions in
ClojureScript are actually implemented as functions with direct
methods attached as properties
(<a href="http://swannodette.github.io/2015/03/16/optimizing-clojurescript-function-invocation/">see my previous post</a>).
But that’s our problem right there! Constructing multi-arity and
variadic function values requires an invoke and invokes aren’t on the
list of things that Google Closure will move.</p>

<p>Simply put, large chunks of the ClojureScript standard library were
considered too dynamic to move by the Closure Compiler.</p>

<p>So after assessing a variety of ways to make the top-level more
static, I ended up deciding that top-level fns should be treated as a
special case and, to avoid further complications to the actual compiler,
to implement the change via customizing the <code class="language-plaintext highlighter-rouge">defn</code> macro. Being
able to do significant work at the macro level is definitely one of the big
perks of Lisp - it will probably come as no surprise to the Lisperati that the
ClojureScript macros file is bigger than the compiler file!</p>

<p>The actual changeset is pretty technical and of interest mostly to
experienced Clojure devs and ClojureScript compiler hackers, you can
<a href="https://github.com/clojure/clojurescript/commit/576fb6e054dd50ec458a3c9e4172a5a0002c7aea">see it here</a>.</p>

<p>After this change the end result for Mori is a much more reasonable
split, ~27K gzipped for the base module and ~18K gzipped for the
extras. We can likely further improve this, but already a significant
amount of ClojureScript source is now movable that previously wasn’t.</p>

<p>For those of you unlucky souls that have to deal with JavaScript
build tools this was all the configuration required to get the
optimized Mori split:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="no">:cljs-base</span><span class="w"> </span><span class="p">{</span><span class="no">:entries</span><span class="w"> </span><span class="o">#</span><span class="p">{</span><span class="n">cljs.core</span><span class="w"> </span><span class="n">mori</span><span class="p">}</span><span class="w">
             </span><span class="no">:output-to</span><span class="w"> </span><span class="s">"release/build/mori.base.js"</span><span class="p">}</span><span class="w">
 </span><span class="no">:mutable</span><span class="w">   </span><span class="p">{</span><span class="no">:entries</span><span class="w"> </span><span class="o">#</span><span class="p">{</span><span class="n">mori.mutable</span><span class="p">}</span><span class="w">
             </span><span class="no">:output-to</span><span class="w"> </span><span class="s">"release/build/mori.mutable.js"</span><span class="p">}</span><span class="w">
 </span><span class="no">:extra</span><span class="w">     </span><span class="p">{</span><span class="no">:entries</span><span class="w"> </span><span class="o">#</span><span class="p">{</span><span class="n">clojure.data</span><span class="w"> </span><span class="n">cljs.reader</span><span class="w"> </span><span class="n">clojure.set</span><span class="w"> </span><span class="n">mori.extra</span><span class="p">}</span><span class="w">
             </span><span class="no">:output-to</span><span class="w"> </span><span class="s">"release/build/mori.extra.js"</span><span class="p">}}</span><span class="w">
</span></code></pre></div></div>

<p>You can experiment with <code class="language-plaintext highlighter-rouge">:modules</code> and the enhanced code motion by
using the
<a href="https://github.com/clojure/clojurescript/releases/tag/r3178">0.0-3178</a>
pre-release.</p>]]></content><author><name>David Nolen</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Optimizing ClojureScript Function Invocation</title><link href="https://swannodette.github.io/2015/03/16/optimizing-clojurescript-function-invocation/" rel="alternate" type="text/html" title="Optimizing ClojureScript Function Invocation" /><published>2015-03-16T00:00:00+00:00</published><updated>2015-03-16T00:00:00+00:00</updated><id>https://swannodette.github.io/2015/03/16/optimizing-clojurescript-function-invocation</id><content type="html" xml:base="https://swannodette.github.io/2015/03/16/optimizing-clojurescript-function-invocation/"><![CDATA[<p>For all the available abstractions, the #1 tool of any
<a href="http://clojure.org">Clojure</a> and
<a href="http://clojurescript.org">ClojureScript</a> programmer is the humble
function. This being true it becomes extremely important to optimize
this common operation. This is not quite as straightforward as it may
seem when compiling to JavaScript due to the fact that many Clojure
and thus ClojureScript functions leverage multiple arities.</p>

<p>On the JVM this is handled via the <code class="language-plaintext highlighter-rouge">clojure.lang.IFn</code> interface as the JVM
already has good support for methods with multiple arities. When writing
JavaScript by hand this feature is simulated by dispatching on the
<code class="language-plaintext highlighter-rouge">length</code> property of the magic <code class="language-plaintext highlighter-rouge">arguments</code> object available to any
JavaScript function. However using the <code class="language-plaintext highlighter-rouge">arguments</code> object is not free
so we would rather not pay this cost if we don’t have to.</p>

<p>In the following we’ll dig into the JavaScript generated by the
ClojureScript compiler and the differences between the available
optimization settings. All you need is an install of
<a href="http://www.oracle.com/technetwork/java/javase/overview/java8-2100321.html">Java 8</a>.</p>

<p>Run the following in a terminal in a directory of your choosing:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir -p compiler_fun/src/compiler_fun
cd compiler_fun
touch src/compiler_fun/core.cljs
curl -OL https://github.com/clojure/clojurescript/releases/download/r3123/cljs.jar
touch build.clj
</code></pre></div></div>

<p>Use your favorite text editor to edit <code class="language-plaintext highlighter-rouge">src/compiler_fun/core.cljs</code>. Make
it look like the following:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">ns</span><span class="w"> </span><span class="n">compiler-fun.core</span><span class="p">)</span><span class="w">

</span><span class="p">(</span><span class="nb">nth</span><span class="w"> </span><span class="p">[</span><span class="mi">1</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="mi">3</span><span class="p">]</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="no">:oops</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<p>Let’s compile this simple program. Edit <code class="language-plaintext highlighter-rouge">build.clj</code> to look like the following:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">require</span><span class="w"> </span><span class="ss">'cljs.closure</span><span class="p">)</span><span class="w">

</span><span class="p">(</span><span class="nf">cljs.closure/build</span><span class="w"> </span><span class="s">"src"</span><span class="w">
 </span><span class="p">{</span><span class="no">:output-to</span><span class="w"> </span><span class="s">"out/main.js"</span><span class="w">
  </span><span class="no">:verbose</span><span class="w"> </span><span class="n">true</span><span class="p">})</span><span class="w">
</span></code></pre></div></div>

<p>Let’s compile:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java -cp cljs.jar:src clojure.main build.clj
</code></pre></div></div>

<p>Examine <code class="language-plaintext highlighter-rouge">out/compiler_fun/core.js</code>. Notice that <code class="language-plaintext highlighter-rouge">nth</code> got compiled to
something like the following:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">cljs</span><span class="p">.</span><span class="nx">core</span><span class="p">.</span><span class="nx">nth</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span><span class="k">new</span> <span class="nx">cljs</span><span class="p">.</span><span class="nx">core</span><span class="p">.</span><span class="nx">PersistentVector</span><span class="p">(...));</span>
</code></pre></div></div>

<p>You’re probably wondering why we would do the obviously slow thing and
go through <code class="language-plaintext highlighter-rouge">call</code> here? In ClojureScript data structures are functions
too, by invoking through <code class="language-plaintext highlighter-rouge">call</code> we can have higher order call sites
that can invoke data structures as well as functions.</p>

<p>If we examine <code class="language-plaintext highlighter-rouge">out/cljs/core.js</code> and search for the value of
<code class="language-plaintext highlighter-rouge">cljs.core.nth</code> we’ll see a fairly large function that is invoked
immediately. This function creates the arity dispatcher. You’ll see
that the dispatcher looks something like the following and
interestingly has the different arities assigned as properties as
well. We see how the properties are used shortly:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">cljs$core$nth</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">coll</span><span class="p">,</span> <span class="nx">n</span><span class="p">,</span> <span class="nx">not_found</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">switch</span> <span class="p">(</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">case</span> <span class="mi">2</span><span class="p">:</span>
            <span class="k">return</span> <span class="nx">cljs$core$nth__2</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">coll</span><span class="p">,</span> <span class="nx">n</span><span class="p">);</span>
        <span class="k">case</span> <span class="mi">3</span><span class="p">:</span>
            <span class="k">return</span> <span class="nx">cljs$core$nth__3</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">coll</span><span class="p">,</span> <span class="nx">n</span><span class="p">,</span> <span class="nx">not_found</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">throw</span> <span class="p">(</span><span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="dl">'</span><span class="s1">Invalid arity: </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span><span class="p">));</span>
<span class="p">};</span>
<span class="nx">cljs$core$nth</span><span class="p">.</span><span class="nx">cljs$core$IFn$_invoke$arity$2</span> <span class="o">=</span> <span class="nx">cljs$core$nth__2</span><span class="p">;</span>
<span class="nx">cljs$core$nth</span><span class="p">.</span><span class="nx">cljs$core$IFn$_invoke$arity$3</span> <span class="o">=</span> <span class="nx">cljs$core$nth__3</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">cljs$core$nth</span><span class="p">;</span>
</code></pre></div></div>

<p>Why do we use <code class="language-plaintext highlighter-rouge">call</code> again here paired with <code class="language-plaintext highlighter-rouge">this</code>? This is because
the dispatcher might end up as a method on a data structure. While
useless in this context, we can keep the compiler uniform. We won’t be
going through the dispatcher in production anyway.</p>

<p>Let’s change <code class="language-plaintext highlighter-rouge">build.clj</code> to the following:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">require</span><span class="w"> </span><span class="ss">'cljs.closure</span><span class="p">)</span><span class="w">

</span><span class="p">(</span><span class="nf">cljs.closure/build</span><span class="w"> </span><span class="s">"src"</span><span class="w">
  </span><span class="p">{</span><span class="no">:output-to</span><span class="w"> </span><span class="s">"out/main.js"</span><span class="w">
   </span><span class="no">:optimizations</span><span class="w"> </span><span class="no">:simple</span><span class="w">
   </span><span class="no">:static-fns</span><span class="w"> </span><span class="n">true</span><span class="w">
   </span><span class="no">:pretty-print</span><span class="w"> </span><span class="n">true</span><span class="w">
   </span><span class="no">:verbose</span><span class="w"> </span><span class="n">true</span><span class="p">})</span><span class="w">

</span><span class="p">(</span><span class="nf">System/exit</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<p>And rebuild:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">java</span> <span class="o">-</span><span class="nx">cp</span> <span class="nx">cljs</span><span class="p">.</span><span class="nx">jar</span><span class="p">:</span><span class="nx">src</span> <span class="nx">clojure</span><span class="p">.</span><span class="nx">main</span> <span class="nx">build</span><span class="p">.</span><span class="nx">clj</span>
</code></pre></div></div>

<p>This time we examine <code class="language-plaintext highlighter-rouge">out/main.js</code>. Since we use a Google Closure
optimization pass we end up with a single JavaScript file. By setting
<code class="language-plaintext highlighter-rouge">:static-fns</code> we are asking the ClojureScript compiler to leverage
static information. If we look at the end of the file we’ll see
something like this:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">cljs</span><span class="p">.</span><span class="nx">core</span><span class="p">.</span><span class="nx">nth</span><span class="p">.</span><span class="nx">cljs$core$IFn$_invoke$arity$3</span><span class="p">(</span><span class="k">new</span> <span class="nx">cljs</span><span class="p">.</span><span class="nx">core</span><span class="p">.</span><span class="nx">PersistentVector</span><span class="p">(...));</span>
</code></pre></div></div>

<p>The indirection of <code class="language-plaintext highlighter-rouge">call</code> has disappeared which means we’re not
switching on <code class="language-plaintext highlighter-rouge">arguments</code> anymore. The ClojureScript compiler has
static information about <code class="language-plaintext highlighter-rouge">nth</code>, it knows precisely what arities it
supports and can optimize the call.</p>

<p>Why don’t we always do this? The problem is that doing so for
development would break redefinition. Many ClojureScript programmers
enjoy redefining running programs as evidenced by the popularity of
REPL driven development and even more radical tools like
<a href="https://github.com/bhauman/lein-figwheel">Figwheel</a>.</p>

<p>There’s one final production optimization. In the above form many
JavaScript engines do not optimize nested property accesses like
this. Google Closure in advanced compilation mode will collapse the
namespace convention.</p>

<p>Change your <code class="language-plaintext highlighter-rouge">build.clj</code> to the following:</p>

<div class="language-clj highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nf">require</span><span class="w"> </span><span class="ss">'cljs.closure</span><span class="p">)</span><span class="w">

</span><span class="p">(</span><span class="nf">cljs.closure/build</span><span class="w"> </span><span class="s">"src"</span><span class="w">
  </span><span class="p">{</span><span class="no">:output-to</span><span class="w"> </span><span class="s">"out/main.js"</span><span class="w">
   </span><span class="no">:optimizations</span><span class="w"> </span><span class="no">:advanced</span><span class="w">
   </span><span class="no">:pretty-print</span><span class="w"> </span><span class="n">true</span><span class="w">
   </span><span class="no">:pseudo-names</span><span class="w"> </span><span class="n">true</span><span class="w">
   </span><span class="no">:verbose</span><span class="w"> </span><span class="n">true</span><span class="p">})</span><span class="w">

</span><span class="p">(</span><span class="nf">System/exit</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w">
</span></code></pre></div></div>

<p>And rebuild:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">java</span> <span class="o">-</span><span class="nx">cp</span> <span class="nx">cljs</span><span class="p">.</span><span class="nx">jar</span><span class="p">:</span><span class="nx">src</span> <span class="nx">clojure</span><span class="p">.</span><span class="nx">main</span> <span class="nx">build</span><span class="p">.</span><span class="nx">clj</span>
</code></pre></div></div>

<p>We pretty-print and enable <code class="language-plaintext highlighter-rouge">:pseudo-names</code> so that we can see human
readable output. Now if we look at the last line of <code class="language-plaintext highlighter-rouge">out/main.js</code>
we’ll see:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">$cljs$core$nth$$</span><span class="p">.</span><span class="nx">$cljs$core$IFn$_invoke$arity$3$</span><span class="p">(...);</span>
</code></pre></div></div>

<p>The nested property access is gone. This code will execute
significantly faster than the development version.</p>

<p>Future posts will cover protocol dispatch, type inference, arithmetic,
and other neat things we’re doing to ensure that ClojureScript is
zippy across JavaScript engines old and new.</p>]]></content><author><name>David Nolen</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Scripting ClojureScript with JavaScript</title><link href="https://swannodette.github.io/2015/03/10/scripting-clojurescript-with-javascript/" rel="alternate" type="text/html" title="Scripting ClojureScript with JavaScript" /><published>2015-03-10T00:00:00+00:00</published><updated>2015-03-10T00:00:00+00:00</updated><id>https://swannodette.github.io/2015/03/10/scripting-clojurescript-with-javascript</id><content type="html" xml:base="https://swannodette.github.io/2015/03/10/scripting-clojurescript-with-javascript/"><![CDATA[<p>The following code demonstrates how to script the ClojureScript
compiler with the Nashorn JavaScript engine that ships with Java 8.</p>

<p>Create a file called <code class="language-plaintext highlighter-rouge">build.js</code> with the following contents:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Use the Java interop clojure.lang.RT namespace to get at </span>
<span class="c1">// Clojure vars</span>
<span class="kd">var</span> <span class="nx">ArrayList</span> <span class="o">=</span> <span class="nx">java</span><span class="p">.</span><span class="nx">util</span><span class="p">.</span><span class="nx">ArrayList</span><span class="p">,</span>
    <span class="nx">RT</span> <span class="o">=</span> <span class="nb">Packages</span><span class="p">.</span><span class="nx">clojure</span><span class="p">.</span><span class="nx">lang</span><span class="p">.</span><span class="nx">RT</span><span class="p">,</span>
    <span class="nx">seq</span> <span class="o">=</span> <span class="nx">RT</span><span class="p">.</span><span class="kd">var</span><span class="p">(</span><span class="dl">"</span><span class="s2">clojure.core</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">seq</span><span class="dl">"</span><span class="p">);</span>

<span class="c1">// ================================================================================</span>
<span class="c1">// Bootstrap</span>

<span class="c1">// Nashorn JavaScript arrays don't satisfy java.util.List</span>
<span class="c1">// convert them into ArrayLists which do</span>
<span class="kd">var</span> <span class="nx">arrayToArrayList</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">arr</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">ret</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ArrayList</span><span class="p">();</span>
    <span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">arr</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">ret</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">arr</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="nx">ret</span><span class="p">;</span>
<span class="p">};</span>

<span class="c1">// Given a Clojure namespace and name get the var</span>
<span class="c1">// and return a JavaScript function which can invoke it</span>
<span class="c1">// in the usual JavaScript way</span>
<span class="kd">var</span> <span class="nx">varToFn</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">ns</span><span class="p">,</span> <span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// if only given one argument assume the namespace</span>
    <span class="c1">// is clojure.core</span>
    <span class="k">if</span><span class="p">(</span><span class="nx">name</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">name</span> <span class="o">=</span> <span class="nx">ns</span><span class="p">;</span>
        <span class="nx">ns</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">clojure.core</span><span class="dl">"</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="kd">var</span> <span class="nx">v</span> <span class="o">=</span> <span class="nx">RT</span><span class="p">.</span><span class="kd">var</span><span class="p">(</span><span class="nx">ns</span><span class="p">,</span> <span class="nx">name</span><span class="p">);</span>
    <span class="k">return</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nx">arrayToArrayList</span><span class="p">(</span><span class="nx">arguments</span><span class="p">);</span>
        <span class="k">return</span> <span class="nx">v</span><span class="p">.</span><span class="nx">applyTo</span><span class="p">(</span><span class="nx">seq</span><span class="p">.</span><span class="nx">invoke</span><span class="p">(</span><span class="nx">args</span><span class="p">));</span>
    <span class="p">};</span>
<span class="p">};</span>

<span class="kd">var</span> <span class="nx">hashMap</span> <span class="o">=</span> <span class="nx">varToFn</span><span class="p">(</span><span class="dl">"</span><span class="s2">hash-map</span><span class="dl">"</span><span class="p">),</span>
    <span class="nx">keyword</span> <span class="o">=</span> <span class="nx">varToFn</span><span class="p">(</span><span class="dl">"</span><span class="s2">keyword</span><span class="dl">"</span><span class="p">);</span>

<span class="c1">// Helper to convert JavaScript objects into Clojure</span>
<span class="c1">// hash maps</span>
<span class="kd">var</span> <span class="nx">objectToMap</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ArrayList</span><span class="p">();</span>
    <span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">p</span> <span class="k">in</span> <span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">arr</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">keyword</span><span class="p">(</span><span class="nx">p</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/</span><span class="se">([</span><span class="sr">a-z</span><span class="se">])([</span><span class="sr">A-Z</span><span class="se">])</span><span class="sr">/g</span><span class="p">,</span> <span class="dl">'</span><span class="s1">$1-$2</span><span class="dl">'</span><span class="p">).</span><span class="nx">toLowerCase</span><span class="p">()));</span>
        <span class="nx">arr</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">obj</span><span class="p">[</span><span class="nx">p</span><span class="p">]);</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="nx">hashMap</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nx">arr</span><span class="p">);</span>
<span class="p">};</span>

<span class="c1">// =============================================================================</span>
<span class="c1">// Fun Starts Here</span>

<span class="kd">var</span> <span class="nx">symbol</span> <span class="o">=</span> <span class="nx">varToFn</span><span class="p">(</span><span class="dl">"</span><span class="s2">symbol</span><span class="dl">"</span><span class="p">),</span>
    <span class="nx">require</span> <span class="o">=</span> <span class="nx">varToFn</span><span class="p">(</span><span class="dl">"</span><span class="s2">require</span><span class="dl">"</span><span class="p">);</span>

<span class="c1">// Load cljs.closure</span>
<span class="nx">require</span><span class="p">(</span><span class="nx">symbol</span><span class="p">(</span><span class="dl">"</span><span class="s2">cljs.closure</span><span class="dl">"</span><span class="p">));</span>

<span class="c1">// The actual build fn</span>
<span class="kd">var</span> <span class="nx">build_</span> <span class="o">=</span> <span class="nx">varToFn</span><span class="p">(</span><span class="dl">"</span><span class="s2">cljs.closure</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">build</span><span class="dl">"</span><span class="p">);</span>

<span class="c1">// Define a build function that can take an JavaScript object</span>
<span class="c1">// with camelCase keys</span>
<span class="kd">function</span> <span class="nx">build</span><span class="p">(</span><span class="nx">src</span><span class="p">,</span> <span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nx">build_</span><span class="p">(</span><span class="nx">src</span><span class="p">,</span> <span class="nx">objectToMap</span><span class="p">(</span><span class="nx">obj</span><span class="p">));</span>
<span class="p">}</span>

<span class="c1">// Build!</span>
<span class="nx">build</span><span class="p">(</span><span class="dl">"</span><span class="s2">src</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span><span class="na">outputTo</span><span class="p">:</span> <span class="dl">"</span><span class="s2">out/main.js</span><span class="dl">"</span><span class="p">});</span>
</code></pre></div></div>

<p>You can use this script in place of the <code class="language-plaintext highlighter-rouge">build.clj</code> script described
in the new
<a href="https://github.com/clojure/clojurescript/wiki/Quick-Start">ClojureScript Quick Start</a>
by running the following instead:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jjs -J-Djava.class.path=cljs.jar build.js
</code></pre></div></div>

<p>Fun stuff.</p>]]></content><author><name>David Nolen</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Lessons in the Fundamentals</title><link href="https://swannodette.github.io/2015/03/09/lessons-in-the-fundamentals/" rel="alternate" type="text/html" title="Lessons in the Fundamentals" /><published>2015-03-09T00:00:00+00:00</published><updated>2015-03-09T00:00:00+00:00</updated><id>https://swannodette.github.io/2015/03/09/lessons-in-the-fundamentals</id><content type="html" xml:base="https://swannodette.github.io/2015/03/09/lessons-in-the-fundamentals/"><![CDATA[<p><img width="300" style="margin-left: 143px; width: 300px; border: 1px solid #ccc" src="/assets/images/fundamentals.jpg" /></p>

<p><a href="https://github.com/clojure/clojurescript">ClojureScript 0.0-3058</a> is
a series of lessons in the fundamentals.</p>

<h2 id="read-eval-print-loop">Read-Eval-Print-Loop</h2>

<p>For the very first time ClojureScript ships with REPLs
that deliver the functionality people have long ago come to expect
from Clojure: <code class="language-plaintext highlighter-rouge">:reload</code>, <code class="language-plaintext highlighter-rouge">:reload-all</code>, <code class="language-plaintext highlighter-rouge">doc</code>, <code class="language-plaintext highlighter-rouge">source</code>, <code class="language-plaintext highlighter-rouge">find-doc</code>,
<code class="language-plaintext highlighter-rouge">apropos</code>, <code class="language-plaintext highlighter-rouge">dir</code>, and <code class="language-plaintext highlighter-rouge">pst</code> are all there.</p>

<p>All REPLs ship with source mapping support enabled. Whether you’re in a
REPL hooked up to Firefox, Safari, Chrome, Node.js, Rhino, or Nashorn
you will always get a <em>ClojureScript</em> stacktrace.</p>

<h2 id="compile-times">Compile Times</h2>

<p>While slow compile times are acceptable for production builds,
significantly slowing down the precious interactive programming
feedback loop McCarthy gave us during development is simply
unacceptable. ClojureScript now ships with aggressive caching features
enabled including a pre-compiled standard library, pre-calculated
analysis information, and pre-generated source map.</p>

<p>On my work machine I can now compile a trivial <code class="language-plaintext highlighter-rouge">"Hello world!"</code> from
cold JVM boot in around 1.7 seconds.</p>

<h2 id="utility-without-dependencies">Utility Without Dependencies</h2>

<p>My various “mies” Leiningen templates were patching over the fact that
it was pretty much impossible to try ClojureScript without Leiningen
or Maven to manage dependencies.</p>

<p>No more.</p>

<p>ClojureScript now provides a
<a href="https://github.com/clojure/clojurescript/releases/tag/r3058">standalone JAR</a>,
the only thing you need to bring is an installation of Java 8.</p>

<h2 id="the-fundamentals">The Fundamentals</h2>

<p>Even if you are an experienced ClojureScript developer it’s time to
revisit the
<a href="https://github.com/clojure/clojurescript/wiki/Quick-Start">fundamentals</a>.</p>

<p>I hope that through a shared understanding of the fundamentals we can
collectively push the broader ClojureScript ecosystem of libraries and
tooling to even greater heights.</p>

<p>Happy hacking!</p>]]></content><author><name>David Nolen</name></author><summary type="html"><![CDATA[]]></summary></entry></feed>