<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">>
  <channel>
    <title>clojure on Daniel Compton</title>
    <link>https://danielcompton.net/tags/clojure/index.xml</link>
    <description>Recent content in clojure on Daniel Compton</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 25 Jul 2022 13:30:36 +1200</lastBuildDate><atom:link href="https://danielcompton.net/tags/clojure/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Leiningen dependency commands in Clojure CLI</title>
      <link>https://danielcompton.net/snippets/leiningen-dependency-commands-clojure-cli</link>
      <pubDate>Mon, 25 Jul 2022 13:30:36 +1200</pubDate>
      
      <guid>https://danielcompton.net/snippets/leiningen-dependency-commands-clojure-cli</guid>
      <description>At work, we have recently converted our projects to the Clojure CLI and deps.edn. There were a few commands from Leiningen that I needed to find an equivalent for when working with dependencies.
Download all dependencies Often in a CI environment, you want to download all of the dependencies for a project before building the project. In Leiningen, you can use lein deps to do this.
You can use clojure -P to Prepare the project with the Clojure CLI.</description>
      <content:encoded><![CDATA[<p>At <a href="https://whimsical.com/">work</a>, we have recently converted our projects to the Clojure CLI and <code>deps.edn</code>. There were a few commands from Leiningen that I needed to find an equivalent for when working with dependencies.</p>
<h2 id="download-all-dependencies">Download all dependencies</h2>
<p>Often in a CI environment, you want to download all of the dependencies for a project before building the project. In Leiningen, you can use <code>lein deps</code> to do this.</p>
<p>You can use <code>clojure -P</code> to <strong>P</strong>repare the project with the Clojure CLI. This downloads libs and caches the classpath.</p>
<p>Note that you should avoid running <code>clojure -P</code> in parallel on new environments (like CI). When running <code>clojure -P</code> for the first time, it will set up files in <code>~/.clojure</code> and clone gitlibs. If you run multiple processes doing this simultaneously, you can get race conditions that throw errors.</p>
<h2 id="view-the-dependency-tree">View the dependency tree</h2>
<p>When debugging dependency issues, it&rsquo;s often helpful to see which library pulled in a transitive dependency.</p>
<p>Leiningen can print the dependency showing the resolved transitive dependencies.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">$ lein deps :tree
</span></span><span class="line"><span class="cl"> <span class="o">[</span>clansi <span class="s2">&#34;1.0.0&#34;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"> <span class="o">[</span>clj-kondo <span class="s2">&#34;2022.03.09&#34;</span> :scope <span class="s2">&#34;test&#34;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"> <span class="o">[</span>babashka/fs <span class="s2">&#34;0.1.2&#34;</span> :scope <span class="s2">&#34;test&#34;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"> <span class="o">[</span>cheshire <span class="s2">&#34;5.10.2&#34;</span> :scope <span class="s2">&#34;test&#34;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"> <span class="o">[</span>com.fasterxml.jackson.dataformat/jackson-dataformat-cbor <span class="s2">&#34;2.12.4&#34;</span> :scope <span class="s2">&#34;test&#34;</span> :exclusions <span class="o">[[</span>com.fasterxml.jackson.core/jackson-databind<span class="o">]]]</span>
</span></span><span class="line"><span class="cl"> <span class="o">[</span>com.fasterxml.jackson.dataformat/jackson-dataformat-smile <span class="s2">&#34;2.12.4&#34;</span> :scope <span class="s2">&#34;test&#34;</span> :exclusions <span class="o">[[</span>com.fasterxml.jackson.core/jackson-databind<span class="o">]]]</span>
</span></span><span class="line"><span class="cl"> <span class="o">[</span>tigris <span class="s2">&#34;0.1.2&#34;</span> :scope <span class="s2">&#34;test&#34;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"> <span class="o">[</span>com.cognitect/transit-clj <span class="s2">&#34;1.0.324&#34;</span> :scope <span class="s2">&#34;test&#34;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># ...</span>
</span></span></code></pre></div><p><code>clojure</code> has a similar command, though with a slightly different output. In contrast to Leiningen, <code>clojure</code> prints the entire dependency tree. Dependencies <code>clojure</code> didn&rsquo;t select get an <code>X</code> in front of them, and a short reason like <code>:older-version</code> or <code>:excluded</code>. These views can be helpful when debugging why you didn&rsquo;t get the version you expected.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">$ clojure -Stree
</span></span><span class="line"><span class="cl">org.clojure/clojure 1.11.0
</span></span><span class="line"><span class="cl"> . org.clojure/spec.alpha 0.3.218
</span></span><span class="line"><span class="cl"> . org.clojure/core.specs.alpha 0.2.62
</span></span><span class="line"><span class="cl">org.clojure/java.classpath 1.0.0
</span></span><span class="line"><span class="cl">clansi/clansi 1.0.0
</span></span><span class="line"><span class="cl">org.clojure/data.json 2.4.0
</span></span><span class="line"><span class="cl">org.slf4j/slf4j-simple 2.0.0-alpha1
</span></span><span class="line"><span class="cl"> . org.slf4j/slf4j-api 2.0.0-alpha1
</span></span><span class="line"><span class="cl">org.owasp/dependency-check-core 7.0.2
</span></span><span class="line"><span class="cl"> . us.springett/cpe-parser 2.0.2
</span></span><span class="line"><span class="cl"> X org.slf4j/slf4j-api 1.7.30 :older-version
</span></span><span class="line"><span class="cl"> . com.vdurmont/semver4j 3.1.0
</span></span><span class="line"><span class="cl"> X org.slf4j/slf4j-api 1.7.36 :older-version
</span></span></code></pre></div><h2 id="view-the-classpath">View the Classpath</h2>
<p>While dependency trees can help track down dependency problems, sometimes you need to see the actual classpath.</p>
<p>Tip: I like to use <code> | tr ':' '\n' | sort</code> to get a sorted list of the classpath entries.</p>
<p>You can do this in Leiningen:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">lein classpath
</span></span><span class="line"><span class="cl"><span class="c1"># or</span>
</span></span><span class="line"><span class="cl">lein classpath <span class="p">|</span> tr <span class="s1">&#39;:&#39;</span> <span class="s1">&#39;\n&#39;</span> <span class="p">|</span> sort
</span></span></code></pre></div><p>With <code>clojure</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">clojure -Spath
</span></span></code></pre></div><p>Both Leiningen and <code>clojure</code> have more commands for dependencies; you can read more about them at <a href="https://clojure.org/reference/dep_expansion">Dep Expansion</a>, <a href="https://clojure.org/reference/deps_and_cli">Deps and CLI</a>, and <a href="https://github.com/technomancy/leiningen/blob/ee6b88beb8a82ae11605bc8f3e20c22f1a5ca886/src/leiningen/deps.clj#L109-L151">lein deps</a>.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Using classifiers with deps.edn</title>
      <link>https://danielcompton.net/snippets/how-to-use-classifier-in-tools-deps</link>
      <pubDate>Tue, 19 Jul 2022 12:10:36 +1200</pubDate>
      
      <guid>https://danielcompton.net/snippets/how-to-use-classifier-in-tools-deps</guid>
      <description>One of Maven&amp;rsquo;s dependency management features is the classifier. Classifiers let you create multiple different artifacts from the same POM. You might use this to publish variations with native libraries for each OS, or to support different Java versions. This is also how sources and javadoc artifacts are created.
In Maven you can specify a dependency on a version with &amp;lt;classifier&amp;gt; like this:
&amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;io.netty&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;netty-transport-native-epoll&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;4.1.74&amp;lt;/version&amp;gt; &amp;lt;classifier&amp;gt;linux-x86_64&amp;lt;/classifier&amp;gt; &amp;lt;/dependency&amp;gt; To specify this dependency with Clojure&amp;rsquo;s deps.</description>
      <content:encoded><![CDATA[<p>One of Maven&rsquo;s dependency management features is the <a href="https://maven.apache.org/pom.html">classifier</a>. Classifiers let you create multiple different artifacts from the same POM. You might use this to publish variations with native libraries for each OS, or to support different Java versions. This is also how <code>sources</code> and <code>javadoc</code> artifacts are created.</p>
<p>In Maven you can specify a dependency on a version with <code>&lt;classifier&gt;</code> like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;dependency&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;groupId&gt;</span>io.netty<span class="nt">&lt;/groupId&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;artifactId&gt;</span>netty-transport-native-epoll<span class="nt">&lt;/artifactId&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;version&gt;</span>4.1.74<span class="nt">&lt;/version&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;classifier&gt;</span>linux-x86_64<span class="nt">&lt;/classifier&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/dependency&gt;</span>
</span></span></code></pre></div><p>To specify this dependency with Clojure&rsquo;s deps.edn, you need to use the <a href="https://clojure.org/reference/deps_and_cli#_dependencies">syntax</a> <code>&lt;group&gt;/&lt;artifact&gt;$&lt;classifier&gt;</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-clj" data-lang="clj"><span class="line"><span class="cl"><span class="p">{</span><span class="ss">:deps</span> 
</span></span><span class="line"><span class="cl">  <span class="p">{</span><span class="nv">io.netty/netty-transport-native-epoll$linux-x86_64</span> 
</span></span><span class="line"><span class="cl">    <span class="p">{</span><span class="ss">:mvn/version</span> <span class="s">&#34;4.1.74.Final&#34;</span><span class="p">}}}</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>Why Heart of Clojure was special</title>
      <link>https://danielcompton.net/heart-of-clojure</link>
      <pubDate>Sat, 24 Aug 2019 20:54:05 +1300</pubDate>
      
      <guid>https://danielcompton.net/heart-of-clojure</guid>
      <description>A few weeks ago I got to attend and speak at Heart of Clojure. I met lots of online friends in person for the first time, and made some new ones too. I&amp;rsquo;ve thought a lot about how to describe it since then, and every time I come back to the word special.
Others have also posted their thoughts on Heart of Clojure: Fork This Conference, The people’s conference, The hallway track conference, Community with lots of heart, and A courageous conference?</description>
      <content:encoded><![CDATA[<p>A few weeks ago I got to attend and speak at <a href="https://heartofclojure.eu">Heart of Clojure</a>. I met lots of online friends in person for the first time, and made some new ones too. I&rsquo;ve thought a lot about how to describe it since then, and every time I come back to the word special.</p>
<p>Others have also posted their thoughts on Heart of Clojure: <a href="https://lambdaisland.com/blog/2019-08-09-fork-this-conference">Fork This Conference</a>, <a href="http://manuel-uberti.github.io//clojure/2019/08/04/clojure-heart/">The people’s conference</a>, <a href="https://quanttype.net/posts/2019-08-12-hallway-track-conference.html">The hallway track conference</a>, <a href="http://www.saskialindner.com/blog/2019-08-16-community-with-heart/">Community with lots of heart</a>, and <a href="https://mallozup.github.io/posts/heartofclojure/">A courageous conference?</a>.</p>
<p>Here were some things that I think made Heart of Clojure so special. If you&rsquo;re running a conference, consider stealing some of these ideas.</p>
<ul>
<li>There was an <a href="https://activities.heartofclojure.eu">site</a> which listed activities around the event. Anyone could host an activity and others could join. Having it on a website meant everyone knew what was happening around the conference. I felt like this helped Heart of Clojure feel very welcoming to all of the conference goers, especially those who were less outgoing.</li>
<li>One of the nights I joined an activity for an adventurous dinner. People got split into groups of 6-8 with a reservation at a restaraunt in Leuven. This broke up friend groups and introduced me to a bunch of new people. The restaurant we went to had their own brewery, and I got to try the flavours of a beer soup, beer stew, and beer crème brûlée!</li>
<li>Yulia Startsev&rsquo;s talk <a href="https://www.youtube.com/watch?v=-IGViUlbemo&amp;feature=youtu.be">To loosen up, to put together</a> set the tone for the conference and captured the spirit of mixing technology and the humanities. Many of the talks and conversations referenced her talk throughout the rest of the event.</li>
<li>Leuven was a perfect town to have the conference. It was large enough to have a good nightlife, but small enough that you could walk between the conference venue, the bars, restauruants, and hotels in 10-15 minutes.</li>
<li>In the months before the conference, <a href="https://www.janstepien.com">Jan Stępień</a> paired up new speakers with more experienced speakers. This was my first conference talk, and I got paired up with Tiago Luchini. Tiago was a very experienced public speaker and gave me great feedback on my talk. Having to show someone my presentation helped me get it into shape well before the conference. I think Jan&rsquo;s work here contributed to the high quality of the talks at the conference.</li>
<li>I&rsquo;m not a vegeterian, but I really appreciated that all of the breakfast and lunches were vegeterian. I can imagine it would have made things very easy for vegeterians. The food was delicious and healthy tasting.</li>
<li>There was ample time left around the talks so that you didn&rsquo;t need to choose between the &lsquo;hallway track&rsquo; and the conference track. On the Saturday there was a siesta break between 12pm and 4pm. You could do one of the activities, take a nap, or just chat with others. I was a bit skeptical before the conference that this was going to be too long, but it worked out really well.</li>
<li>The lightning talks on Saturday broke up the afternoon and left space for serendipity to strike. Connie&rsquo;s <a href="https://www.youtube.com/watch?v=qyhjok21Y3o&amp;list=PLhYmIiHOMWoEgJEvgkmUe8D0agxy_T2vR&amp;index=16&amp;t=0s">talk</a> on waffles, Vim, and building her own language captured the audience.</li>
<li>On the Saturday evening after the conference ended, lots of people stayed behind to help pack down the auditorium. This made the job much easier.</li>
<li>There was a large contingent of people from Berlin, and they were all incredible. Berlin feels like it has a really vibrant community, one day I&rsquo;d like to visit it.</li>
</ul>
<p>Heart of Clojure was a very special event. I can&rsquo;t imagine how much work it was for Arne Brasseur, Martin Klepsch, and all of the other helpers before, during, and after the event but it paid off. Heart of Clojure felt like a very polished event, not something being put on for the first time. Thanks to everyone who organised, helped out, spoke, sponsored, and attended the conference. I hope there is another Heart of Clojure in the future, if you get a chance to go, I highly recommend it.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>What do :project/dev and :profiles/dev mean in a Leiningen project?</title>
      <link>https://danielcompton.net/snippets/what-do-project-dev-profiles-dev-mean-leiningen</link>
      <pubDate>Fri, 23 Aug 2019 07:23:48 +1300</pubDate>
      
      <guid>https://danielcompton.net/snippets/what-do-project-dev-profiles-dev-mean-leiningen</guid>
      <description>A few years ago I came across a Leiningen project that defined profiles for :project/dev, :profiles/dev, :project/test, and :profiles/test. It took me a little bit of digging, but eventually I discovered what was happening. This is a convention that I think originated with James Reeves. I&amp;rsquo;m reposting my issue comment here, so it can be more accessible for searchers.
If you see profiles like this in a project.clj, here is what is happening:</description>
      <content:encoded><![CDATA[<p>A few years ago I came across a Leiningen project that defined profiles for <code>:project/dev</code>, <code>:profiles/dev</code>, <code>:project/test</code>, and <code>:profiles/test</code>. It took me a little bit of digging, but eventually I discovered what was happening. This is a convention that I think originated with <a href="https://github.com/weavejester">James Reeves</a>. I&rsquo;m reposting my <a href="https://github.com/weavejester/environ/issues/15#issuecomment-293144253">issue comment</a> here, so it can be more accessible for searchers.</p>
<p>If you see profiles like this in a <code>project.clj</code>, here is what is happening:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-clojure" data-lang="clojure"><span class="line"><span class="cl"><span class="ss">:dev</span>  <span class="p">[</span><span class="ss">:project/dev</span>  <span class="ss">:profiles/dev</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="ss">:test</span> <span class="p">[</span><span class="ss">:project/test</span> <span class="ss">:profiles/test</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="ss">:profiles/dev</span>  <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="ss">:profiles/test</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"><span class="ss">:project/dev</span>  <span class="p">{</span> <span class="nv">...</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="ss">:project/test</span> <span class="p">{</span> <span class="nv">...</span> <span class="p">}</span>
</span></span></code></pre></div><p>Leiningen has a feature called <a href="https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md#composite-profiles">Composite Profiles</a>. On startup, if Leiningen sees a vector of keywords for a profile, it will lookup each keyword as a profile, and merge them together. For the <code>:dev</code> profile, Leiningen will merge the values of <code>:project/dev</code> and <code>:profiles/dev</code>.</p>
<p>If you want to add any custom settings or dependencies for your own use, you can place them into the <code>:profiles/dev</code> or <code>:profiles/test</code> in your <code>~/.lein/profiles.clj</code>. If either of these are set in the user&rsquo;s <code>profiles.clj</code>, they will override the empty <code>:profiles/dev</code> map specified in the <code>project.clj</code>. You need an empty map for <code>:profiles/dev {}</code> in the <code>project.clj</code>, because otherwise Leiningen will complain about a missing profile.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Announcing defn-spec, a library to create specs inline with your defn</title>
      <link>https://danielcompton.net/announcing-defn-spec</link>
      <pubDate>Sun, 31 Mar 2019 20:31:25 +1300</pubDate>
      
      <guid>https://danielcompton.net/announcing-defn-spec</guid>
      <description>I&amp;rsquo;m pleased to announce the initial release of defn-spec, a library to create specs inline with your defn.
[net.danielcompton/defn-spec-alpha &amp;quot;0.1.0&amp;quot;]
A quick peek at defn-spec:
(ds/defn to-zoned-dt :- ::zoned-date-time [instant :- ::instant zone-id :- ::zone-id] (ZonedDateTime/ofInstant instant zone-id))  One of the features in Schema that I always appreciated was inline function schemas, using a schema.core/defn macro.
When spec was released it had many similarities to Schema, but one thing it didn&amp;rsquo;t have was a way of expressing specs inline with your function definition.</description>
      <content:encoded><![CDATA[<p>I&rsquo;m pleased to announce the initial release of <a href="https://github.com/danielcompton/defn-spec">defn-spec</a>, a library to create specs inline with your <code>defn</code>.</p>
<p><code>[net.danielcompton/defn-spec-alpha &quot;0.1.0&quot;]</code></p>
<p>A quick peek at <code>defn-spec</code>:</p>
<pre><code>(ds/defn to-zoned-dt :- ::zoned-date-time
  [instant :- ::instant
   zone-id :- ::zone-id]
  (ZonedDateTime/ofInstant instant zone-id))
</code></pre>
<p>One of the features in <a href="https://github.com/plumatic/schema">Schema</a> that I always appreciated was inline function schemas, using a <code>schema.core/defn</code> macro.</p>
<p>When spec was released it had many similarities to Schema, but one thing it didn&rsquo;t have was a way of expressing specs inline with your function definition. Spec only supported defining function specs separately with <code>fdef</code>. This does have some advantages, it forces you to think carefully about changing your specs, and to be aware of possibly breaking consumers. While this is valuable, not all code is written to these constraints, and I found having <code>fdef</code>&rsquo;s separate from the function definition had a number of downsides.</p>
<p>When writing Clojure, I noticed that I often resisted writing specs for functions. After thinking about it I realised that I didn&rsquo;t want to duplicate information from the <code>defn</code> into the <code>fdef</code>. It&rsquo;s not a huge deal, but it was enough to deter me from writing specs on code that was being heavily modified. This is a really useful time to have basic specs on your functions, so that you can catch refactorings gone wrong early.</p>
<p>I created defn-spec to increase the locality of the spec definitions, and to reduce the activation energy to start adding specs to your codebase. defn-spec copies the syntax (and implementation) of Schema&rsquo;s <code>defn</code> macro. This has the advantage of adopting a proven design, familiarity for many Clojurists, and the ability to work with existing tooling that understands the Schema <code>defn</code> macro.</p>
<h2 id="benefits-and-tradeoffs">Benefits and tradeoffs</h2>
<p>Like all things in life, defn-spec has benefits and tradeoffs:</p>
<p><strong>Benefits</strong></p>
<ul>
<li>Makes it easy to incrementally spec your functions. It lowers the activation energy needed to add a spec, perhaps just for a single arg or return value.</li>
<li>Makes it easier to see more code on one screen.</li>
<li>Makes it harder for your specs to get out of sync with the function definition, as they are linked together. Depending on how you instrument your specs, it may be possible to go quite some time before you realise that your specs are broken.</li>
<li>Avoids repeating all argument names in the <code>s/cat</code> form.</li>
</ul>
<p><strong>Tradeoffs</strong></p>
<ul>
<li>For some specs, particularly complex <code>:args</code> specs with many branches, it may be simpler to define the <code>fdef</code> separately. <code>defn-spec</code> is designed for the 80-90% of Clojure functions that have simple argument lists and return types.</li>
<li>Making it easier to change specs means that it is easier to accidentally break your callers. If your <code>fdef</code> is defined separately, it forces you to think more about growing the spec.</li>
</ul>
<p>This is similar to Orchestra&rsquo;s <a href="https://github.com/jeaye/orchestra#defn-spec">defn-spec</a> macro, but allows for optionally only speccing part of the function, and matches the well-known Schema defn syntax. Try them both out though, and see which one works best for you. defn-spec is still missing some features from the defn macro like destructuring, but they are on the roadmap to be added soon. I&rsquo;m releasing this early to get feedback from other users.</p>
<p>defn-spec will follow Spec&rsquo;s release cycle, and there will be a new set of namespaces and artifacts for spec-alpha2 and beyond. If you have features/bug reports, feel free to post them on <a href="https://github.com/danielcompton/defn-spec">GitHub</a>.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>State of Clojure Survey 2019 Analysis</title>
      <link>https://danielcompton.net/clojure-survey-2019</link>
      <pubDate>Wed, 06 Feb 2019 23:41:45 +1300</pubDate>
      
      <guid>https://danielcompton.net/clojure-survey-2019</guid>
      <description>Cognitect have recently released the results of their State of Clojure Survey for 2019. For the last three Clojure surveys, I have reviewed the free-form answers at the end of the survey and tried to summarise how the community is feeling. This year I&amp;rsquo;m repeating the exercise, keeping the same categories as before. If you&amp;rsquo;d like to see all of the comments, I&amp;rsquo;ve published them in rough groupings.
Some comments have been lightly edited for spelling, clarity, and brevity.</description>
      <content:encoded><![CDATA[<p>Cognitect have recently released the <a href="https://clojure.org/news/2019/02/04/state-of-clojure-2019">results</a> of their State of Clojure Survey for 2019. For <a href="/2016/01/29/clojure-survey-2015">the</a> <a href="/2017/02/08/clojure-survey-2016">last</a> <a href="/2018/03/28/clojure-survey-2018">three</a> Clojure surveys, I have reviewed the free-form answers at the end of the survey and tried to summarise how the community is feeling. This year I&rsquo;m repeating the exercise, keeping the same categories as before. If you&rsquo;d like to see all of the comments, I&rsquo;ve <a href="/assets/outlines/clojure-survey-2019/">published</a> them in rough groupings.</p>
<p>Some comments have been lightly edited for spelling, clarity, and brevity.</p>
<p><strong>Update:</strong> Alex Miller has <a href="http://insideclojure.org/2019/02/07/survey-comments/">posted</a> a few responses to some of the comments I highlighted below, and some suggestions for the next steps that people can take to help.</p>
<h2 id="error-messages">Error messages</h2>
<p>Error messages have been a top complaint in Clojure for a long time, I think since the very first survey. <a href="https://dev.clojure.org/jira/browse/CLJ-2373">CLJ-2373</a> introduced improvements to error messages in Clojure 1.10. A number of comments complained about error messages this year, but none of the complaints mentioned 1.10&rsquo;s changes. Given that 1.10 was <a href="https://clojure.org/news/2018/12/17/clojure110">released</a> on 17 December 2018, and the survey ran from 7-22 January 2019, it seems likely to me that many of the people complaining haven&rsquo;t tried the latest improvement to Clojure&rsquo;s error messages.</p>
<ul>
<li>I appreciate all the work that&rsquo;s been done in improving error messages. Thanks to Alex Miller and others!</li>
<li>Thanks for all of your hard work on Spec and the error messages in general (often caused by minor typos).</li>
<li>1.10 alleviates most of the problems I found with error messages. Since this was my single biggest concern I had with Clojure, I just want to say thank you for listening!</li>
<li>Just give me the Clojure filename and line where the exception happened, please. I beg of you.</li>
<li>Better error messages. Please!</li>
<li>Great to see the improved error messages in Clojure 1.10 - it was my number one issue in all previous Clojure surveys, but not this one :-)</li>
</ul>
<h2 id="spec">Spec</h2>
<p>Spec has been around for two and half years, but is still in alpha. A number of comments referenced Rich&rsquo;s recent <a href="https://www.youtube.com/watch?v=YR5WdGrpoug">Maybe Not</a> talk about coming changes to Spec. It was great to see Rich putting in to words some of the problems I had felt. It feels like the community is in a transitional phase with spec, where people are still not quite sure where things are going to land.</p>
<ul>
<li>Clojure spec tooling would be nice! Because it&rsquo;s hard to learn and visualize&ndash;and it&rsquo;s not obvious how to integrate it with normal deftest tests. It has a massive amount of IDE integration potential though.</li>
<li>I&rsquo;d really love spec to feel a little more complete. &hellip; I&rsquo;ve got a lot of love for spec as a project and use it heavily at work, but I feel it&rsquo;s shadowed at the moment by some ambiguity about what changes might be on the way.</li>
<li>Spec has great potential, but really bad UX. If you are new to Clojure it&rsquo;s very hard to figure out what&rsquo;s wrong. Spec made Clojure errors worse.</li>
<li>Spec should have better tool integration and more static analysis facilities.</li>
<li>Really excited to see the direction spec is heading, can&rsquo;t wait to see the next iteration.</li>
<li>Thank you again, for all that you have given to us. Looking forward to the improvements in spec from “Maybe Not?”! I am certainly feeling the pain points they address, and currently work around them by generating heaps of variations on essentially the same spec per fdef.</li>
<li>I couldn&rsquo;t put my finger on it, but it always felt a bit awkward to use specs and had to juggle the spec and what the spec meant at a particular point in time during the flow of my software. Thanks Mr. Hickey for the presentation during Conj, it finally makes sense! I&rsquo;m looking forward to the next iteration of spec.</li>
</ul>
<h2 id="docs">Docs</h2>
<p>Documentation has continued to be a sore spot for beginners. API docstrings were often cited as being too hard to understand, instead people preferred to see examples at <a href="https://clojuredocs.org">clojuredocs.org</a>. The documentation at <a href="https://clojure.org">clojure.org</a> has grown this year with a number of great <a href="https://clojure.org/guides/guides">guides</a> added, particularly <a href="https://clojure.org/guides/repl/introduction">Programming at the REPL</a>.</p>
<ul>
<li>Concerning docs, I&rsquo;m seldom able to really make use of the Clojure API docs. Since examples help me more to understand what a function does, I rely more often upon the examples provided by the community at <a href="https://clojuredocs.org">clojuredocs</a>. However, the quality of the examples vary and it would be helpful if there was a set of curated examples.</li>
<li>Clojure is great, but the main website, docs, examples and tutorials are not good. I would invest time in improving it as it has become a barrier for the language.</li>
<li>I wish we had a better documentation generator and a better culture of documentation. I really miss the documentation in the Haskell ecosystem (and five years ago, I never thought I would be saying that!). For example, the Haskell community generally expects detailed documentation of data structures, including detailed asymptotics, e.g. <a href="http://hackage.haskell.org/package/containers-0.6.0.1/docs/Data-Sequence.html">Data.Sequence</a>. This complaint extends to many of Clojure&rsquo;s included features, too. Headline features like STM have incredibly sparse documentation (about one printed page with the semantics only hinted at), so I&rsquo;m left guessing at what I can actually do with these things.</li>
<li>The beginner support is exceptionally good. I think I would appreciate more intermediate to advanced support, in the form of books, courseware etc. to carry through to advanced Clojure.</li>
<li>I love Clojure. The docs are phenomenal. The improvements to the ClojureScript site and getting started and the CLI tools have been huge.</li>
<li>As a beginner I really struggle to understand the api docs. I tend to use third-party websites more often.</li>
<li>It would be great to know things like when to use a record vs a map. Intermediate guides would be nice. Also a guide on effective idiomatic Clojure like <a href="https://golang.org/doc/effective_go.html">golang provides</a>.</li>
<li>Please work on improving the ease of use. The doc strings for the core language are third rate, poorly written, cryptic and unhelpful. The error messages (although presented more nicely in 1.10) are still the same terrible error messages as they have been for years.</li>
<li>I&rsquo;d ask for more examples in documentation and provide more tutorials like <a href="https://twitter.github.io/scala_school/">Scala School</a> or <a href="https://elixirschool.com/en/">Elixir School</a> for Clojure, for newbies like me.</li>
<li>Beginner experience still needs more work. Please consult with first-time programmers and teachers who teach them.</li>
</ul>
<h2 id="startup-time">Startup time</h2>
<p>Startup time has been a perennial complaint, and there haven&rsquo;t been any major changes here.</p>
<ul>
<li>This long-standing issue of startup time + poor runtime performance (out of the box, without tinkering) + insanely high memory usage is becoming the major drawback of the language for me (and us). We are planning to move to a faster language (probably Rust or Go).</li>
<li>I would like to use Clojure (not CLJS) in AWS Lambdas for a side project but the painfully slow startup time prevents me from doing so. Improving startup times will do more than just improve developer happiness, it will make Clojure a much better tool for serverless computing.</li>
</ul>
<h2 id="marketingadoptionstaffing">Marketing/adoption/staffing</h2>
<p>Clojure continues to grow in business adoption, but hiring developers has been one of the top three things preventing people from using Clojure for the last three years. I&rsquo;ll add that one way that companies could address the mismatched supply and demand of Clojure developers is being more open to remote workers. <strong>Update:</strong> Alex Miller also suggested training people in Clojure, which I thought about when preparing the post, but forgot to include in the final copy.</p>
<p>A new option in the survey this year was &ldquo;Convincing coworkers/companies/clients&rdquo;; it was ranked number one in preventing people from adopting Clojure. In my opinion, this is a significant issue to be addressed if Clojure wants to grow its market share further. This probably needs more research to find out what the barriers are to convincing people. Elm is proof that exotic languages can be adopted widely, we should learn from what they&rsquo;ve done.</p>
<ul>
<li>We&rsquo;d all benefit from wider Clojure take up. I worry about the view from the outside looking in. Why is it not attractive to more?</li>
<li>My biggest problem after one year of intense Clojure learning/coding is to find a Clojure job as remote (because there are zero Clojure jobs in Taiwan). Regardless of how good I am at writing functional code, finding a remote job (outside of the US) is hard.</li>
<li>Very passionate evangelist 5+ years &ndash; It&rsquo;s surprising how hard it is to have some folks even consider Clojure. Rubyists are particularly baffled: &ldquo;ok what do you mean REPL driven &ndash; we have pry!&rdquo;, etc.</li>
<li>I co-founded a startup company and we picked Clojure as our primary language and are very happy with the decision. A nice note is that almost none of our hires knew Clojure before, they all learned it quickly and like it! I don&rsquo;t see a lack of Clojure talent as a concern at all.</li>
<li>Clojure is thoughtfully designed and stable. It’s a dynamic, functional lisp that can actually be sold to the bosses (A sentence I never thought I would write).</li>
<li>Clojure has a great community and great technology but it would be super helpful in selling the language if there were more efforts put into marketing the language and perhaps having &ldquo;blessed&rdquo; solutions using Clojure from Cognitect; similar to what Lightbend does with Scala.</li>
<li>Thank you for all the hard work you all have been and continue to put into Clojure. We&rsquo;ve built our entire new startup on Clojure, and was able to hire an amazing team within just a year by tapping into the local, tight-knit community.</li>
</ul>
<h2 id="language">Language</h2>
<p>There were again more suggestions for improvements to existing language features, or development of new ones.</p>
<ul>
<li>Please, take a look once again at <a href="http://www.dunaj.org">Dunaj Project</a> or similar ideas. I believe that the community still have many great ideas which could be adopted by Clojure and wouldn&rsquo;t bring up any breaking changes. And we need better IDE for sure.</li>
<li>Please spend time improving clojure.test.</li>
<li>When I dream, I dream of seeing a slime-style backtrace in Clojure.</li>
<li>ClojureScript namespace definition &lt;-&gt; :require &lt;-&gt; macro &amp; reader conditionals - and how these interact with each other is seriously non-trivial; especially so for macros you intend to use in Clojure too. Simplification there would be welcome, if possible.</li>
</ul>
<h2 id="language-development-process">Language Development Process</h2>
<p>2018 had a <a href="https://gist.github.com/richhickey/1563cddea1002958f96e7ba9519972d9">lot</a> <a href="https://twitter.com/cemerick/status/1067111260611850240">of</a> <a href="https://gist.github.com/halgari/c17f378718cbd2fd82324002133ef678">discussions</a> <a href="https://gist.github.com/halgari/c17f378718cbd2fd82324002133ef678#gistcomment-2768338">about</a> Clojure&rsquo;s development process, and the relationship between the core team and the community. I was very curious to see how widely those feelings were reflected in the free-form comments from respondents. After compliments (~230), this was the most common comment type, with ~70 responses (positive, negative, and in-between) on Clojure&rsquo;s language development process (out of 563 total comments). While many people had issues with the development process, there were also many people who were supportive of how Clojure is currently developed.</p>
<ul>
<li>Grateful for the careful stewardship of Clojure and ClojureScript by Rich Hickey and Cognitect.</li>
<li>Clojure has strong opinions on how software should be built. It needs to keep those strong opinions as it&rsquo;s these opinions that differentiate it and make it attractive. Keep up the great work!</li>
<li>Clojure is Amazing and you guys do a FANTASTIC job!!! Ignore the critics and keep doing things just like you have been. Thank you for this wonderful language!!</li>
<li>Closed core development and disappointment with spec have made made many friends leave Clojure/Script last year. Let&rsquo;s make 2019 better.</li>
<li>I love Clojure, and an extremely grateful to Rich, Stu, Alex, etc for their continuing stewardship and work of this fantastic gift. With respect to recent kerfuffles about community involvement, I simultaneously understand and respect Rich&rsquo;s position, and I am also concerned that some very respected Clojure developers who have contributed a lot (IMHO) feel disconnected and may be drifting away from the community.</li>
<li>About the governance of Clojure by Cognitect: thank you all! You&rsquo;re doing it right.</li>
<li>Managing expectations in 2018 is about 10 years too late. Please give a signal that the core team recognises that, and also how much the community is worth to Clojure as a language before dismissing any critics to the (previously very unclear) contribution/lifecycle process.</li>
<li>I love the principled stand taken by the clojure/core team about silly arguments erupting in the &ldquo;community&rdquo;. I really appreciate that the core is so well thought out and there is a valid resistance to adding &ldquo;stuff&rdquo; in there.</li>
<li>I appreciate Alex&rsquo;s insights into the Clojure development process, and what he&rsquo;s working on. I also appreciate the all of the core team&rsquo;s work that makes Clojure such a great language to use!</li>
<li>Thanks for recent improvements inline with community wishes. Still makes me sad we don&rsquo;t have a bigger core team utilizing the skills of (some) of the community that could do things like e.g. actively improve core.async.</li>
<li>Clojure is a wonderful language; however, we are becoming worried about the future prospects of the language because of the way that Cognitect handles community feedback about the direction of the language.</li>
<li>/2018 was the year that Rich finally explained how he felt about the open source community around Clojure. For many this was disappointing, but I&rsquo;m glad that he finally explained how he felt, because at least it is now in the open and people can make decisions with full information. Five years ago, Clojure could afford to lose key contributors because the language was growing and new people were coming along. Clojure is now at a very different place and position, and it&rsquo;s no longer growing at the same rate, or has the same mindshare. I&rsquo;ve invested many years, and lots of time into the Clojure community. Up until this year, I thought I would have a long career with Clojure, but I am starting to look around at other language communities for ones that are a better fit for my values.</li>
<li>Even though I agreed with the substance of Rich Hickey&rsquo;s &ldquo;Clarity&rdquo; gist, it is concerning to me that some of the more prolific library maintainers are leaving the community. I&rsquo;m sure that had it been me, I would have responded even less graciously. Still, there&rsquo;s an element of community management that goes beyond just being correct.</li>
<li>After using Clojure professionally for 7 years, I am hedging my bets by involving myself in the Rust community. While Rich&rsquo;s comments may be lauded by the greater online community, it has had a large impact on my personal consideration on the state of Clojure. &hellip; But, as a member of the community, my concern is that the user base of Clojure cannot grow larger without this concept of ownership changing. This conflict, at the end of the day, is a conflict between what my hopes for Clojure were and the interests of Cognitect &hellip; But it seems that Clojure has remained what Rich originally intended it to be. &hellip; The conflict is simply that, for some reason, I had assumed my interests were in line with Cognitect&rsquo;s. It has become clearer, year after year and especially this year, that this is not the case. It&rsquo;s very likely this misunderstanding is a mistake on my part. Looking back, I see no reason that I should have assumed this other than it is generally the trajectory of most languages focus on growth. For this reason, I will likely exit this community as many others have. I don&rsquo;t have any hard feelings or regret being part of it. I am very appreciative to all of the hard work that has gone into Clojure and regretful that I did not contribute nearly enough during my time writing it.</li>
</ul>
<h2 id="community">Community</h2>
<p>People seem to mostly enjoy the Clojure community, but others have had negative experiences, often citing an elitist attitude from some community members. Losing the history from Clojurians Slack came up several times. I&rsquo;m not sure if everyone is aware of the <a href="https://clojurians-log.clojureverse.org">Clojurians Slack Log</a>?</p>
<ul>
<li>&hellip; the community has been aggressive/hostile from our experience.</li>
<li>Love the community. Everyone has been really helpful. I wish it was more diverse and wrote more stuff down. A lot seems to get shared face to face which is great, but makes a really high barrier to entry.</li>
<li>I&rsquo;m a bit worried about the long-term viability [of Clojure]. I wouldn&rsquo;t be so worried about the language and ecosystem not being friendly to newcomers, it&rsquo;s clearly distilling many years of software practitioner&rsquo;s experience and thus is opinionated.</li>
<li>The only bad/ugly part of the Clojure ecosystem is the use of (unsearchable)Slack as the main knowledge base.</li>
<li>I really enjoy this community. Despite the occasional war of words, generally it seems to be filled with helpful, deep thinking people who are fun to interact with. If we were known for one thing only, I&rsquo;d like it to be that!</li>
<li>Thanks so much to the Cognitect team and everyone who helps to make the Clojure community better. I understand that people can be very vocal about the things they dislike and not so much when it comes to appreciate the things that work nicely. Being able to use Clojure professionally to build software that solves problems is really exciting and I&rsquo;m grateful for it.</li>
<li>I suggest moving off of slack to a more accessible chat system. Losing history is a bad thing. Check out discord or matrix or gitter or mattermark or any other number of tools made for this purpose.</li>
<li>I&rsquo;m concerned that there is too much of a disconnect between the core developers and the wider community. &hellip; I think it would be great if the core acknowledged some of the work of <a href="https://www.clojuriststogether.org">Clojurists Together</a>. I think the new <a href="https://clj-commons.org">clj-commons</a> organisation is a great idea and I&rsquo;d like to see it better promoted and supported.</li>
<li>The tone in the community has changed. I think this is very sad.</li>
<li>The community and the prominent people around it are OUTSTANDING. It is really something to behold. This was my first motivation. I am staying for the good language and tools and etc. but the people behind it are definitely the main treasure here.</li>
</ul>
<h2 id="libraries">Libraries</h2>
<p>People are still looking for a curated on-ramp into Clojure web development, a &lsquo;Rails for Clojure&rsquo;. There are a number of frameworks and templates here, but they don&rsquo;t seem to be hitting the spot. I&rsquo;m not sure whether that is because of limited mindshare/marketing, limited documentation, or the scope and quality of the frameworks. Having used Clojure for many years, I no longer find it difficult to find and assemble the pieces that I need for projects, but I definitely remember finding this being difficult when I started. Data Science and ML were places that people saw a niche for Clojure. Several people hoped for improvements on core.async, it still has a number of rough edges.</p>
<ul>
<li>I would love to see a way to get open source tools, such as Cider, sustainable support. I&rsquo;m worried about all you open source maintainers getting burned out and not creating these awesome tools. I don&rsquo;t know what this looks like yet. [Ed. I&rsquo;ve got just the <a href="https://www.clojuriststogether.org">program</a> for you]</li>
<li>I know that Clojure promotes a build-it-yourself type of mentality, which is nice, but it would be great if it had standard implementations for things like webapps (auth, security, etc.) that were leading the way for alternatives to follow. It&rsquo;s ok to be opinionated, if it works properly.</li>
<li>One huge opportunity that is still being missed is the field of data science &ndash; Clojure(+Clojurescript) has the potential to become the best platform for data research ever. In that field, more than others, it is important to be beginner-friendly.</li>
<li>Clojure needs a Rails-like &ldquo;killer app framework&rdquo; that provides novices a training-wheels included opinionated approach to building applications with Clojure. The roll your own / pick your poison approach to Clojure is a barrier to many.</li>
<li><code>core.async</code> could use some love with closing long-open bugs and documentation on best-practices and how to build bigger systems with it. Or maybe it just needs to be officially deprecated? As an outside observer, it feels like it&rsquo;s in limbo by the clojure-core team. Either way, we&rsquo;re currently using Zach Tellman&rsquo;s <code>manifold</code> abstractions a lot to great effect.</li>
<li>I much prefer the library over framework approach taken in the Clojure community, but I do miss the rapid development which RubyOnRails allows, i.e. conventions.</li>
<li>&hellip; I think a curated collection of recommended third party libraries would help a lot of teams.</li>
</ul>
<h2 id="other-compilation-targets">Other compilation targets</h2>
<p>People have been experimenting with the Graal compiler to produce static binaries without needing a JVM. At this point that seems like the strongest option for people wanting to use Clojure without the JVM. Better Android support was also requested.</p>
<ul>
<li>Clojure doesn&rsquo;t seem to have any plan for Android integration, this is pretty sad considering how much computing power is employed there, and how big of a showcase mobile development is :(</li>
<li>I think that the limitations of their respective host languages are holding Clojure and ClojureScript back.</li>
<li>Is there a Clojure project that compiles to WebAssembly?</li>
<li>So many people want a native Clojure. We need a native Clojure without JVM. Is there a plan about this?</li>
<li>The advent of GraalVM, and the resulting ability to build Clojure executables that startup up quickly has been a game changer. The slow startup time and need to use a JVM has been a real impediment to Clojure&rsquo;s adoption as a general purpose language. It would be even better if someone would pursue a Clojure native x86_64 compiler which would generate native executables, but that is probably not going to happen. Ensuring that Clojure can run well with GraalVM is probably the most we can hope for, and there is plenty of work to be done there.</li>
<li>Difficulties in running on Android may end up forcing me to port all the existing desktop applications off of Clojure to pure Java/Kotlin solutions.</li>
<li>Targeting two of the most popular VMs is great, but being able to get native performance is always a wish, like LLVM.</li>
</ul>
<h2 id="typing">Typing</h2>
<p>For the past few years people have been less and less <a href="https://danielcompton.net/2016/07/11/people-are-worried-about-types">worried about types</a>. I suspect this is mostly due to spec.</p>
<ul>
<li>Love Clojure. But at two Java shops over four years, the lack of static typing (the ability to command-click identifiers in IntelliJ and navigate to their source, the ability to refactor) has prevented me from winning over colleagues. TBH it&rsquo;s also reduced my own enthusiasm since the prospect of <em>me</em> working on our 1.6MM LoC project without static typing honestly scares me.</li>
<li>I&rsquo;ve selected &ldquo;no static typing&rdquo; but matching Haskell is not my intent. Lack of static guarantees is what bothers me. If it were possible to reject programs that are guaranteed to fail, that would be an improvement. For example: <code>(clojure.string/replace nil #&quot;a&quot; &quot;b&quot;)</code> or <code>(clojure.string/replace &quot;abc&quot; #&quot;a&quot;)</code>.</li>
</ul>
<h2 id="clojurescript">ClojureScript</h2>
<p>Shadow CLJS was mentioned by many people as having been a great part of their workflow. For those not using Shadow, externs remain challenging.</p>
<ul>
<li>shadow-cljs made me continue developing ClojureScript + started using it in backend services. It provides significantly better support for NPM libs than lein-cljsbuild that I&rsquo;ve been using before.</li>
<li>Without shadow-cljs we wouldn&rsquo;t have been able to use clojurescript because we found it impossible to get the npm packages we needed to work.</li>
<li>It&rsquo;s not at a terrible state right now, but I&rsquo;m at least slightly worried about more divergence between Clojure and ClojureScript in the future.</li>
<li>shadow-cljs does great job on compiling clojurescript and npm integration, but it more and more diverges from the standard compiler. I would love to see shadow-cljs merged into the mainstream clojurescript compiler. In general: I would like to have better, easier way to compile clojurescript without setting tons of flags.</li>
<li>Feel like cljs could make an amazing, even-better version of <a href="https://github.com/plotly/dash">dash</a> (maybe powered by Reagent/re-frame).</li>
<li>Although work has been done on externs, I find venturing into JavaScript interop fraught with peril. I would be very happy if interop would just work, same as Java interop. Most frustrating is that development builds work but releases don&rsquo;t. Catching these problems early would seriously mitigate the issue. For now I&rsquo;m using cljs-oops library, which works very well, but it feels kind of a hack. Overall I&rsquo;m very content with ClojureScript though!</li>
</ul>
<h2 id="setuptooling">Setup/tooling</h2>
<p>Clojure&rsquo;s tooling has continued to improve. This year lots of work has been done adding plugins or expanding functionality of the new official Clojure tools. clj on Windows was asked for by many people. Maintainer burnout seems like a significant risk to the Clojure tooling ecosystem.</p>
<ul>
<li>I&rsquo;m happy to see that many have realised we need to find ways to better support the development of CIDER, a crucial part of Clojure development infrastructure. Seems like the lead dev has been burning out recently, and many of us depend on his (and a few others&rsquo;) goodwill.</li>
<li>It has been a challenging first year in obtaining high productivity with the tools. Would be great to see a simple but capable tool set get some focus, e.g. Atom or VSCode.</li>
<li>I no longer want to work with CIDER or Cursive, rather, I&rsquo;d like to work with REBL + a REPL as my IDE. I believe we can have a renaissance of Clojure tooling if prepl becomes demystified and/or we add a tap-repl, something like <code>tap&gt;</code> to the Clojure repl. This would allow tooling to be added and removed dynamically.</li>
<li>Please port clj to Windows!</li>
<li>clj for windows please.</li>
<li>We need clj under Windows. Is it possible to release it?</li>
</ul>
<h2 id="compliments">Compliments</h2>
<p>As always, the vast number of comments were compliments to Clojure and the core team.</p>
<ul>
<li>Keep up the good work! 👍</li>
<li>Clojure is beautiful, functional and concise. It really rejuvenated my love for programming.</li>
<li>I absolutely love Clojure 💚</li>
<li>I really appreciate the well thought out design of Clojure. We feel that Clojure gives us distinct advantages while providing a language with minimum disruption.</li>
<li>5 years later and I still enjoy writing Clojure. Thanks to all those who make it extremely productive and fun to use!</li>
<li>I really appreciate all the work Cognitect and the community abroad put into making Clojure and the Clojure community a joy to work with. Keep up the good work!</li>
<li>It&rsquo;s my 11th year with Clojure. What a journey. Thanks, Rich and everybody.</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>Clojure is a great language, and people are very enthusiastic about it. Its adoption in business continues to grow. There are a number of areas for improvement still, especially if the Clojure community wants to grow further. Not all of this work needs to go through Core though, particularly in areas of documentation and guides, libraries, and tooling.</p>
<p>I worry about the Clojure community losing key contributors. There are a few linchpins holding a lot of things together; if we lose them, it will be hard to come back from. If you don&rsquo;t want to see this happen then please support the libraries and tools you rely on by contributing code, documentation, issue triage, or money.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>On Abstraction</title>
      <link>https://danielcompton.net/on-abstraction</link>
      <pubDate>Fri, 23 Nov 2018 21:24:37 +1300</pubDate>
      
      <guid>https://danielcompton.net/on-abstraction</guid>
      <description>Almost two years ago, there was a Github issue on reagent (a ClojureScript React wrapper), suggesting that Preact be added as a substitute for React. I wrote up a fairly long comment about why I didn&amp;rsquo;t think this was a great idea (at least not immediately). React&amp;rsquo;s recent announcement of the new hooks feature made me think about it again. I&amp;rsquo;ve republished it here with a few edits for context and time.</description>
      <content:encoded><![CDATA[<p>Almost two years ago, there was a Github issue on reagent (a ClojureScript React wrapper), suggesting that Preact <a href="https://github.com/reagent-project/reagent/issues/271">be added</a> as a substitute for React. I wrote up a <a href="https://github.com/reagent-project/reagent/issues/271#issuecomment-266257908">fairly long comment</a> about why I didn&rsquo;t think this was a great idea (at least not immediately). React&rsquo;s recent announcement of the new <a href="https://reactjs.org/docs/hooks-intro.html">hooks</a> feature made me think about it again. I&rsquo;ve republished it here with a few edits for context and time.</p>
<hr>
<h2 id="introduction">Introduction</h2>
<p>In principle, I&rsquo;m not opposed to the idea of Reagent using Preact. It has some cool features and I like that it is small (although in comparison to the total compiled size of a normal CLJS app it&rsquo;s probably a wash). If Preact worked 100% out of the box with Reagent with no code changes required then I would have no issues with someone swapping out the React dependency for a Preact one and calling it a day. If there are only a few minor tweaks to Reagent required to pass the tests, then again I don&rsquo;t really have any issues with that. I suspect that even if you have 100% of the tests passing, there will still be issues, as Reagent was built around React, and may not have tests that would cover the difference in behaviour between React and Preact.</p>
<h2 id="abstraction">Abstraction</h2>
<p>It looks like it may not be a pure lift and shift to support Preact. If that&rsquo;s the case then we run into a bigger issue: abstraction. Reagent was written and built around the ideas and in the context of React. There are assumptions (probably tens or hundreds) built around React&rsquo;s API and possibly implementation details too.</p>
<p>Adding abstraction adds a large cost because you can no longer program against a concrete API and implementation, you now have to consider two. There are three numbers in computer science, 0, 1, and many. We would be moving from 1 to many, and that takes work.</p>
<p>An aside: recently at work, we were looking at moving a legacy system from only supporting dates in the past to also be able to support dates in the future. This should be straightforward right? We talked to the programmers responsible for it and they couldn&rsquo;t guarantee that it would work, nor whether supporting future dates would be easy or hard. In the building of that (or any) system, hundreds of simplifying assumptions are made around the context that the system is going to be built in.</p>
<blockquote>
<p>It is a very common pattern to have different backends and I don&rsquo;t see any downsides to it.</p>
</blockquote>
<p>I can&rsquo;t think of a single example of a system with multiple backends that didn&rsquo;t have any downsides to it, e.g. ORMs, HTML/CSS/JS, Java. There may be some, but they would be the exceptions that prove the rule. <strong>Everything has a cost, the question is whether there is a benefit that outweighs the cost</strong>. It is much harder to remove something from software than to add it, which is why we should be certain that the benefits outweigh the costs.</p>
<blockquote>
<p>While Preact strives to be API-compatible with React, portions of the interface are intentionally not included. The most noteworthy of these is createClass() &hellip;
<a href="https://preactjs.com/guide/switching-to-preact#3-update-any-legacy-code">https://preactjs.com/guide/switching-to-preact#3-update-any-legacy-code</a></p>
</blockquote>
<p>Reagent currently uses createClass. There are workaround options provided, but this is an example of some of the API differences between React and Preact which you need extra compatibility layers to support. Do we know if the compatibility layer works 100% correctly?</p>
<h2 id="a-possible-future-if-preact-support-is-merged-now">A possible future if Preact support is merged now</h2>
<p>As a thought experiment, let&rsquo;s assume that Preact is in Reagent with some kind of compatibility shim. Preact already has several performance optimisations that people can take advantage of:</p>
<blockquote>
<p>customizable update batching, optional async rendering, DOM recycling and optimized event handling via Linked State. - (from <a href="https://preactjs.com">Preact homepage</a>)</p>
</blockquote>
<p>Wouldn&rsquo;t you want to be able to take advantage of those in your application? I certainly would. Now to do so, you may run into issues because the compatibility shim layer that was written was encoded around default assumptions of React, and they may not apply to Preact. Do we have to rework the shim layer, or lower level Reagent API stuff? Who is going to do that work? Who is going to review it and merge it?</p>
<p>Let&rsquo;s consider the reverse. Perhaps in some new React version, Facebook comes out with a new API which is faster or better suited to Reagent&rsquo;s style of rendering, so we want to switch to that [since writing this they came out with <a href="https://reactjs.org/docs/hooks-intro.html">Hooks</a>. These may be <a href="https://github.com/developit/preact/issues/1247">added</a> to Preact also, but this isn&rsquo;t certain and neither is the time-frame]. However that new model may not work with Preact. Again, we&rsquo;re in a bit of a pickle: Preact users want to be carried along with Reagent and get the benefits of new Reagent work, but it may not be easy or possible to support the new API for them. Now what?</p>
<p>Consider everyday development on Reagent. Reagent&rsquo;s source code is built around a very detailed understanding of React and is highly optimised. If Preact was supported too, then developers would probably need to gain an understanding of Preact too.</p>
<p>At the moment, Preact has one main contributor, it has been around for 1.5 years. React has many contributors. I&rsquo;d estimate there are 100+ people with very deep knowledge of React. It&rsquo;s been around (in public form) for 3.5 years. In general, the JavaScript community does not have a reputation for long-term support of projects. What happens if development slows/stops on Preact and the compatibility layer isn&rsquo;t kept up to date? It is much harder to remove something than it is to add it. Who decides when/if to remove Preact from Reagent at a future date?</p>
<p>These are all hypotheticals, but I hope this demonstrates that <strong>the extra abstraction provided by supporting two VDOM layers doesn&rsquo;t come for free</strong>. At the very least, it consumes extra brain cycles when testing and developing Reagent, extra support and documentation costs from users wanting to use one or the other, as well as extra indirection when running and debugging apps using Reagent.</p>
<h2 id="the-innovators-dilemma">The Innovators Dilemma</h2>
<p>If you haven&rsquo;t already, I highly recommend reading &ldquo;The Innovators Dilemma&rdquo; by Clayton Christensen. One of the key points he makes in that book is the difference between integrated and modular products and when to develop each kind.</p>
<blockquote>
<p>CHRISTENSEN: When the functionality of a product or service overshoots what customers can use, it changes the way companies have to compete. When the product isn’t yet good enough, the way you compete is by making better products. <strong>In order to make better products, the architecture of the product has to be interdependent and proprietary in character.</strong></p>
<p>In the early years of the mainframe computer, for example, you could not have existed as an independent contract manufacturer of mainframe computers, because the way they were made depended upon the art that was employed in the design. The way you designed them depended upon the art that you would employ in manufacturing. There were no rules of design for manufacturing.</p>
<p>Similarly, you could not have existed as an independent maker of logic circuitry or operating systems or core memory because the design of those subsystems was interdependent. <strong>The reason for the interdependence was that the product wasn’t good enough. In every product generation, the engineers were compelled by competition to fit the pieces of the system together in a more efficient way to wring the maximum performance possible out of the technology that was available at the time.</strong> This meant that you had to do everything in order to do anything. <strong>When the way you compete is to make better products, there is a big competitive advantage to being integrated.</strong>
&hellip;
In order to compete in that way, to be fast and flexible and responsive, the architecture of the product has to evolve toward modularity. Then, because the functionality is more than good enough, you can afford to have standard interfaces; you can trade off performance to get the advantages of speed and flexibility. These standard interfaces then enable independent providers of pieces of the system to thrive, and the industry comes to be dominated by a population of specialized firms rather than integrated companies.</p>
<ul>
<li><a href="http://www.strategy-business.com/article/14501?gko=ca7ad">Clayton M. Christensen, The Thought Leader Interview</a></li>
</ul>
</blockquote>
<p>I would argue that we are still very much at the point where the current VDOM libraries aren&rsquo;t good enough yet. They aren&rsquo;t yet ready to be commoditised, and the best option is to tightly integrate.</p>
<h2 id="options-from-here-with-some-conjecture">Options from here (with some conjecture)</h2>
<ol>
<li>
<p>Someone can make a PR to Reagent to add support for Preact. It will probably take a while to get merged because it is a significant change. Once it is merged and released, there will probably need to be several rounds of revisions before it is ready to go. Because Reagent moves relatively slowly, this will take a while.</p>
<p>Reagent also has a large number of production users, so new releases need to be well tested and stable. Adding Preact to the mix is going to slow this down further.</p>
</li>
<li>
<p>Someone can make a fork of Reagent (let&rsquo;s say it&rsquo;s called Preagent). You can run wild experimenting with what is the best way to use Preact in Preagent, take advantage of all of the great features Preact has, and have a much faster turnaround time for releasing and using it. You will be able to work out what is the right API and integration points for Preact because you have room to experiment with it, without the weight and responsibility of bringing the rest of the Reagent users along with you.</p>
<p>At some point in the future, you could review merging Preagent back into Reagent, given all that you now know. You would also have the weight of evidence on your side where you can demonstrate the benefits of Preact and can show how many users want Preact. This would let you make a much better case for including Preact, give you what you want in the meantime, and likely provide a higher quality integration in the future.</p>
<p>Alternatively, you may decide that Preagent is better served going its own way and integrating more closely with Preact. This is also a good option.</p>
</li>
</ol>
<h2 id="abstraction-is-not-free">Abstraction is not free</h2>
<p>The point I have been trying to drive through this post is that abstraction is not free. Over-abstraction is a common anti-pattern and it saps productivity. I had a friend who recently left a Clojure job and started a Java one. He quipped to me about how he&rsquo;d forgotten what it was like to trace code through five layers of abstraction to get to the concrete implementation. As programmers, we&rsquo;re trained to solve problems by adding layers of abstraction, but that isn&rsquo;t always the best way to solve the problem.</p>
<p>Lastly, this isn&rsquo;t a personal attack on you or your ideas. I&rsquo;m all for innovation in ClojureScript webapps and I think that it is worth investigating Preact and how it could work in the ClojureScript ecosystem 😄. I&rsquo;m not against Preact. I would consider using it if there was a measurable benefit. I&rsquo;m just suggesting that the best way to go about this is probably not to integrate it into Reagent as the first step.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Announcing The REPL podcast</title>
      <link>https://danielcompton.net/announcing-the-repl</link>
      <pubDate>Tue, 20 Nov 2018 09:56:03 +1300</pubDate>
      
      <guid>https://danielcompton.net/announcing-the-repl</guid>
      <description>I sent the first newsletter for The REPL two years ago, and I have really enjoyed writing it. I&amp;rsquo;ve learnt a lot from what people have written and created to share with the Clojure community. Sometimes when I&amp;rsquo;m writing the newsletter I’ve thought &amp;ldquo;That&amp;rsquo;s fascinating, I&amp;rsquo;d love to hear more about the technical details of that&amp;rdquo;. Now I have an outlet for doing just that.
I first had the idea of producing a Clojure podcast around January 2018.</description>
      <content:encoded><![CDATA[<p>I sent the first newsletter for <a href="https://therepl.net">The REPL</a> two years ago, and I have really enjoyed writing it. I&rsquo;ve learnt a lot from what people have written and created to share with the Clojure community. Sometimes when I&rsquo;m writing the newsletter I’ve thought &ldquo;That&rsquo;s fascinating, I&rsquo;d love to hear more about the technical details of that&rdquo;. Now I have an outlet for doing just that.</p>
<p>I first had the idea of producing a Clojure podcast around January 2018. I didn’t have the time for it then, but the idea kept swirling around the back of my brain. When Michael Drogalis&rsquo;s Pyrostore was acquired, I wanted to hear more about the acquisition, so I contacted Michael to see if he wanted to talk about it. That became the <a href="https://www.therepl.net/episodes/1/">first episode</a>.</p>
<p>My goal for The REPL is to talk with people about the technical details of the projects they are working on. The Clojure community has a ton of interesting people doing really creative work with Clojure. I&rsquo;ve really enjoyed talking with a bunch of people already, and I’m looking forward to talking to more of them in the future. You can find it <a href="https://www.therepl.net">therepl.net</a>. It&rsquo;s available on <a href="https://geo.itunes.apple.com/ca/podcast/feed/id1434612191?at=11lLuB">Apple Podcasts</a>, <a href="https://feeds.therepl.net/therepl">RSS</a> and all of the other common podcasting apps.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>State of Clojure Survey 2018 Analysis</title>
      <link>https://danielcompton.net/clojure-survey-2018</link>
      <pubDate>Wed, 28 Mar 2018 12:28:56 +1300</pubDate>
      
      <guid>https://danielcompton.net/clojure-survey-2018</guid>
      <description>Cognitect has recently released the results of their State of Clojure Survey for 2018. For the last two Clojure survey&amp;rsquo;s, I have reviewed the free-form answers at the end of the survey and tried to summarise the zeitgeist of community feeling. I enjoy it each time, and so here&amp;rsquo;s this years analysis.
Some comments have been lightly edited for spelling, clarity, and brevity.
Error messages Error messages have been one of the top complaints about Clojure since the surveys started, and this year they have gotten worse with the introduction of specs on core macros.</description>
      <content:encoded><![CDATA[<p>Cognitect has recently released the <a href="http://blog.cognitect.com/blog/2017/1/31/clojure-2018-results">results</a> of their State of Clojure Survey for 2018. For the <a href="https://danielcompton.net/2016/01/29/clojure-survey-2015">last</a> <a href="https://danielcompton.net/2017/02/08/clojure-survey-2016">two</a> Clojure survey&rsquo;s, I have reviewed the free-form answers at the end of the survey and tried to summarise the zeitgeist of community feeling. I enjoy it each time, and so here&rsquo;s this years analysis.</p>
<p>Some comments have been lightly edited for spelling, clarity, and brevity.</p>
<h2 id="error-messages">Error messages</h2>
<p>Error messages have been one of the top complaints about Clojure since the surveys started, and this year they have gotten worse with the introduction of specs on core macros. I&rsquo;m not the <a href="https://clojureverse.org/t/improving-error-messages-in-clojure-as-a-library/1765/21?u=danielcompton">only</a> <a href="https://www.reddit.com/r/Clojure/comments/7wy8l0/defn_podcast_31_bruce_hauman/du4wmr1/?context=1">one</a> who has noticed this either. In 2015 Colin Fleming gave a talk on <a href="https://www.youtube.com/watch?v=kt4haSH2xcs">improving Clojure&rsquo;s error messages with Grammars</a>. In previous surveys there was hope that spec would be able to use this approach to improve error messages; Ben Brinckerhoff has recently shown a <a href="https://gist.github.com/bhb/f637ef589ef3ac3d2ca5a883fafc2c12">proof-of-concept</a> that gives some similar (excellent) error messages in <a href="https://github.com/bhb/expound">Expound</a>.</p>
<ul>
<li>My primary wish would be for more helpful error messages (e.g a la Elm) in Clojure and Clojurescript.</li>
<li>I was excited about spec initially; however, I find the error messages so large, noisy and unhelpful that I don&rsquo;t want to use it. To put it another way: when there&rsquo;s a spec failure, my heart sinks; knowing that the next few minutes are probably going to be frustrating and painful.</li>
<li>Spec was supposed to help with error messages, but it just made them worse. Stuff like <code>(let [f/x 42] f/x)</code> now emit insane error messages. But it looks like the Clojure dev team has moved on to improving command line tools now? Can we please just get error messages fixed before a ton of people get frustrated and jump ship? The current state of errors in Clojure is an embarrassment to the community.</li>
<li>Error messages is a big show stopper. I am trying to get Clojurescript adopted for web and react-native development withing our organization for few years, but I always see the same pattern: people get some error during project setup/configuration and get stuck forever because they have no idea what the error means at all and how get it fixed. Please please improve error reporting. :)</li>
<li>A big problem for new starters, an issue that has been singled out time and time again over the years, is poor error messages that lead to difficult debugging of code structure. That Clojure 1.9 has actually made these error messages harder to understand is a disaster. [&hellip;] I hope I&rsquo;m wrong and that I&rsquo;ll understand the grand plan eventually.</li>
<li>Please please please please enhance the error messages. An incredible error reporting would make this language out of this world, and that would make the biggest difference.</li>
</ul>
<h2 id="spec">Spec</h2>
<p>Comments ranged from loving spec to disliking it. There were also requests for more guidance on how to apply spec to real-world use-cases and how to integrate it into whole programs.</p>
<ul>
<li>OMG Spec is amazing. It&rsquo;s dramatically changing the way I program. I&rsquo;ve been starting new projects out by writing specs before nearly any other code. The result is that I am able to extend my hammock time to the keyboard, and think through my domain model with composable, high level descriptions implemented as specs. The fact that these high level descriptions then become so useful in so many different ways &ndash; generative testing, value conformation for data api parsing, more useful error messages, etc &ndash; is a stunning thing to behold. I&rsquo;m excited to see how the fruits of these ideas permeate through our and other communities.</li>
<li>The presence of &ldquo;spec&rdquo; on some of those lists made me want to rate everything else &ldquo;important&rdquo; so I could show how unimportant it is. [&hellip;]</li>
<li>spec is awesome, but its dogmatism leaves us needing tools like spec-tools, which makes working with spec clunky.</li>
<li>There needs to be more guidance, development and reliance on spec from both Cognitect and community.</li>
</ul>
<h2 id="docs">Docs</h2>
<p>Documentation in all forms has been another perrenial complaint but this is starting to improve. <a href="https://clojure.org">clojure.org</a> continues to add more guides this year on <a href="https://clojure.org/guides/higher_order_functions">Programming at the REPL</a> and <a href="https://clojure.org/guides/higher_order_functions">Higher Order Functions</a> among other things. Martin Klepsch&rsquo;s <a href="https://github.com/martinklepsch/cljdoc">cljdoc</a> holds a lot of promise to improve the state of third-party documentation, by automatically generating and publishing docs for published JARs.</p>
<ul>
<li>We should take example of how Rust community/documenation is run: BIG focus on newcomers, features MUST be perfectly documented before being shipped. This serve advanced users as well. No offense, but Rich Hickey should understand what good documentation is, or delegate completely to people who do so that he can focus and making a even greater language (his strong point).</li>
<li>I feel the true weak points are confusing error messages, not enough friendly guides/tutorials for the early to beginner Clojurist, and a lack of solid CLJ/S example projects. These are key because it is difficult to know the right way without “blessed” examples.</li>
<li>Please provide a good set of tutorials on Javascript Interop such as how to translate a ES6 or higher JS file into ClojureScript.</li>
<li>The documentation is really awful - incomplete, vague, no examples, no semantic precision - not up to the standards of what one normally sees for programming language documentation.</li>
<li>Please improve the docstrings. They are the worst of any programming language I have ever used.</li>
<li>Really, the core documentation is not written for beginners or even intermediates</li>
<li>What I miss most is a book which teaches how to approach problems with Clojure. I mean primarily not &ldquo;best practices&rdquo; or &ldquo;design patterns&rdquo; or language independent algorithms. Nor a kind of language reference or few lines long mini examples, but complex, advanced examples with detailed explanations about the pros and cons of certain solutions applied/not applied.</li>
</ul>
<h2 id="startup-time">Startup time</h2>
<p>Startup time continues to be an issue for people. As serverless computing becomes more mainstream, this may end up pushing people from Clojure to ClojureScript, or elsewhere.</p>
<ul>
<li>Startup time is really really really really really long</li>
<li>Startup time never used to be an issue for me, as my services were long running and persistent. Lately however, I&rsquo;ve been using Docker for jobs. Startup time becomes an issue here. Continued improvements in total app startup time will pay dividends going forward.</li>
<li>Startup time regression. Clojure 1.9 startup time is 1/3 longer then Clojure 1.8 (1.6s vs 1.1s on my humble machine).</li>
</ul>
<h2 id="marketingadoptionstaffing">Marketing/adoption/staffing</h2>
<p>There were lots of comments this year in this category. Even after 10 years, Clojure still unknown or seen as being extremely niche to many people, especially among business stakeholders. Hiring seems to be less of an issue than in years past. There is still a large contingent of programmers looking to work with Clojure in remote positions, although it&rsquo;s hard to say whether this proportion is any higher than in other language communities.</p>
<ul>
<li>I recently hired a programmer with no Clojure experience. She was writing lovely idiomatic Clojure within a month. The biggest difficulty was overcoming her initial fear of parentheses.</li>
<li>To use Clojure(Script) more it would help if there was marketing for it. It&rsquo;s still largely unknown, and therefore hard to sell to other companies.</li>
<li>There is always an uphill battle in pushing Clojure as an enterprise solution, this seems to mostly occur to lack of marketing. Non-technical decision makers care about branding.</li>
<li>I&rsquo;ve found that some folks really dislike lisps passionately. One of our vendors indicated that his customers and employees were highly critical of the use of Clojure as an extension point.</li>
<li>Unfortunately, this year my organization in ceasing its use of Clojure for production projects after many years of using it. Staffing and on-boarding external resources are the 2 main reasons for doing so.</li>
<li>Hard to convince managers at work to use Clojure because of the perception that its a fringe language</li>
<li>I wish it was easier to find a remote (non US-only) remote Clojure/Clojurescript job for people with no major Clojure experience :)</li>
<li>It&rsquo;s very important to address the enterprise software community. We need formal tools, formal approaches, standard IDEs, SonarQube, Eclipse, Jenkins, e.t.c.</li>
<li>I believe &ldquo;JavaScript converts&rdquo; will be an important source of growth for Clojure moving forward.</li>
<li>We find Clojure a joy to use and hiring Clojure engineers or those excited and capable of learning Clojure has been a big advantage, contrary to common wisdom. Clojure positions tend to self select for strong candidates.</li>
</ul>
<h2 id="language">Language</h2>
<ul>
<li>Enterprise Java tends to lean heavily on reflection to pull components together (e.g., Spring, annotation-driven JUnit and JAX-RS). To incorporate Clojure into those environments, lots of component-specific wrappers are needed. It is easy to slip a little Java into a Clojure codebase, but this has made the reverse difficult.</li>
<li>I would love to see some more work on improving clojure.test. It works, but I wish there was less stateful macro magic and more flexibility with fixturing and test structure</li>
<li>I&rsquo;m increasingly finding that I&rsquo;m writing more cljc than clj or cljs but find it really frustrating that cljs seems to be a second citizen to clj. It would be much better if there was actually a core Clojure library/api that was actively supported by both, with clear variances between them.</li>
<li>I would love to see some work towards using JVM MethodHandle&rsquo;s to obviate the need for the compiler&rsquo;s direct linking. Seems we could have our var cake, and eat it too.</li>
<li>We have a relatively large codebase and 20+ build targets (fat jars/advance compilation js files). we&rsquo;d like better AOT support and ability to incrementally compile this code base as most changes only affect a few targets. right now AOT compile is pretty black box and not very amenable to building tooling.</li>
</ul>
<h2 id="language-development-process">Language Development Process</h2>
<p>This hasn&rsquo;t changed in a long time, and I don&rsquo;t see it changing in the future, but it has been persistently highlighted by many people as a big issue.</p>
<ul>
<li>For long term success of Clojure/ClojureScript, it&rsquo;s important for the Clojure core team &amp; project to be more open and welcoming like other open source projects. The view from outside of the Cognitect bubble is that the language and community aren&rsquo;t healthy at all, and I fear for it&rsquo;s long run viability.</li>
<li>The core team seems to be extra cautious and move really slowly on the language and core libraries. And the roadmap for releasing new versions is really opaque to the community.</li>
<li>Cognitect has continued to be good technical stewards of Clojure, but poor stewards of the relationship between the core team and the rest of the community. Many (most?) senior Clojure programmers want nothing to do with contributing to Clojure or any projects owned by Core (like the site) because the process is designed to frustrate and prevent meaningful contributions.</li>
<li>Cognitect need to climb a few rungs down the ivory tower and engage with the community as if it were in fact made up of human beings trying to do their jobs.</li>
<li>I don&rsquo;t know what direction the core team is taking Clojure, and the top issues (startup time, poor error messages, lack of involvement with the community and numerous improvements to Java interop in JIRA being ignored) have not changed significantly over the past 5 years. I never felt welcomed to contribute, and seeing how Skummet and other large efforts from the community were largely ignored was not encouraging.</li>
<li>More attention to JIRA issues/patches/contributions would be great. [&hellip;] I painstakingly write a patch and jump through the JIRA hoops; but there it languishes. The dev team&rsquo;s complete silence is not encouraging. Makes me feel more of an outsider, less of a part of the community.</li>
</ul>
<h2 id="community">Community</h2>
<p>By and large, people found the community welcoming, and personally I have found it to be one of the best things about working with Clojure. However there is a persistent undercurrent of eliteness from some Clojure programmers which really puts people off the language.</p>
<ul>
<li>I find Clojure a great language, but I haven&rsquo;t noticed any increase in market (or mind) share. Quite the opposite, it seems to be going nowhere, possibly dying a slow death I hope I&rsquo;m wrong, but, for now anyway, I&rsquo;ve given up on it.</li>
<li>Thanks, Alex et al! I&rsquo;m still extremely happy with Clojure, and appreciate the community. I worry a bit about the possibility of clj/s losing user share and dwindling, which I didn&rsquo;t worry about a year ago. I hope like hell that that won&rsquo;t happen, and try to do at least a bit toward preventing it.</li>
<li>That defn podcast is bloody marvelous</li>
<li>Being in the Clojure community since around 1.2, I loved the language then, and I like the direction, it&rsquo;s been taking since. The community is great, very friendly and even its most controversial figures are usually polite, intelligent people. Heck, even the local troll from the mailing list is occasionally helpful, stays on point in his threads and sticks with the conversation, even after blowing stuff up.</li>
<li><a href="https://clojure.org">clojure.org</a> changes so infrequently (like once a year, if that?) that I&rsquo;m concerned the language is not being enthusiastically supported and will soon fade away. It makes me nervous to invest time and money in a language that seems to have no vitality.</li>
<li>Clojure conferences lack diversity in both attendees, speakers, and programs. I hope the merging of Conj and West will improve that this year.</li>
<li>People who give to the Clojure community are role models. I&rsquo;m serious about this. I&rsquo;ve woken up and thought &ldquo;what would Bruce Hauman do&rdquo; more than once. I talk with my daughters about the Clojure community.</li>
<li>Cognitect is doing an awesome job, making programming fun again! Alex Miller is very helpful.</li>
<li>Effort community makes to promote diversity, particularly in terms of women is good, although there is a long way to go.</li>
<li>I am doing Clojure for some time now and what does not bring me joy is the fact that the message to other communities (other languages) is clear: &ldquo;we are better and smarter&rdquo;. [&hellip;] I think we can <em>do</em> better without thinking that we are.</li>
<li>I didn&rsquo;t want to tick the unpleasant communities cause it is not [&hellip;] lately [however], [&hellip;] I started noticing a kind of &ldquo;elitism&rdquo; especially from people that are frequent speakers or started working early with the language.</li>
<li>I have multiple colleagues, all great developers, all former Clojure developers. Whenever Clojure comes up they never fail to mention how alienating the &ldquo;smarter than you&rdquo; attitude sometimes present in the community can be.</li>
<li>I&rsquo;m worried about the perceived shrinking of the Clojure community</li>
<li>I&rsquo;ve gotten to know a few more female developers using Clojure in the past year, and have learned that some parts of the community are scaring/driving women away. This includes unpleasant interactions on Slack and working to avoid certain people at Conj.</li>
<li>Not to put too much stock in the oversimplified Gartner hype curve model, it does seem like Clojure is passing through what they call the trough of disillusionment.</li>
<li>Please consider supporting <a href="https://clojuriststogether.org">Clojurists Together</a>, even launching initiatives for the community to help through it.</li>
</ul>
<h2 id="libraries">Libraries</h2>
<p>More guidance on how to compose and select libraries remains a common common issue for people in this section, as well as improving the state of library documentation.</p>
<ul>
<li>The plethora of web app (both client &amp; server side) frameworks is both bad and good. Too many to choose from (no standard like rails) and also lots of options. Also, limited security options, especially w.r.t. use of session state, async handlers &amp; server-less designs.</li>
<li>I frequently find myself frustrated by looking for a library that will help me do &ldquo;X&rdquo;. There are many choices out there, each of which does some subset of what one might want in that arena, but a different subset.</li>
<li>It is sad that I often find interesting Clojure or ClojureScript libraries that are abandoned and haven&rsquo;t been updated for a long time</li>
<li>Need more quality open source projects for machine learning and data visualization libraries. Great to see the advances from conj but for a language that has a front end tool built in, there is no excuse for someone not to build a great visualization library for data science.</li>
<li>No de-facto web framework, Pedestal is in dire need of documentation, Schema is deprecated and Spec isn&rsquo;t ready, New CLI tools in Clojure 9 competing with Leiningen/Boot. All of these complaints have something in common: it looks like the Clojure core team is actively hostile towards the larger community. All community-built tools/libraries are open to attack and replacement by the core team and there&rsquo;s always fear of a major destabilizing revolution everyday.</li>
<li>Several widely used library started to stall&hellip; sustainability might become a concern&hellip; [Ed: hopefully <a href="https://clojuriststogether.org">Clojurists Together</a> can help here]</li>
</ul>
<h2 id="other-targets">Other targets</h2>
<p>As in previous years, there are a smattering of people asking for alternative platforms to target other than JS and the JVM. LLVM, Go, and Web Assembly all had interest from people.</p>
<ul>
<li>Is it posible to use Clojure with the Go ecosystem? That would be amazing</li>
<li>It is hard to watch Go get so much mind-share. Clojure on the JVM is great, but it would sure be nice if I could build a Clojure application that didn&rsquo;t need the JVM.</li>
<li>I still long for a low-level oriented Clojure dialect to be able to produce small clj executables with low overhead and systems programming capacity, but one can dream!</li>
<li>webassembly support? and native support? (like a <a href="http://www.scala-native.org/en/latest/">scala-native</a>)</li>
</ul>
<h2 id="typing">Typing</h2>
<p>Requests for static typing were down from previous years. I attribute that mostly to spec gaining wider adoption and understanding.</p>
<ul>
<li>Clojure needs to make a better case for why static typing is not necessary for maintainable, large, multi-contributor codebases and how the REPL dev process helps with that.</li>
<li>I still love Clojure as a whole more than any other. I&rsquo;d love to address long-term maintenance. The difficulty of stepping back into a codebase after some time can be more challenging than with Haskell or PureScript. I wish the compiler could do more for me. Spec is <em>huge</em> though, really enjoying it. It still takes a good amount of discipline to use well, but I&rsquo;m thankful for it.</li>
<li>I used Clojure for one work project because a coworker recommended it. Overall it was a good experience, but the lack of a type system made maintaining that particular project too difficult. Tools like Plumatic Schema and Typed Clojure helped in some ways but didn&rsquo;t end up pulling their weight. Regardless, the Clojure service continues to run today and it&rsquo;s better than the Ruby service it replaced.</li>
</ul>
<h2 id="clojurescript">ClojureScript</h2>
<p>ClojureScript continues to improve, although getting the tooling setup remains a pain point, as does integrating NPM modules. There are recent improvements on that front though, so this may not be such an issue in 12 months time. I have heard lots of good things about shadow-cljs, it seems to be a strong tool to investigate for ClojureScript usage, especially if you work with a lot of NPM modules.</p>
<ul>
<li>ClojureScript has had a serious push this year&hellip; ;)</li>
<li>For CLJS, we really need to get npm deps working. Right now it&rsquo;s hard to get right, or at least there&rsquo;s no up-to-date tutorials available..?</li>
<li>I find I spend more time than I should configuring my development environment so it works well. This is particularly bad in React Native, but cljs/figwheel can still be frustratingly complex to get right.</li>
<li>Lack of async/await support in CLJS is holding it back. The JS community has settled on promises and async/await as the primary asynchronous patterns, and although core.async is useful for certain things, shoehorning existing JS code into it is very kludgy.</li>
<li>Nothing has made a bigger improvement to my ClojureScript workflow in the past couple of years than shadow-cljs.
<ul>
<li>Intelligent externs inference, plus simple <code>^js</code> or <code>^clj</code> tagging for anything that’s missed</li>
<li>Virtually trouble free usage of other JavaScript modules /npm</li>
<li>Way faster cljs compile flow due to smart caching of intermediate artifacts</li>
<li>Self-hosted dependencies handled very well</li>
</ul>
</li>
<li>NPM support in ClojureScript seems to be a little bit tricky and not working all the time for all the libs. But has been improved a lot in the past.</li>
<li>Probably my biggest frustration has been trying to use libraries from JS in a full-on ClojureScript front-end app.</li>
</ul>
<h2 id="setuptooling">Setup/tooling</h2>
<p>Tooling on the Clojure side seems to be somewhat less of an issue this year, but setting up ClojureScript projects with all the things that you need remains an issue for many people.</p>
<ul>
<li>Clojure is now mature and stable enough to start focusing in tooling. Many JVM tools are not Clojure specific and for people coming to Clojure from non-jvm languages diagnosing problems is a barrier (more with systems in production). From GC issues, to debugging exceptions, to attaching to a process in runtime to peek at some memory or patch something. It was pretty easy to do with <code>gdb</code> in linux, it should be much more easily done with Clojure.</li>
<li>Fast track to CLJS web dev for junior devs, in one piece in one place. There is not that much essential knowledge/tooling needed to get started that it can’t fit in a CreateReactApp-like solution. Too much content, too many sources, don’t help. No need to be exhaustive.</li>
<li>Git-based deps seem like a bad idea. clj build tool is otherwise cool, if a bit unnecessary given the prevalence and quality of leiningen, along with the stability afforded through maven central/clojars.</li>
<li>I think we should pay more attention to interactive programming. Like what <a href="http://worrydream.com">Bret Victor</a> proposes, beyond the REPL.</li>
<li>Making changes to libraries then having to jar them just to test is hard (checkouts never worked for me (or others) with cljs). I hope Alex Miller&rsquo;s recent work will fix that.</li>
<li>Once Figwheel and Reagent and tests were set up, my experience as a developer was very positive - barring some bad times with advanced Closure optimization bugs. Really happy with ClojureScript myself, but it would be hard to convince a friend to start using it, because there is no clear or standard way to develop.</li>
</ul>
<h2 id="compliments">Compliments</h2>
<p>As always, the survey was dominated by positive comments. Here were some of my favourites.</p>
<ul>
<li>Clojure has ruined every other language for me. Every time I have to do something in another language, I always wish it was in clojure. It’s just so easy to get things done in clojure. I love the language and hope to use it forever.</li>
<li>Clojure&rsquo;s still the language I find myself turning to most frequently when given a choice. It just feels natural, the toolkit simple and yet powerful enough to express pretty much anything at a whim.</li>
<li>I&rsquo;ve been using Clojure professionally for at least 4 years and these have been the most productive years of my career. I&rsquo;m looking forward to using spec more fully. I&rsquo;m looking forward to seeing what improvements come to the language in the next few years and have no desire to leave. Thanks so much for this language, community, and way of working.</li>
<li>This. Is. The. Best. Language. Ever. High-level programming done right. Thank you Rich.</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>When I went to write this years summary, I re-read the previous posts to remind myself of where we were a few years ago. While some areas have improved, I was struck by how many of the comments could have been lifted from previous years survey results. There was a worrying trend in the community and adoption sections that people perceive Clojure to be shrinking. Perception doesn&rsquo;t always match reality, and it may be (as a commenter noted) that Clojure is entering the trough of disillusionment phase of the <a href="https://www.gartner.com/technology/research/methodologies/hype-cycle.jsp">Gartner Hype Cycle</a>. However I think there are a lot of low-hanging fruit around that could significantly improve the experience and ecosystem around Clojure without changes to the core language.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>How to serve ClojureScript files in development</title>
      <link>https://danielcompton.net/how-to-serve-clojurescript</link>
      <pubDate>Wed, 21 Mar 2018 22:20:01 +1300</pubDate>
      
      <guid>https://danielcompton.net/how-to-serve-clojurescript</guid>
      <description>When I develop ClojureScript projects, I almost always use Figwheel. It’s a great tool, but sometimes in development I would end up with stale files. This led to some very confusing debugging sessions. It only happened some of the time, and was always fixed after a hard refresh. I thought about just disabling the browser cache, but I didn&amp;rsquo;t like ignoring the issue. After seeing colleagues struggle with stale caching, I decided to figure out what was going on, and fix it once and for all.</description>
      <content:encoded><![CDATA[<p>When I develop ClojureScript projects, I almost always use <a href="https://figwheel.org">Figwheel</a>. It’s a great tool, but sometimes in development I would end up with stale files. This led to some very confusing debugging sessions. It only happened some of the time, and was always fixed after a hard refresh. I thought about just disabling the browser cache, but I didn&rsquo;t like ignoring the issue. After seeing colleagues struggle with stale caching, I decided to figure out what was going on, and fix it once and for all.</p>
<h2 id="cache-control-rules-everything-around-me">Cache-Control rules everything around me</h2>
<p>The first thing to do was to <a href="https://github.com/bhauman/lein-figwheel/pull/586">add</a> a <code>Cache-Control: no-cache</code> header to all static file responses. Despite the name, <code>no-cache</code> tells the browser it can cache files, but must always validate them with the server before using them. If the browser&rsquo;s cached version is up-to-date, a compliant HTTP server should return a <a href="https://httpstatuses.com/304">304 Not Modified</a> response, otherwise it serves the new file.</p>
<p>If you don’t provide a caching header to an HTTP response, the browser can choose its own caching behaviour. The browser&rsquo;s caching heuristics are much more aggressive than you want in development, and lead to the weird caching behaviour I was seeing.</p>
<p>I thought this had fixed the issue, but occasionally I would still notice stale files were being used. After looking closely at the compiled output files, I made a surprising discovery.</p>
<h2 id="clojurescript-copies-file-modification-times">ClojureScript copies file modification times</h2>
<p>ClojureScript (as of March 2018) copies the last-modified date of ClojureScript source files to the compiled JavaScript target files. This is so that the Clojure compiler can detect changes to source files. JavaScript from the Closure compiler (e.g. <code>goog.base</code>), gets a modification time that matches the time it was compiled.</p>
<p>Using a <code>Last-Modified</code> date header for caching is often useful, but was causing two problems here:</p>
<ul>
<li>Closure compiled JavaScript doesn&rsquo;t change from run to run, so caching based on the last modified date will cause it to be unnecessarily re-downloaded.</li>
<li>JavaScript compiled from ClojureScript that uses macros from other Clojure files will receive the modification date of the consuming ClojureScript file, <strong>even if the macro files have changed more recently and triggered a recompilation</strong>. This was leading to the second round of (very confusing) caching issues that I saw.</li>
</ul>
<p>To avoid these issues, I recommend removing the <code>Last-Modified</code> header from the response when in development.</p>
<h2 id="etags">ETags</h2>
<p>To knock both problems on the head once and for all (hopefully), I <a href="https://github.com/bhauman/lein-figwheel/pull/667">added</a> a <a href="https://en.wikipedia.org/wiki/Cyclic_redundancy_check">CRC32 checksum</a> based <a href="https://en.wikipedia.org/wiki/HTTP_ETag">ETag</a> to Figwheel for static file responses. I packaged this up in a library <a href="https://github.com/deps-app/ring-etag-middleware">ring-etag-middleware</a> so that other projects could also use it.</p>
<h2 id="serve-304-not-modified-responses">Serve 304 Not Modified responses</h2>
<p>At this point the browser will check with the server for every ClojureScript file, on every pageload. However, this causes all of the files to be downloaded each time, even if they haven&rsquo;t changed. The last step is to add <a href="https://github.com/ring-clojure/ring/">ring&rsquo;s</a> <code>ring.middleware.not-modified/wrap-not-modified</code> middleware. This will return a &ldquo;304 Not Modified&rdquo; response if the ETag provided in the <code>If-None-Match</code> request header matches the <code>ETag</code> header in the response.</p>
<h2 id="summary">Summary</h2>
<p>As best as I can tell, this has completely solved all of the odd caching issues that I was seeing, while still keeping the app snappy to load by reusing as much of the cache as possible. If you are serving ClojureScript files in development and not using Figwheel, I recommend you follow these three steps:</p>
<ol>
<li>Set a <code>Cache-Control: no-cache</code> header</li>
<li>Add an ETag to your static file responses</li>
<li>Remove the <code>Last-Modified</code> header</li>
<li>Wrap your responses in <code>ring.middleware.not-modified/wrap-not-modified</code> or the equivalent in your Clojure web framework.</li>
</ol>
]]></content:encoded>
    </item>
    
    <item>
      <title>The case for and against Clojure predicates returning nil</title>
      <link>https://danielcompton.net/clojure-nil-predicates</link>
      <pubDate>Fri, 31 Mar 2017 12:26:41 +1300</pubDate>
      
      <guid>https://danielcompton.net/clojure-nil-predicates</guid>
      <description>Last week, there was a mailing list post on the clojure-dev mailing list noting that several of the new predicates in Clojure 1.9 alphas return true or nil. The three new predicates are: qualified-keyword?, qualified-ident?, and qualified-symbol?. Previously, all predicate functions in Clojure core, i.e. functions that end in a ? have returned true/false. In this post I want to examine the pros and cons of this new behaviour.
If I&amp;rsquo;ve missed anything here, please get in contact and I&amp;rsquo;ll update the post.</description>
      <content:encoded><![CDATA[<p>Last week, there was a <a href="https://groups.google.com/forum/#!topic/clojure-dev/JlJxy2-w3_Q">mailing list post</a> on the <a href="https://groups.google.com/forum/#!forum/clojure-dev">clojure-dev mailing list</a> noting that several of the new predicates in Clojure 1.9 alphas return true or nil. The three new predicates are: <code>qualified-keyword?</code>, <code>qualified-ident?</code>, and <code>qualified-symbol?</code>. Previously, all predicate functions in Clojure core, i.e. functions that end in a <code>?</code> have returned true/false. In this post I want to examine the pros and cons of this new behaviour.</p>
<p>If I&rsquo;ve missed anything here, please get in <a href="http://www.danielcompton.net/about">contact</a> and I&rsquo;ll update the post.</p>
<h2 id="pros-to-some-predicates-returning-nil">Pros to some predicates returning <code>nil</code></h2>
<ul>
<li>The main argument for some predicates returning nil is that the predicate still returns a falsy value. Idiomatic Clojure code usually doesn&rsquo;t need to distinguish between <code>nil</code> and <code>false</code>.</li>
<li>The docstrings for <code>qualified-keyword?</code> for example says: &ldquo;Return true if x is a keyword with a namespace&rdquo;. It doesn&rsquo;t say anything about what happens if it doesn&rsquo;t have a namespace, so returning <code>nil</code> or <code>false</code> are both technically valid interpretations.</li>
<li>Not coercing the output from <code>qualified-keyword?</code> into a boolean is faster. On my computer <code>qualified-keyword?</code> takes roughly 3.5 ns to run, and a <a href="https://gist.github.com/favila/589b3369b984cad1c37c063b96d79424#file-main-cljs-L7">version</a> that returns a boolean value takes around 6.5 ns. In absolute terms they are both pretty small though.</li>
</ul>
<p>The first two points aren&rsquo;t strong arguments for returning nil, rather they argue that it doesn&rsquo;t matter whether the functions return nil or false.</p>
<h2 id="cons-to-some-predicates-returning-nil">Cons to some predicates returning nil:</h2>
<ul>
<li>
<p>The biggest downside to this change is that it breaks a core convention that Clojure and the community has held around predicates, namely that any function ending in <code>?</code> returns <code>true</code> or <code>false</code>. This is my biggest concern about the changes. You can find this expectation in:</p>
<ul>
<li><a href="https://pragprog.com/book/shcloj2/programming-clojure">Programming Clojure</a>: &ldquo;A predicate is a function that returns either true or false. In Clojure, it is idiomatic to name predicates with a trailing question mark, for example <code>true?</code>, <code>false?</code>, <code>nil?</code>, and <code>zero?</code>.&rdquo; - Programming Clojure, 2nd Ed., Page 27.</li>
<li>Clojure&rsquo;s own <a href="http://dev.clojure.org/display/community/Library+Coding+Standards">library coding standards</a>: &ldquo;Use &lsquo;?&rsquo; suffix for predicates. N.B. - predicates return booleans&rdquo;. That page also has the disclaimer: &ldquo;Rules are made to be broken. Know the standards, but do not treat them as absolutes.&rdquo;</li>
<li>The community <a href="https://github.com/bbatsov/clojure-style-guide#pred-with-question-mark">Clojure Style Guide</a>: &ldquo;The names of predicate methods (methods that return a boolean value) should end in a question mark (e.g., <code>even?</code>).&rdquo;</li>
<li>All of the Clojure standard library functions that end in a <code>?</code> return a boolean value. Anyone learning Clojure would be justified in assuming that all functions that end in <code>?</code> return a boolean value if that&rsquo;s the convention they have always seen.</li>
<li>A <a href="https://groups.google.com/forum/#!topic/clojure/IdSGKwTYqPU">mailing list thread</a> on predicates in the aforementioned Programming Clojure book.</li>
<li>A <a href="https://groups.google.com/forum/#!topic/clojure/y8ySWiLXGQc">mailing list thread</a> about this exact question, whether all Clojure functions that end in <code>?</code> should return a boolean value.</li>
<li><a href="https://www.tutorialspoint.com/clojure/clojure_predicates.htm">Tutorials Point</a>: &ldquo;Predicates are functions that evaluate a condition and provide a value of either true or false.&rdquo;</li>
<li><a href="http://stackoverflow.com/questions/10732187/whats-the-usual-naming-rule-in-clojure">StackOverflow</a> on naming rules: &ldquo;The main function naming conventions seem to be &hellip; Use <code>?</code> to indicate a predicate that returns true or false: <code>sequential?</code>&rdquo;</li>
</ul>
</li>
<li>
<p>The second biggest problem is that <strong><code>qualified-keyword?</code> can return three values</strong>. &ldquo;How is that?&rdquo; you might be asking, &ldquo;Didn&rsquo;t you just say that the functions return <code>true</code> or <code>nil</code>?&rdquo;. I thought so too. However as I was looking at the implementation of these functions, I realised that <code>qualified-keyword?</code> can return false as well, if not given a keyword. For example:</p>
<pre><code>  user=&gt; (qualified-keyword? ::abc)
  true
  user=&gt; (qualified-keyword? :abc)
  nil
  user=&gt; (qualified-keyword? 'abc)
  false
</code></pre>
<p>It is <a href="http://blog.jayfields.com/2011/08/clojure-partition-by-split-with-group.html">fairly common</a> to use <code>group-by</code> or <code>juxt</code> with a predicate function to partition a collection into two groups. If you use any of the new qualified* functions, you will end up with three groups. Based on Alex Miller&rsquo;s <a href="https://twitter.com/puredanger/status/845080310039695361">tweet</a>, it seems like this was considered and accepted.</p>
</li>
<li>
<p>If these predicates are used at the boundaries of systems or in interop with Java, then it would be easy to forget that the qualified* predicates may return nil, and end up passing null into a Java method as a parameter when you meant to pass false. You could also return false under certain input when you expected the function to only return true or nil, or return nil when you were expecting the result to be a boolean. These kinds of bugs can be very subtle, especially with Clojure&rsquo;s falsy handling.</p>
</li>
<li>
<p>ClojureScript code is a <a href="https://gist.github.com/favila/589b3369b984cad1c37c063b96d79424">lot smaller and enables more optimisations</a> when it can guarantee that a boolean value is returned.</p>
</li>
<li>
<p>Clojure gets similar benefits from the JVM when it can mark the function as returning a Boolean.</p>
</li>
<li>
<p>Historically, Clojure has made a distinction between functions that return truthy and those that return true. There are predicate functions in core that return a truthy value like <code>some</code> and <code>every-pred</code>, but they don&rsquo;t end in a <code>?</code>. This change starts to dissolve that distinction.</p>
</li>
</ul>
<h2 id="summary">Summary</h2>
<p>Personally, I don&rsquo;t see a strong reason to keep the current behaviour of the new qualified predicate functions, but you might see things differently. Whatever the outcome, I&rsquo;m glad that in Clojure we don&rsquo;t have to name all of our boolean functions <a href="http://softwareengineering.stackexchange.com/a/5576/">with an &ldquo;Eh&rdquo; suffix</a>.</p>
<h2 id="update">Update</h2>
<p>Alex Miller <a href="https://www.reddit.com/r/Clojure/comments/62i9fz/the_case_for_and_against_clojure_predicates/dfnjwdw/">suggested</a> to file a ticket about this behaviour, so I opened <a href="http://dev.clojure.org/jira/browse/CLJ-2141">CLJ-2141</a>. After some discussion, a <a href="https://github.com/clojure/clojure/commit/e9e57e4808b7700ccee2ea32e17051ba1063112e">patch</a> was made to coerce the output of these new functions to a boolean.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>State of Clojure Survey 2016 Analysis</title>
      <link>https://danielcompton.net/clojure-survey-2016</link>
      <pubDate>Wed, 08 Feb 2017 23:15:38 +1300</pubDate>
      
      <guid>https://danielcompton.net/clojure-survey-2016</guid>
      <description>The State of Clojure 2016 survey results have just been published. Last year I wrote an summary of the free text comment portion of the State of Clojure 2015 Survey. I enjoyed writing it, and it was my second most popular post of the year, so I&amp;rsquo;m repeating the process again.
In his summary, Justin said that 62% of the responses were positive. That number sounded low to me (but was presumably calculated by SurveyMonkey).</description>
      <content:encoded><![CDATA[<p>The <a href="http://blog.cognitect.com/blog/2017/1/31/state-of-clojure-2016-results">State of Clojure 2016</a> survey results have just been published. Last year I wrote an <a href="https://danielcompton.net/2016/01/29/clojure-survey-2015">summary of the free text comment portion</a> of the State of Clojure 2015 Survey. I enjoyed writing it, and it was my second most popular post of the year, so I&rsquo;m repeating the process again.</p>
<p>In his summary, Justin said that 62% of the responses were positive. That number sounded low to me (but was presumably calculated by SurveyMonkey). I would have estimated closer to 80% after <a href="https://www.surveymonkey.com/results/SM-7K6NXJY3/">reading through them all</a>. A little under one quarter of the 2420 survey respondents left a comment.</p>
<p>I&rsquo;m reusing most of the same categories from last year so interested readers can compare with <a href="https://danielcompton.net/2016/01/29/clojure-survey-2015">last years post</a>. Some comments have been lightly edited for spelling, clarity, brevity, and niceness.</p>
<h1 id="error-messages">Error messages</h1>
<p>Error messages were the biggest pain point for people last year. This year there were still many complaints about error messages and stack traces, but a lot of people are waiting to see what spec brings. There was a lot of discussion about spec error messages several months ago, but it seems to have gone quiet. I&rsquo;m really hopeful that spec will improve error messages.</p>
<p>This year Figwheel has started providing very sophisticated reporting of compile errors, and configuration problems. It has made a massive difference to my ClojureScript workflow. Thanks Bruce!</p>
<blockquote>
<p>Please Please Please can we get better error messages. &hellip;</p>
</blockquote>
<blockquote>
<p>ClojureScript has come a long way, but I still encounter errors that are totally perplexing. Better debugging would help enormously.</p>
</blockquote>
<blockquote>
<p>Error messages are very frustrating and it is hard to find where the error occurred and why. Errors coming from underlying Java code are only somehow relevant to the Clojure that produced them. Programming with dynamically typed language rocks when inferred types align with your idea, but when it&rsquo;s not, things get fuzzy.</p>
</blockquote>
<blockquote>
<p>Please, please, please, please, improve error messages. This would single handedly improve: new user onboarding, community feedback (let&rsquo;s admit it - it is a small community), rapid iterations, usage of the REPL, usage of spec and testing, and other areas. &hellip;</p>
</blockquote>
<blockquote>
<p>I consistently see error messages being the biggest barrier for learners of Clojure, and even more so for ClojureScript</p>
</blockquote>
<blockquote>
<p>I think a concerted focus on improving Clojure&rsquo;s error reporting &amp; handling would benefit both newcomers to the language and experienced developers alike and would result in considerably less wasted time &amp; effort.</p>
</blockquote>
<h1 id="docs">Docs</h1>
<p>Last year <a href="https://clojure.org/">clojure.org</a> had just been revamped and open sourced. I wrote at the time:</p>
<blockquote>
<p>I have high hopes that it will become a central source for high quality, official documentation and ease the pain for newcomers.</p>
</blockquote>
<p>clojure.org has had some contributions from the community, but it still doesn&rsquo;t have the breadth of material needed to be a central source. I would love to see something like Python&rsquo;s web documentation for Clojure. Renzo Borgatti is writing a mammoth book <a href="https://www.manning.com/books/clojure-standard-library">&ldquo;The Clojure Standard Library&rdquo;</a> which will cover the entire Clojure standard library.</p>
<blockquote>
<p>&hellip; Please improve the documentation. Recently I heard someone describe Clojure documentation as &ldquo;comically terse&rdquo;.</p>
</blockquote>
<blockquote>
<p>A simple way to get someone up and running that is a standard for the community would be great. There is nothing more frustrating than telling new people to &ldquo;Google&rdquo; for a solution and pick one you like&hellip; They never get further than reading the docs.</p>
</blockquote>
<blockquote>
<p>Clojure appeared to be a nice language when I started with it and I do not regret this decision. The flip side is that I had hoped that the poor documentation would have gone away by now &ndash; 1.4 was the first version I used and it does not seem to have improved. That&rsquo;s a shame. Documentation helps new users and really, hinders nobody.</p>
</blockquote>
<blockquote>
<p>Clojure docs are too terse. They assume that the reader already fully understands the concepts being described, and merely needs a refresher. &hellip;</p>
</blockquote>
<blockquote>
<p>Clojure&rsquo;s community is surprisingly small given it&rsquo;s output. This leaves documentation and tutorials sparse because they require time and effort that is in short supply. &hellip;</p>
</blockquote>
<blockquote>
<p>I think both clojure.org and clojurescript.org could use a better &ldquo;Get Started&rdquo; experience. It&rsquo;s our best opportunity at a first impression but we rely too heavily on third party docs. For example, on cljs.org the reference section starts with compiler options. Doesn&rsquo;t really capture the imagination.</p>
</blockquote>
<h1 id="setuptooling">Setup/tooling</h1>
<p>Again, Figwheel has been leading the way in improving tooling on the ClojureScript side. Tooling is still a pain point, but seems to be less so than in previous years. For Clojure editors, Cider, Cursive, and vim-fireplace are all used pretty much the same amount as last year, but Atom has entered fourth place, presumably coupled with <a href="https://atom.io/packages/proto-repl">proto-repl</a>.</p>
<blockquote>
<p>One thing we&rsquo;re used to from C#/Java that would be awesome to have is a better unit testing framework with IDE integration. &hellip;</p>
</blockquote>
<blockquote>
<p>The build toolchain for cljs has been a  pain. All of my learning has come from cloning public repos and seeing how they do it.</p>
</blockquote>
<blockquote>
<p>A huge thanks to the community for invaluable tools like Leiningen, Parinfer and the various IDE plugins like ProtoREPL or Cursive. And of course huge thanks to the core team for excellent stewardship of Clojure itself.</p>
</blockquote>
<blockquote>
<p>While tooling for Clojure is improving there needs to be a lot more resources devoted to it. I am currently in a Java shop and the only realistic option is Cursive.</p>
</blockquote>
<h1 id="startup-time">Startup time</h1>
<p>Startup time was another persistent complaints this year. Unfortunately there wasn&rsquo;t always enough information about whether startup time was a problem in development or production. There are several good options for avoiding constantly restarting Clojure REPLs in development (<a href="https://juxt.pro/blog/posts/live-programming-websites.html">and in production</a>), but perhaps for newcomers these are too complicated to setup, or they don&rsquo;t know about them?</p>
<blockquote>
<p>Love Clojure &hellip; hate its startup time!</p>
</blockquote>
<blockquote>
<p>Love the language and will keep at it. Primary frustration is with the start up time and tooling. In particular, I&rsquo;m finding it difficult to quickly test the backend and frontend of my application with Boot.</p>
</blockquote>
<blockquote>
<p>&hellip; We love functional programming, but hate Clojure&rsquo;s long startup times. We do what we can to minimize this (using test-refresh, REPLs, etc.), but it is still very painful, and we find ourselves twiddling our thumbs waiting for a restart several times a day. Similarly, our Clojurescript compiles take ~60 seconds (:simple optimizations) or ~30 seconds (:none optimizations). This slows us down substantially. Coming from Python, where compile and startup times are sub-second, this is the biggest complaint from our team.</p>
</blockquote>
<blockquote>
<p>Clojure would be perfect with faster startup time and a little less memory usage. Seriously I don&rsquo;t even mind the java stack traces.</p>
</blockquote>
<blockquote>
<p>REPL startup time is all I care about. I use emacs+cider, and it takes an age. Otherwise, I am completely happy with Clojure :)</p>
</blockquote>
<h1 id="marketingadoption">Marketing/Adoption</h1>
<p>Justin specifically mentioned marketing and adoption as a common theme amongst the feedback:</p>
<blockquote>
<p>One relatively stronger theme this year was the need for better marketing for the purposes of expanding or introducing Clojure within organizations, which is a great area for contribution from the entire community.</p>
</blockquote>
<p>In my opinion, one of the areas where Clojure could improve on marketing is on the main <a href="http://clojure.org">Clojure</a> and <a href="https://clojurescript.org">ClojureScript</a> websites. I think <a href="https://www.scala-lang.org">Scala</a> in particular has done a really good job of this. <a href="http://elm-lang.org">Elm</a> and <a href="https://www.rust-lang.org/en-US/">Rust</a> also do really well in presenting the main reasons why you would want to use their languages. The community isn&rsquo;t able to help with this, as contributions to style and templates are <a href="https://github.com/clojure/clojure-site/blob/master/content/community/contributing_site.adoc#style">not currently wanted</a>.</p>
<p>Last year I mentioned Cognitect&rsquo;s <a href="http://cognitect.com/resources#case-studies">case studies</a> on Clojure adoption, this year Juxt has done some great work with their case studies of companies using <a href="https://juxt.pro/clojure-in.html">Clojure in Europe</a>.</p>
<p>Anecdotally, I&rsquo;ve seen fewer people coming along to the <a href="https://www.meetup.com/Auckland-Clojure/">Auckland Clojure Meetup</a> than in previous years, although we&rsquo;re working on a fairly small sample size. I&rsquo;m not sure what (if anything) to make of that.</p>
<blockquote>
<p>I would do 100% of my development in Clojure if the enterprise-y company I worked for allowed it. &ldquo;Reason for not using Clojure as much as you would like&rdquo;? Management not on board.</p>
</blockquote>
<blockquote>
<p>I&rsquo;d love to see more &ldquo;serious&rdquo; support for ClojureScript: when I present ClojureScript to colleagues, it looks like a thing supported by several enthusiasts rather than a platform supported by a company.</p>
</blockquote>
<blockquote>
<p>Clojure is very solid. As a frontend developer, a stable build system, DCE and syntax stability are very valuable for me. I failed to convince my CTO on Clojure and instead we stuck to ES6/ES7. The main concern of management was hiring and training people. Although the learning curve for Clojure is easy, people still have a perception that LISP syntax is esoteric and difficult to pick up for someone completely new to the ecosystem. This myth has to be busted on a larger scale.</p>
</blockquote>
<blockquote>
<p>Language is great, community is great, the &ldquo;marketing&rdquo; is not that great. You guys have a great language and you are struggling to sell it.</p>
</blockquote>
<blockquote>
<p>[I] would love to see better marketing from Cognitect and other Clojure centric shops. Selling Clojure to a Java shop is not easy. It can and should be easier. (and simple, but I&rsquo;ll take &ldquo;easier&rdquo; here first)</p>
</blockquote>
<blockquote>
<p>As an average developer fluent in Java, I would love to use Clojure more, but the biggest hurdle for me is the lack of peers interested in Clojure. At the local meetup people report the same situation at their organisations. Pity, because Clojure is super cool! Thank you.</p>
</blockquote>
<blockquote>
<p>Love Clojure, really. Can&rsquo;t convince my peers that it&rsquo;s worth investing the time to learn it though.</p>
</blockquote>
<blockquote>
<p>The Clojure community needs a &ldquo;Rails killer,&rdquo; and only Arachne holds serious promise for that.</p>
</blockquote>
<blockquote>
<p>Clojure/ClojureScript ecosystem could benefit from stronger stewardship from Cognitect to propel it into the mainstream with a focus on a killer app or a industry domain similar to the way Light Bend has been focusing on enterprise and reactive system to promote the Scala ecosystem. &hellip;</p>
</blockquote>
<blockquote>
<p>I&rsquo;m in Shanghai and we barely have full-time Clojure developers in China. We formed online groups, but I guess we need help to push it to the next level.</p>
</blockquote>
<p>And the age old developer question:</p>
<blockquote>
<p>How can we get management to understand what they don&rsquo;t understand?</p>
</blockquote>
<h1 id="language-development">Language Development</h1>
<p>Like last year, there are still concerns about the contribution process, and the opaque decision making process for Clojure&rsquo;s development.</p>
<blockquote>
<p>Engagement of community is still sub-optimal, there are talented individuals who could be engaged more and productively so without opening it up to the peanut gallery.</p>
</blockquote>
<blockquote>
<p>I wish that the core Clojure development process was more flexible and friendly. I (and all the Clojure developers I know) have pretty much given up on trying to make suggestions or tickets about Clojure because I usually wind up banging my head against the wall and getting frustrated. The core team are under no obligations to explain themselves or their motivations, but they would save a lot of frustration from new community members wishing to contribute if there was a prominent document outlining the philosophy, and what kinds of changes and suggestions are and aren&rsquo;t welcome.</p>
</blockquote>
<blockquote>
<p>A more open approach to development and contributing to Clojure would be appreciated. I&rsquo;d love to contribute to Clojure but the mess of a lot of the code in Clojure and the JIRA-based contribution model is a barrier. I know that&rsquo;s what Rich likes and see the rest of Cognitect are happy contributing in this way but I&rsquo;d love to see something more open and approachable.</p>
</blockquote>
<blockquote>
<p>The slow rate at which JIRA issues are addressed remains a frustration, and provides a disincentive for contributing. Features that Cognitect cares about get rushed into the language half-baked, while well-thought out patches from years ago languish.</p>
</blockquote>
<blockquote>
<p>A little concerned over how &lsquo;arbitrary&rsquo; some design decisions seem to be and how inflexible the core team is. Running instrumented post-condition specs is such an obvious idea for example but it has been deemed not necessary &ldquo;from on high&rdquo;.</p>
</blockquote>
<blockquote>
<p>The issue tracker is well tended during the earlier workflow stages. There seems to be a bottleneck later on. I hope 2017 will bring the project&rsquo;s founders to modes of community contribution that are more efficient of the art and tradecraft of the many.</p>
</blockquote>
<h1 id="community">Community</h1>
<p>I would say that Clojure&rsquo;s community is one of it&rsquo;s greatest assets. There were mostly positive comments for the community, though still some concerns. The <a href="http://clojurians.net">Clojurians Slack</a> has been a great resource for a lot of newcomers, and spawned many channels for libraries and topics. IRC is still around, but seems to be less popular, and doesn&rsquo;t have the breadth of topics that Clojurians does.</p>
<blockquote>
<p>Alex Miller is doing a great job addressing the community.</p>
</blockquote>
<blockquote>
<p>CLJS has come a long way!! to the point we can use it for production development! this community is great! Justin_Smith stands out as <em>ridiculously</em> helpful on IRC &hellip; if the world (this community) had more folks like him, it&rsquo;ll elevate all of our games!</p>
</blockquote>
<blockquote>
<p>The thing that makes me wary of continuing to invest in Clojure professionally is how few paid opportunities there are for women and people of color. I don&rsquo;t know what the exact problem is - they are left of networks, don&rsquo;t have an opportunity to build their skills, or just straight-up sexism and racism - but it is definitely a problem. The current state of things means I will likely not be able to be on teams with women or people of color, and that is a big turn-off for me.</p>
</blockquote>
<blockquote>
<p>Clojure has the best community after PostgreSQL, in my opinion. I came for the language but I stayed for the community.</p>
</blockquote>
<blockquote>
<p>Be more inviting to new-comers.. so they stop learning Ruby.</p>
</blockquote>
<h1 id="libraries">Libraries</h1>
<p>A &ldquo;Rails for Clojure&rdquo; was a common request so people can start delivering value quickly. <a href="http://arachne-framework.org">Arachne</a> was commonly raised as one possibility to provide this.</p>
<blockquote>
<p>Clojure/ClojureScript it&rsquo;s very cool, but not very practical nor efficient in many typical business case scenarios. I&rsquo;m missing a full stack framework like Grails or Ruby on Rails or Django: there&rsquo;s nothing like that for the Clojure world: it&rsquo;s not about a project template but about the quick prototyping (with the customer by your side) these frameworks allow.</p>
</blockquote>
<blockquote>
<p>&hellip; There is also no good Clojure Web Development story: Pedestal looks interesting, but not actively developed and unsupported, Arachne is years away from being complete and useful, Luminus/Duct are initial scaffold project generators. It&rsquo;s hard to delivering some value quickly - user have to dig through all underlying libs and how they work together.</p>
</blockquote>
<blockquote>
<p>&hellip; Clojure web development needs a &ldquo;Rails&rdquo; to overcome the chicken-and-egg problem of getting enough developers to be able to hire for it. &hellip;</p>
</blockquote>
<blockquote>
<p>I hope to write a lot more Clojure. No, I hope to do a lot more with less Clojure. And looking forward to using Arachne.</p>
</blockquote>
<h1 id="other-targets">Other targets</h1>
<p>Many people are looking to run Clojure on alternative platforms or reduce host dependence. LLVM was a common request. Some are looking to move away from the JVM, while others are looking to move into environments that Java and JavaScript aren&rsquo;t suited for. This is an interesting request, though one of Clojure&rsquo;s original goals (and still on the Clojure homepage) is to be a hosted language. I&rsquo;m not sure whether it&rsquo;s possible for these two desires to ever meet? Graal and Truffle are also interesting possibilities.</p>
<blockquote>
<p>The biggest thing I&rsquo;ve noticed for beginners on forums / blog comments is they are afraid of the JVM. &hellip;</p>
</blockquote>
<blockquote>
<p>I&rsquo;ll never rewrite all my Scala into Clojure unless some sort of Cognitect Clojure OFFICIAL LLVM effort is made. Scala Native is [beating] Clojure.</p>
</blockquote>
<blockquote>
<p>Clojure&rsquo;s hosted nature is its biggest downfall, in my opinion. As a systems programmer looking to lisp + immutability for saner concurrency, the cost of Clojure&rsquo;s startup time and memory usage is very high. &hellip;</p>
</blockquote>
<blockquote>
<p>The one thing that I think would drive Clojure to a new level of adoption across the industry would be for someone to do an actual LLVM implementation of Clojure. Not a &ldquo;close variant&rdquo; of Clojure, but real Clojure. This would probably yield some performance boost beyond Java, but more importantly it would open up Clojure to environments that are simply not amenable to Java (or Javascript) for whatever reason. Some people have moved in this direction, but either have not completed the work, or have implemented their own &ldquo;variants&rdquo; of Clojure. What I wish someone would do is implement something with LLVM that is at least as close to Clojure as Clojurescript is.</p>
</blockquote>
<blockquote>
<p>I really think an opportunity is being missed by dismissing the c++ ecosystem, and I think that something that should be given somewhat serious consideration to by somebody would be to leverage LLVM with JIT and get a clojurescript running in that setting. There are significant legacy environments to be liberated there.</p>
</blockquote>
<blockquote>
<p>I would love for there to be some sort of compile-to-bundle with Clojure such that you have a single artifact that doesn&rsquo;t require an external JVM installation. Like Go programs. An embedded JVM (perhaps).</p>
</blockquote>
<h1 id="typing">Typing</h1>
<p>As we&rsquo;ve all learned this year, <a href="https://danielcompton.net/2016/07/11/people-are-worried-about-types">people are worried about types</a>. Spec is the biggest movement in this direction, and the number of type related comments has dropped a lot since last year.</p>
<blockquote>
<p>I know that Spec should help a lot with the error messages once we move to 1.9, although people coming from a non-Java background still have a lot of learning to do.</p>
</blockquote>
<blockquote>
<p>It is just sad that people who love Clojure (Colin Fleming, Steve Yegge, Adam Bard), have to use Kotlin sometimes instead (better startup times, static typing and Java interop like fast multidimensional arrays)</p>
</blockquote>
<blockquote>
<p>I hope Spec will find its way into tooling, especially Cursive.</p>
</blockquote>
<blockquote>
<p>Looking forward to learn and use spec</p>
</blockquote>
<blockquote>
<p>I&rsquo;d most like to see improvements to the Clojure compiler. Error messages, performance, better Java interop and simple static type checking seem most important.</p>
</blockquote>
<h1 id="compliments">Compliments</h1>
<p>As I mentioned at the start, the overwhelming majority of comments had positive things to say about Clojure. Alex Miller also deserves a special mention for his work with the community, and maintaining the Clojure infrastructure.</p>
<blockquote>
<p>I sincerely thank Clojure(Script) community to make LISP revolution back to live stage and making us realize the importance of focusing on core things which matter</p>
</blockquote>
<blockquote>
<p>I have been programming since 1979. Clojure is a work of art.</p>
</blockquote>
<blockquote>
<p>The community has been unbelievably great and I hope it stays true to its roots! Keep up the good work and I can&rsquo;t wait to see where Clojure/Script goes next!</p>
</blockquote>
<blockquote>
<p>The community is amazing, with a special shoutout to Alex Miller for being such a great part of it.</p>
</blockquote>
<blockquote>
<p>Happy Clojure user for over 4 years. Still loving every minute :-).</p>
</blockquote>
<p>Finally, I found a comment that I think sums up the general feeling of the community (and my own):</p>
<blockquote>
<p>No one and nothing is perfect, but I (for one) am very appreciative of the work that has been done and is on-going around Clojure/ClojureScript and the community in general. People tend to &lsquo;harp&rsquo; on the things that aren&rsquo;t just right (in their opinion) and forget about all the things that are amazing. I just want to say thanks, and keep up the superb work! :-)</p>
</blockquote>
<p>I think the future of Clojure is bright.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>A guide to the Datomic licensing changes</title>
      <link>https://danielcompton.net/guide-to-datomic-licensing-changes</link>
      <pubDate>Tue, 29 Nov 2016 10:20:49 +1300</pubDate>
      
      <guid>https://danielcompton.net/guide-to-datomic-licensing-changes</guid>
      <description>Shockwaves rang out through the Clojuresphere today with the news that Datomic is changing their licensing to drop the per-process limits. This is big news if you were limited in the number of processes you wanted to run.
The major changes in a nutshell:
 There are now no limits on process count Datomic Starter is now limited to one year of updates, then you need to pay $5,000 for Datomic Pro, or stay on the current version when your license expires.</description>
      <content:encoded><![CDATA[<p>Shockwaves rang out through the Clojuresphere today with the news that Datomic is <a href="http://blog.datomic.com/2016/11/datomic-update-client-api-unlimited.html">changing their licensing</a> to drop the per-process limits. This is big news if you were limited in the number of processes you wanted to run.</p>
<p>The major changes in a nutshell:</p>
<ul>
<li>There are now no limits on process count</li>
<li>Datomic Starter is now limited to one year of updates, then you need to pay $5,000 for Datomic Pro, or stay on the current version when your license expires.</li>
<li>Datomic Starter can now run the Memcached cache.</li>
<li>All Datomic Pro licenses are now $5,000, and annual maintenance is also $5,000/year.</li>
</ul>
<p>If I&rsquo;ve got any of the following wrong, please <a href="https://danielcompton.net/about">get in touch</a> via email and I&rsquo;ll update my post.</p>
<h2 id="the-old-pricing-model">The old pricing model</h2>
<p>Datomic launched in March 2012 with a paid option and in July 2012 added Datomic Free. In November 2013, Cognitect <a href="http://blog.datomic.com/2013/11/datomic-pro-starter-edition.html">launched</a> Datomic Pro Starter Edition. The old pricing page is on <a href="https://archive.org">archive.org</a> <a href="https://web.archive.org/web/20160414204211/http://www.datomic.com/pricing.html">here</a>. This model was easy to understand, as it mapped well to existing database licensing patterns of &lsquo;perpetually free with limitations&rsquo; or &lsquo;paid without limitations on a per node basis&rsquo;.</p>
<h3 id="datomic-free">Datomic Free</h3>
<ul>
<li>Free (as the name indicates)</li>
<li>Limited to storing data in memory on the transactor, or on the transactor&rsquo;s disk.</li>
<li>Freely redistributable (i.e. in on-premise or open source software)</li>
<li>Only able to run two peers (clients) and a single transactor. If the single transactor fails, then you won&rsquo;t be able to write to the database until another one starts.</li>
<li>Community support</li>
</ul>
<h3 id="datomic-pro-starter-edition">Datomic Pro Starter Edition</h3>
<ul>
<li>Free</li>
<li>Support for all storage backends (SQL, DynamoDB, Cassandra, Riak, Couchbase, Infinispan)</li>
<li>Limited to 2 peers and a single transactor</li>
<li>Not redistributable</li>
<li>Community support</li>
<li>Limited to 1 year of maintenance and software updates, though you were <a href="https://groups.google.com/d/msg/datomic/1qIxb8GYJrk/83aXJfbd1sIJ">able to renew</a> your Datomic Pro Starter Edition license each year for free (more on this later).</li>
<li>When your updates expire, you can continue using that version of Datomic, but you won&rsquo;t be able to use any future versions.</li>
</ul>
<h3 id="datomic-pro">Datomic Pro</h3>
<ul>
<li>Paid</li>
<li>Support for all storage backends</li>
<li>Able to run a second transactor in HA standby to take over if the first one fails or for rolling updates.</li>
<li>Ability to use Memcache to cache segments rather than all peers needing to talk directly to the storage backend.</li>
<li>Support is included while maintenance is current.</li>
<li>Pricing scaled linearly from $3,000 for five processes (this includes peers and transactors) up to 30 processes for $16,000. You could upgrade later to higher tiers for the price difference between the old license and the new license.</li>
<li>Annual maintenance for support and updates was half of the upfront license price</li>
<li>If an organisation had special needs (more processes, custom EULA, 24x7 support, redistributing Datomic e.t.c.) then you could talk to Cognitect to negotiate terms.</li>
</ul>
<h2 id="the-new-model">The new model</h2>
<p>All versions of Datomic apart from Free now support unlimited peers, high availability, Memcached support, and all storages (more on storage later). This is a <strong>significant</strong> change, as you can now use Datomic in an almost unlimited fashion for free. There is also a new Client API which is suitable for smaller, short-lived processes, like microservices and serverless computing. The changes are smart, as it frees users up from having to architect their systems around their Datomic license limitations. The new pricing model rearranges the tiers. There is now Datomic Free (unchanged), Datomic Starter, Datomic Pro, and Datomic Enterprise.</p>
<h3 id="datomic-starter">Datomic Starter</h3>
<ul>
<li>Similar intent to the previous Datomic Pro Starter</li>
<li>Free</li>
<li>Maintenance and updates limited to 1 year. However, <a href="https://news.ycombinator.com/item?id=13057114">based on discussion on Hacker News</a>, it seems that you can no longer renew your Datomic Starter license. <strong>This means that you will need to pay for Datomic Pro to get updates after one year</strong>. You can still use whichever version was available when your updates expire. Discussion in the #datomic Slack channel on <a href="http://clojurians.net">clojurians</a> matches up with this too.</li>
<li><strong>Update:</strong> Alex Miller said that you can sign up for multiple Datomic Starter licenses for different systems you&rsquo;re running.</li>
</ul>
<h3 id="datomic-pro-1">Datomic Pro</h3>
<ul>
<li>Similar intent to the previous Datomic Pro</li>
<li>$5,000/year per system including maintenance and updates. For organisations using 16 processes or less, then maintenance will be more expensive (previously $1,500 - $4,500 depending on process count).</li>
<li>2 Day Business-Hours-Only Support. The former Datomic Pro didn&rsquo;t have a published SLA for support, but I suspect that this is just formalising what was previously there.</li>
</ul>
<h3 id="datomic-enterprise">Datomic Enterprise</h3>
<ul>
<li>Enterprise integration support (professional services)</li>
<li>Negotiated license terms</li>
<li>24x7 Support</li>
<li>While this is a new tier in the pricing grid, these options were available as a &ldquo;Contact Us&rdquo; note on the former Datomic Pro.</li>
</ul>
<h3 id="other-changes">Other changes</h3>
<p>Datomic has a snazzy new <a href="http://docs.datomic.com/index.html">documentation site</a>. It also looks like as part of the licensing changes, Riak, Couchbase, and Infinispan are now considered <a href="http://docs.datomic.com/legacy-storage.html">legacy storage</a> and are only available to be used under an enterprise license. Standard editions of Datomic only support SQL, DynamodDB, and Cassandra. This change hasn&rsquo;t been mentioned on the <a href="https://groups.google.com/forum/#!forum/datomic">Datomic mailing list</a> or <a href="http://docs.datomic.com/release-notices.html">release notes</a>, but probably will be soon.</p>
<p>Datomic has <a href="http://docs.datomic.com/rest.html">deprecated</a> the REST API in favour of the new <a href="http://docs.datomic.com/clients-and-peers.html">Client API</a>.</p>
<p>There is also a new customer feedback portal where you can suggest features. You can access this after logging in to <a href="https://my.datomic.com">my.datomic.com</a>.</p>
<h2 id="summary">Summary</h2>
<p>If you are a Datomic Pro user then your maintenance is probably going to be higher, although in absolute terms it&rsquo;s still not a lot compared to developer salaries. If you were on Datomic Pro Starter and want to stay current, then you are now looking at moving Datomic Free, or paying $5,000/year for Datomic Pro. If you were using Riak, Couchbase, or Infinispan then it seems like you&rsquo;ll need to get Datomic Enterprise.</p>
<p>Datomic from the beginning has always felt like a database that understood the Cloud, and the zeitgeist of computing. It supported AWS DynamoDB and CloudFormation from early on, and their architecture has always felt well suited to cloud systems. The license changes to accommodate the trend towards microservices and serverless computing are a continuation of that.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Why are people worried about types?</title>
      <link>https://danielcompton.net/people-are-worried-about-types</link>
      <pubDate>Mon, 11 Jul 2016 09:17:14 +1300</pubDate>
      
      <guid>https://danielcompton.net/people-are-worried-about-types</guid>
      <description>Every week in The REPL I have a section called: &amp;ldquo;People are worried about Types&amp;rdquo;. This is based on a section that Matt Levine (my favourite columnist) includes in his daily column &amp;ldquo;People are worried about bond market liquidity&amp;rdquo;, and the related &amp;ldquo;People are worried about unicorns&amp;rdquo;, and &amp;ldquo;People are worried about stock buybacks&amp;rdquo;.
The title is a joke (as is his), I don&amp;rsquo;t really think there are people worried about types, but it is interesting to see a small but steady flow of type or type related (schema, spec, e.</description>
      <content:encoded><![CDATA[<p>Every week in <a href="http://therepl.net">The REPL</a> I have a section called: &ldquo;People are worried about Types&rdquo;. This is based on a section that <a href="https://twitter.com/matt_levine">Matt Levine</a> (my favourite columnist) includes in his <a href="http://www.bloomberg.com/view/contributors/ARbTQlRLRjE/matthew-s-levine">daily column</a> &ldquo;People are worried about bond market liquidity&rdquo;, and the related &ldquo;People are worried about unicorns&rdquo;, and &ldquo;People are worried about stock buybacks&rdquo;.</p>
<p>The title is a joke (as is his), I don&rsquo;t really think there are people worried about types, but it is interesting to see a small but steady flow of type or type related (schema, spec, e.t.c.) articles relating to Clojure each week.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Announcing The REPL - A weekly Clojure newsletter</title>
      <link>https://danielcompton.net/the-repl</link>
      <pubDate>Wed, 22 Jun 2016 08:33:34 +1300</pubDate>
      
      <guid>https://danielcompton.net/the-repl</guid>
      <description>I&amp;rsquo;ve started a weekly newsletter about Clojure and ClojureScript. Each week will have a curated selection of links (both recent, and older) and a sentence or two about why I think they&amp;rsquo;re worth reading. You can sign up at therepl.net.</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve started a weekly newsletter about Clojure and ClojureScript. Each week will have a curated selection of links (both recent, and older) and a sentence or two about why I think they&rsquo;re worth reading. You can sign up at <a href="http://therepl.net">therepl.net</a>.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Requiring records in Clojure and ClojureScript</title>
      <link>https://danielcompton.net/requiring-records-clojure-clojurescript</link>
      <pubDate>Wed, 04 May 2016 11:34:48 +1300</pubDate>
      
      <guid>https://danielcompton.net/requiring-records-clojure-clojurescript</guid>
      <description>One of the datatypes Clojure gives you is the Record. It is used in both Clojure and ClojureScript, but due to implementation differences, the syntax to use records from one namespace in another is different.
Clojure Clojure generates a Java class for every defrecord that you create. You need to :import them, just like you would a standard Java class. Lets say we have a small music store app that sells vinyl:</description>
      <content:encoded><![CDATA[<p>One of the datatypes Clojure gives you is the <a href="http://clojure.org/reference/datatypes">Record</a>. It is used in both Clojure and ClojureScript, but due to implementation differences, the syntax to use records from one namespace in another is different.</p>
<h3 id="clojure">Clojure</h3>
<p>Clojure generates a Java class for every <code>defrecord</code> that you create. You need to <code>:import</code> them, just like you would a standard Java class. Lets say we have a small music store app that sells vinyl:</p>
<pre><code>(ns myapp.cool-music)

(defrecord Vinyl [speed])

;;; meanwhile ...

(ns myapp.music-store
  (:import [myapp.cool_music Vinyl]))

(instance? Vinyl v)
  
;; or

(ns myapp.music-store
  (:import [myapp.cool_music.Vinyl]))

(instance? myapp.cool_music.Vinyl v)
</code></pre>
<p>There&rsquo;s a few things to note here:</p>
<ol>
<li>
<p>Because Clojure is generating Java classes, they follow the naming conventions of Java classes, where dashes get converted to underscores.</p>
</li>
<li>
<p>You should probably prefer the first example where the record is aliased, over the second one where the record is fully qualified.</p>
</li>
<li>
<p>Clojure dynamically generates the class for the record when that namespace is required (ignoring AOT compiling). If your code never requires the namespace that the record lives in, then it won&rsquo;t be created. This will cause <code>ClassNotFoundException</code> errors when you try to import the class. In our trivial example, that would mean changing the ns import to:</p>
<pre><code> (ns myapp.music-store
   (:require [myapp.cool-music]
   (:import [myapp.cool_music Vinyl]))
</code></pre>
</li>
</ol>
<h3 id="clojurescript">ClojureScript</h3>
<p>ClojureScript generates the code for a record in the namespace it is defined in. You can require, refer, and alias a record just like you would any other function in a ClojureScript namespace.</p>
<pre><code>(ns myapp.cool-music)

(defrecord Vinyl [speed])

;;; meanwhile ...

(ns myapp.music-store
  (:require [myapp.cool-music :refer [Vinyl]))

(instance? Vinyl v)

;; or

(ns myapp.music-store
  (:require [myapp.cool-music :as m))

(instance? m/Vinyl v)

;; or

(ns myapp.music-store
  (:require [myapp.cool-music))

(instance? myapp.cool-music/Vinyl v)
</code></pre>
<p>There are no hidden gotchas with requiring records in ClojureScript. At <a href="http://dev.clojure.org/jira/browse/CLJS-312">one point</a> ClojureScript supported importing records like Clojure, but this was <a href="http://dev.clojure.org/jira/browse/CLJS-642">backed out</a> later.</p>
<h3 id="clojure-and-clojurescript">Clojure and ClojureScript</h3>
<p>If you want to work with Clojure and ClojureScript (and let&rsquo;s face it, who doesn&rsquo;t?) then you can use <a href="https://danielcompton.net/2015/06/10/clojure-reader-conditionals-by-example">Reader Conditionals</a> to require a record in both language variants at the same time.</p>
<pre><code>(ns myapp.music-store
  (:require #?(:clj [myapp.cool-music]
               :cljs [myapp.cool-music :refer [Vinyl]]))
  #?(:clj
     (:import [myapp.cool_music Vinyl])))

(instance? Vinyl v)
</code></pre>
]]></content:encoded>
    </item>
    
    <item>
      <title>Speeding up Clojure(Script) sorting by 100x</title>
      <link>https://danielcompton.net/speeding-up-clojure-sorting-by-100x</link>
      <pubDate>Mon, 04 Apr 2016 09:43:46 +1300</pubDate>
      
      <guid>https://danielcompton.net/speeding-up-clojure-sorting-by-100x</guid>
      <description>Suspiciously slow code I&amp;rsquo;ve recently been working on a new ClojureScript application as part of a contract, and I was digging around for things to polish before launch. The app was mostly fast, but I noticed that when the main list of content got to around 40 items, it was a little bit slow to render. I also noticed that it seemed like it got almost twice as slow when I added another 10 items.</description>
      <content:encoded><![CDATA[<h2 id="suspiciously-slow-code">Suspiciously slow code</h2>
<p>I&rsquo;ve recently been working on a new ClojureScript application as part of a contract, and I was digging around for things to polish before launch. The app was mostly fast, but I noticed that when the main list of content got to around 40 items, it was a little bit slow to render. I also noticed that it seemed like it got almost twice as slow when I added another 10 items. At this point, you might already be having alarm bells go off in your head suggesting what the problem was likely to be. I didn&rsquo;t, so I dived into the code to look at the part of the app rendering the main list.</p>
<h2 id="analysis">Analysis</h2>
<p>I looked over the code path that rendered the list, and wrapped <code>time</code> around a few suspect pieces of code. After a few checks, I found that a <code>sort-by</code> function in the view was the slow part, though it wasn&rsquo;t immediately clear why sorting a list of 40 items would take a second. We were using a custom comparison function with <code>sort-by</code> to order items by state (flagged, unread, read, etc.), then reverse date order (newest items first).</p>
<p><code>sort-by</code> takes a custom sort key function. Our comparison parsing the ISO 8601 timestamp into a date, then subtracting the current Unix time from the parsed Unix time to get an integer. The lowest numbers are the most recent dates and would be sorted first. I suspected that the date parsing could be the problem, but I wasn&rsquo;t really sure. As an experiment, I disabled all of the date parsing, and returned the string directly for comparison. My sorting was the wrong way around, but it went from taking 1000 ms to 10 ms, a factor of 100x speedup!</p>
<h2 id="a-fix">A fix</h2>
<p>A standard sort of the dates (which were in ISO 8601 order, e.g. <code>2016-04-02T08:24:31+00:00</code>) sorted the oldest dates as the first ones in the list. After a few minutes thinking, I remembered I had recently read the clojure.org guide on <a href="http://clojure.org/guides/comparators">comparators</a>. In it, it discusses a <a href="http://clojure.org/guides/comparators#_reverse_order">reverse comparator</a>:</p>
<pre><code>(fn [a b] (compare b a))
</code></pre>
<p>This comparator is exactly the same as a normal comparator, but it will return the opposite result to what the normal one would. Passing this comparator to <code>sort-by</code> kept the 100x speedup, but sorted in the correct order. The list rendered in 10-15 ms, and was now plenty fast enough.</p>
<p>One question remained though, why was the list getting so much slower to render as I added a few more items to it? Of course reading this now, you Dear Reader are probably thinking to yourself, &ldquo;aha! JavaScript&rsquo;s sorting algorithm will be <a href="http://stackoverflow.com/a/236534"><code>O(n log(n))</code></a>, and the slow comparison function will therefore be called <code>O(n log(n))</code> times.&rdquo; It took me a bit more thinking than you (I didn&rsquo;t have a blog post explaining why my code was slow to work from), but I got to this conclusion in the end too.</p>
<p>I really enjoyed this debugging session, as it is not very often that I can both speed up real world code by 100x, and get exposed directly to algorithmic complexity issues. A++, would debug again.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Plumatic Schema - specifying goog.date.UtcDateTime</title>
      <link>https://danielcompton.net/snippets/plumatic-schema-goog-date-utcdatetime</link>
      <pubDate>Wed, 17 Feb 2016 01:34:43 +1300</pubDate>
      
      <guid>https://danielcompton.net/snippets/plumatic-schema-goog-date-utcdatetime</guid>
      <description>Plumatic (nee Prismatic) Schema is a great tool for adding structural typing to your code.
Specifying standard Clojure types is fairly straightforward, but I recently needed to specify that a value was a goog.date.UtcDateTime. I did a bit of searching on Google, didn&amp;rsquo;t find anything. I then looked in the company codebase and found it. Here&amp;rsquo;s a minimal example:
(ns myns (:require [goog.date.UtcDateTime])) (def Date js/goog.date.UtcDateTime)  </description>
      <content:encoded><![CDATA[<p>Plumatic (<a href="http://venturebeat.com/2015/12/11/prismatic-is-shutting-down-its-news-app-for-ios-android-and-web-on-december-20/">nee Prismatic</a>) <a href="https://github.com/plumatic/schema">Schema</a> is a great tool for adding structural typing to your code.</p>
<p>Specifying standard Clojure types is fairly straightforward, but I recently needed to specify that a value was a <code>goog.date.UtcDateTime</code>. I did a bit of searching on Google, didn&rsquo;t find anything. I then looked in the company codebase and found it. Here&rsquo;s a minimal example:</p>
<pre><code>(ns myns
  (:require [goog.date.UtcDateTime]))

(def Date js/goog.date.UtcDateTime)
</code></pre>
]]></content:encoded>
    </item>
    
    <item>
      <title>State of Clojure Survey 2015 Analysis</title>
      <link>https://danielcompton.net/clojure-survey-2015</link>
      <pubDate>Fri, 29 Jan 2016 09:56:55 +1300</pubDate>
      
      <guid>https://danielcompton.net/clojure-survey-2015</guid>
      <description>Cognitect has released the State Of Clojure 2015 results. Justin Gehtland did a good analysis on the quantitative parts of the survey, and summarizing the comments section at the end. I read (most) all of them and got a feel for the zeitgeist of where the Clojure community is looking for improvements. After compliments, error messages and documentation far and away received the most comments. Below are some quotes grouped by subject, to help you get a feel for the responses.</description>
      <content:encoded><![CDATA[<p>Cognitect has released the <a href="http://blog.cognitect.com/blog/2016/1/28/state-of-clojure-2015-survey-results">State Of Clojure 2015 results</a>. Justin Gehtland did a good analysis on the quantitative parts of the survey, and summarizing the comments section at the end. I read (most) all of them and got a feel for the zeitgeist of where the Clojure community is looking for improvements. After compliments, error messages and documentation far and away received the most comments. Below are some quotes grouped by subject, to help you get a feel for the responses. You can read all of the comments on the <a href="https://www.surveymonkey.com/results/SM-QKBJ2C5J/">SurveyMonkey page</a>.</p>
<h1 id="error-messages">Error messages</h1>
<p>Error messages have been a pain point with Clojure since the <a href="http://cemerick.com/2010/06/07/results-from-the-state-of-clojure-summer-2010-survey/">first Clojure survey in 2010</a>. <a href="https://twitter.com/colinfleming">Colin Fleming&rsquo;s</a> talk on <a href="https://www.youtube.com/watch?v=kt4haSH2xcs">Improving Clojure&rsquo;s Error Messages with Grammars</a> represents a bright spot on the horizon, and I hope that some variant of this comes to Clojure and ClojureScript. I&rsquo;d highly recommend watching the talk if you haven&rsquo;t already.</p>
<blockquote>
<p>I&rsquo;d love to see elm-like approach to hard tasks like improving on error reporting and documentation. Clojure team is so skilled that it won&rsquo;t bother even with low hanging fruit. But it could be hurtful in the long run.</p>
</blockquote>
<blockquote>
<p>Regarding potential future enhancements, improved error reporting would be very helpful. This has been a major stumbling block for our junior developers in particular. Too many error messages require a high level of understanding of Clojure internals to understand. Overall, I&rsquo;m very appreciative of the well-thought-out design decisions in both Clojure and its ecosystem.</p>
</blockquote>
<blockquote>
<p>Please fix/finish transitive AOT, and please make error messages better. I know error messages continue to receive this sort of &ldquo;well, if you wanna make &rsquo;em better, patches welcome&hellip;&rdquo; treatment, but I think it&rsquo;s a mistake to keep beating up on them, insinuating they don&rsquo;t really matter. As someone who&rsquo;s spent a fair amount of time debugging Clojure programs, some of them <em>do</em> matter, and I think the wrong message is being sent to would-be contributors about the value in improving them.</p>
</blockquote>
<blockquote>
<p>Better error messages from macros! It can be done with PEGs quite easily.</p>
</blockquote>
<blockquote>
<p>Please improve error messages - Elm developers are a good example to follow.</p>
</blockquote>
<blockquote>
<p>2+ years with Clojure. First one was strong, but the community has been solving non-problems (transducers, reducers) instead of improving error messages and general debugability.</p>
</blockquote>
<blockquote>
<p>Highest on my list of annoyances are NullPointerExceptions missing stack traces. They they disproportionately more time to debug that other failures. We rarely see them in production but during development they are a constant scourge.</p>
</blockquote>
<blockquote>
<p>Clojure has the problem that many languages have &mdash; the people capable of providing a better UX aren&rsquo;t interested in solving that problem. (Myself included.) We could learn from the Go core team&rsquo;s willingness to solve common UX problems (fast compiler, auto-formatter) and other projects like Elm&rsquo;s compiler work to support good error messages.</p>
</blockquote>
<h1 id="docs">Docs</h1>
<p><a href="http://clojure.org">clojure.org</a> has undergone a massive visual refresh between the survey being taken, and the results being released. I have high hopes that it will become a central source for hiqh quality, official documentation and ease the pain for newcomers.</p>
<blockquote>
<p>Community &amp; resource wise, everything things feel extremely federated, in a bad way. <em>Documentation</em> This is where I had the worst experience with Clojure. Documentation is extremely federated. To understand clojure.zip &amp; clojure.core.logic took me so much work [&hellip;]</p>
</blockquote>
<blockquote>
<p>Many things that disappoint you about Clojure at first (&ldquo;why errors are so awful?&rdquo;, &ldquo;why the contribution process is so hard?&rdquo;, &quot; why don&rsquo;t you implement this one feature I like? &ldquo;), they fade away as you learn Clojure and Clojure Way more. Still, it would nice to have a sort of explain-like-I&rsquo;m-five FAQ somewhere on clojure.org that covers these non-obvious points so that people skip the frustration part and understand the reasoning behind those decisions immediately.</p>
</blockquote>
<blockquote>
<p>CLJS could use better official documentation.</p>
</blockquote>
<blockquote>
<p>I still don&rsquo;t know how to get externs working with either lein or boot!! Evaluating code in vim doesn&rsquo;t always work. Documentation on google are just not reliable because they are outdated or assumes too much pre-knowledge. Applying what&rsquo;s read in the docs most often do not work, or I just don&rsquo;t understand. The documentation must really be much more comprehensive and not assume the readers are clojure pros.</p>
</blockquote>
<blockquote>
<p>Documentation! The clojure.org documentation is so terse that it is unusable for beginners. The clojuredocs.org documentation is confusing for someone who wants the learn the basics. Some examples are too cryptic and appears to be written by very smart people showing off edge uses of the feature they&rsquo;re describing.</p>
</blockquote>
<blockquote>
<p>Clojure needs more outreach. Clojure.org or clojuredocs.org needs more tutorials, application-development documentation pointers (For example: &ldquo;here are your choices if you want to make webapps with Clojure&rdquo;).</p>
</blockquote>
<blockquote>
<p>Very happy with progress on cljs.js (tho remains sparsely documented). Much of my pain is related to the compilation step. Lots of errors still happen only after compilation, &amp; not easy to know how to split large code base and load only necessary modules, etc.</p>
</blockquote>
<blockquote>
<p>Re. documentation: Features added to clojure.core usually have far inferior documentation on initial release than many libraries. Sometimes this is eventually remedied by the community, but sometimes not. This has been the case for reducers, core.async, the new threading macros, and transducers. Even the core library functions didn&rsquo;t have much example-based documentation until the community took it upon themselves to make clojuredocs. [&hellip;] Actual documentation, with practical examples, would lead to faster and more widespread adoption of new features.</p>
</blockquote>
<blockquote>
<p>We just had a Clojure user group meeting here in PDX with several new faces, new to Clojure. [&hellip;] One person pointed out how the Clojure home page makes no mention of Leiningen, the de-facto standard build tool. The references to running Clojure apps with &ldquo;java -jar &hellip;&rdquo; are that much more intimidating for anyone coming from a non-Java background. Some of these issues were well described in the &ldquo;<a href="https://www.google.co.nz/webhp?sourceid=chrome-instant&amp;ion=1&amp;espv=2&amp;ie=UTF-8#q=clojurescript%20for%20the%20skeptics">ClojureScript for Skeptics</a>&rdquo; talk at the Conj. Consensus: people love, or want to love, the language (I do!) but the rough edges have not been smoothed out, and it is still intimidating to get started in Clojure. &ndash; Howard</p>
</blockquote>
<h1 id="setuptooling">Setup/tooling</h1>
<p>Setup and tooling has historically been another pain point in Clojure. In the ClojureScript world, Figwheel seems to be solving a lot of hard problems (REPL, reloading code) in a relatively easy way to set up, and I&rsquo;m sure it will get even better this year. As an alternative to emacs, <a href="http://cursiveclojure.com/">Cursive</a> (which I use) is a great tool for getting a full Clojure development environment setup with minimal hassle.</p>
<blockquote>
<p>By far, the biggest complaints I hear from friends and at meetups is the startup time and the work required to get a ClojureScript workflow set up.</p>
</blockquote>
<blockquote>
<p>Clojurescript project setup remains really involved.</p>
</blockquote>
<blockquote>
<p>Tooling tooling tooling</p>
</blockquote>
<blockquote>
<p>[&hellip;] EMACS SETUP: IMPOSSIBLE I used and liked emacs 15 years ago and prefer to use emacs for clojure development now, but after a full day of trying I still can&rsquo;t get all the emacs pieces together. It&rsquo;s too complex, there are too many half-baked and out-of-date how-to examples. Will the real viable emacs setup tutorial please stand up?</p>
</blockquote>
<blockquote>
<p>Cursive and it&rsquo;s debugger are a Godsend - I couldn&rsquo;t ever convince myself to use Emacs and all the alternatives were inferior. Cursive made writing and debugging Clojure a really pleasant experience. Same with boot in Clojurescript world - getting lein + cljbsuild + figwheel working well was a pain. Boot+boot-cljs+boot-reload+boot-cljs-repl is a pleasure. I think those two things will do a lot good towards Clojure and  Clojurescript adoption.</p>
</blockquote>
<h1 id="marketingadoption">Marketing/Adoption</h1>
<p>Convincing coworkers to adopt Clojure also was a pain point for some of the respondents, and additional marketing materials could help here. Cognitect&rsquo;s <a href="http://cognitect.com/resources#case-studies">case studies</a> are good, and could be ported to the official Clojure website.</p>
<blockquote>
<p>The clj / cljs / om / figwheel websites make Clojure appear like a niche ecosystem. Seems to be time for marketing!</p>
</blockquote>
<blockquote>
<p>needs better marketing. clojure has bad marketing (great product, bad marketing) typesafe has good marketing (complex product, good marketing) 10gen has great marketing (bad product, great marketing) it is hurting companies wide adoption: &ldquo;Clojure? Um.. What is it you said?&rdquo; &ldquo;Scala, yea, I&rsquo;ve heard good things about it, it&rsquo;s solid.&rdquo; &ldquo;MongoDB? Oh, yea my teams tell me it&rsquo;s really good.&rdquo;</p>
</blockquote>
<blockquote>
<p>Love clojure and clojureScript. Where I need help is on the &ldquo;evangelical&rdquo; side. If we had more people singing the praises of clojure that would help my business secure more clojure business and everyone else&rsquo;s work as well. This brings in more money and talent which can then be reinvested into tooling, systems, turn-around development time,etc. just look at what&rsquo;s happened over in the JS world once their reputation improved.</p>
</blockquote>
<blockquote>
<p>Overall, very happy with the current direction of Clojure. What feels missing is awareness in the market about the goods of is as a technology, as the biggest impediment with using Clojure more has been finding customers willing to embrace the risk. Alternatives like Scala managed to have a better name within the industry.</p>
</blockquote>
<blockquote>
<p>Clojure deserves a better website and documentation.</p>
</blockquote>
<blockquote>
<p>Still trying to persuade co-workers to use Clojure more.</p>
</blockquote>
<h1 id="community">Community</h1>
<p>In my opinion, the Clojure community is one of Clojure&rsquo;s greatest assets. I&rsquo;ve found it to be overwhelmingly positive, and there are a massive amount of innovative libraries coming from a very young community. There were also some concerns about the contribution process, and how many of the decisions about Clojure happen inside Cognitect.</p>
<blockquote>
<p>Many thanks to Rich, Stu, David, Alex and many other people from community and Cognitect. You are doing amazing job. I love the culture of community you created around Clojure: open community with emphasis on learning, design, thinking hard and solving the right problem. It is inspiring place to be in.</p>
</blockquote>
<blockquote>
<p>What an amazing language. Relatively frequent, consistently stable releases. A pleasure to use. A friendly, smart community. I feel very lucky to be a Clojure user! Thank you for all of your hard work.</p>
</blockquote>
<blockquote>
<p>The Clojure contrib process frustrates me more than any technical or community aspect of the language.</p>
</blockquote>
<blockquote>
<p>Clojure gets a lot right, but as has been repeatedly discussed the pace of evolution and the maintainership&rsquo;s dim view of 3rd party non-bugfix work flatly leads to worthy but minor work such as type predicates going largely ignored and certainly unmerged. In most open source projects, contributors can impact priorities by giving of their time to support work which isn&rsquo;t high priority. The work which Nola Stowe did on clojure.string was awesome and I think we can see more of that if Alex et all allocate more capacity to working with contributors.</p>
</blockquote>
<blockquote>
<p>I found some of the recent back-and-forth about tuples to be <em>very</em> disheartening&mdash;if I were Zach Tellman I would decide not to bother attempting to make improvements to the core of Clojure. [&hellip;]</p>
</blockquote>
<blockquote>
<p>i have become a little worried about the future of the language. The core team are way ahead in terms of design and concepts, but seem to lack any kind of empathy with beginners.</p>
</blockquote>
<blockquote>
<p>Things I think should be a priority for the long term future of Clojure: [&hellip;] 3. More open core development process. I worry about the long term future of Clojure when it appears to be driven by internal decisions within a single company (i.e. Cognitect). I am uncomfortable with this approach, and am hesitant to commit fully to Clojure as a language until this becomes more open. Maybe a &ldquo;Clojure Foundation&rdquo; would be a good idea?</p>
</blockquote>
<blockquote>
<p>Thanks to everyone again for another great year in CLJ(S)land. Best community for any language.</p>
</blockquote>
<blockquote>
<p>I participate in a local meetup group which has helped greatly and I find the community very welcoming (especially being a woman, I&rsquo;m not finding as many issues as I do with other communities). Thanks!</p>
</blockquote>
<blockquote>
<p>Keep up the great work! Its been a joy to participate in this community :)</p>
</blockquote>
<blockquote>
<p>I would like to thank entire Cognitect staff for creating such a great environment and community.</p>
</blockquote>
<h1 id="libraries">Libraries</h1>
<p>Although there are some guides like <a href="http://www.clojure-toolbox.com/">Clojure Toolbox</a>, <a href="github.com/razum2um/awesome-clojure">awesome-clojure</a> and the Luminus <a href="http://www.luminusweb.net/docs/useful_libraries.md">useful libraries</a> list, it seems like there are still pain points around library discovery.</p>
<blockquote>
<p>Finding good libraries has not been difficult, but it would be helpful to have some mechanism in the community for evaluating which libraries are viable in the long term as well as which are &ldquo;best in class&rdquo;, so to speek. In many cases, I want a library that will provide a useful component for a multi-year project. The library does what I need and is available, but the modifications on github are 3+ years ago. Should I invest in using this library in my core code? Are there better, more current and maintained options? And so forth. Some community aggregation that makes it easy to evaluate libraries in this sense would be very helpful. [&hellip;]</p>
</blockquote>
<blockquote>
<p>Libraries Not sure where the main place is to find clojure libraries. Some are in maven (with no ability to evaluate the library). Clojars also feels incomplete and hard to evaluate. The landing page <a href="http://clojure.org/libraries">http://clojure.org/libraries</a> even suggests checking maven, clojars, and github, it feels like a dead end. Google is better resource than these, because you can find blogs evaluating the libraries.</p>
</blockquote>
<h1 id="typing">Typing</h1>
<p>I was surprised to see so many comments about static typing, but it was a recurring theme. They can roughly be divided into three groups:</p>
<ol>
<li>People who were interested in structural typing (<a href="https://github.com/plumatic/schema">Prismatic Schema</a>), or gradual typing (<a href="https://github.com/clojure/core.typed">core.typed</a>).</li>
<li>People who were getting push back from their organisation for using a dynamic language.</li>
<li>People who wanted a type system like Haskell&rsquo;s.</li>
</ol>
<p>There seems to be a lot of interest in core.typed but people are waiting at the sidelines until it reaches more maturity.</p>
<blockquote>
<p>I was surprised to see that the survey doesn&rsquo;t include reference to usage of typing or contract tools like core.typed or Schema. I&rsquo;m interested in understanding how widespread their usage is. Schema&rsquo;s been an important tool in helping to encourage Clojure&rsquo;s more widespread use at our enterprise and I&rsquo;ve been largely happy with it.</p>
</blockquote>
<blockquote>
<p>Clojure and ClojureScript are amazing projects and the community is pushing the edges of programming today (Om Next, Datomic, cljc). I&rsquo;ve been close to using both many times, but at this point I don&rsquo;t think I could leave the expressive syntax or type systems in Haskell and PureScript. I wish they had the same community and dev experience, and am interested in using the Clojure community&rsquo;s ideas there.</p>
</blockquote>
<blockquote>
<p>People in my organization feel strongly that dynamic typing won&rsquo;t scale to projects with more than a few developers. I am concentrating on small projects. Also, the learning curve for Java devs is a bit steep. Like anything else, one has to really want it.</p>
</blockquote>
<blockquote>
<p>The two things holding back Clojure/ClojureScript use at work are corporate policy and a strong fear of weakly typed production languages by the team.</p>
</blockquote>
<blockquote>
<p>I love clojure but I also like static type systems. Don&rsquo;t know if its possible to two in a way that works well. Haskell and scala are languages I like for its type system</p>
</blockquote>
<blockquote>
<p>The discussion we have been having lately though is around static typing. I have a Haskell background (and a Phd in type systems, even), so I&rsquo;m aware of the benefits they can provide but I don&rsquo;t think they&rsquo;re a silver bullet either. None-the-less, improved static support seems incredibly useful. A gradual-typing approach does seem ideal, allowing you to specify either types up front, or to add annotations as the design solidifies, perhaps. I&rsquo;m eagerly watching Ambrose&rsquo;s work, and perhaps prismatic-schema is enough &ndash; it would be great to get some of the core community&rsquo;s thoughts on the matter though.</p>
</blockquote>
<blockquote>
<p>I really, really, really want to see some form of official support for static typing. This could be core.typed, but it needs to be blessed by the core Clojure dev team and development to allow core.typed (and other future tools) to better integrate with the compiler is necessary. Type annotations provide helpful documentation and (optional) static type checking can help speed up development for those already annotating for documentation purposes by detecting type errors before executing programs. I see the lack of support for (optional) static typing as Clojure&rsquo;s biggest weakness and the main reason I have considered moving to a different language.</p>
</blockquote>
<h1 id="compliments">Compliments</h1>
<p>Like Justin said, over half of the responses were happy or positive. Here&rsquo;s a few to finish on an upbeat note. I&rsquo;m looking forward to seeing what 2016 brings for Clojure, and especially ClojureScript. The tooling story seems to be coming together quite well. If enhanced error messages make it into Clojure 1.9, and the documentation story improves, a lot of the pain in using Clojure could be minimised.</p>
<blockquote>
<p>(= &ldquo;Clojure&rdquo; &ldquo;Awesome!&rdquo;) =&gt; true</p>
</blockquote>
<blockquote>
<p>Thanks for everything that you do. :)</p>
</blockquote>
<blockquote>
<p>Love it! Thank you for everything that you do.</p>
</blockquote>
<blockquote>
<p>I just love programming in clojure.</p>
</blockquote>
<blockquote>
<p>Very nice thing. I like to program in this Lisp a lot</p>
</blockquote>
<blockquote>
<p>I would never have written <a href="https://partsbox.io/">PartsBox.io</a> if it wasn&rsquo;t for Clojure and ClojureScript. Only these tools allow for such a productivity increase that a single person can write a complete medium-size application.</p>
</blockquote>
<blockquote>
<p>You rock guys, I love you!!!</p>
</blockquote>
<blockquote>
<p>Onward and upward!</p>
</blockquote>
]]></content:encoded>
    </item>
    
    <item>
      <title>Debugging with the Scientific Method - Stuart Halloway</title>
      <link>https://danielcompton.net/snippets/debugging-with-the-scientific-method</link>
      <pubDate>Fri, 29 Jan 2016 04:39:47 +1300</pubDate>
      
      <guid>https://danielcompton.net/snippets/debugging-with-the-scientific-method</guid>
      <description>In this video Stuart Halloway talks about adopting a scientific mindset when debugging. Thinking in this way has absolutely changed the way I now approach debugging. Debugging is such a core skill in software development, but how many developers would rate themselves to be truly great at debugging? Not me yet, but after watching that video I&amp;rsquo;ve picked up two books: Debugging and Why Programs Fail to learn more and hone this skill.</description>
      <content:encoded><![CDATA[<p>In this video Stuart Halloway talks about adopting a scientific mindset when debugging. Thinking in this way has absolutely changed the way I now approach debugging. Debugging is such a core skill in software development, but how many developers would rate themselves to be truly great at debugging? Not me yet, but after watching that video I&rsquo;ve picked up two books: <a href="http://www.amazon.com/exec/obidos/ASIN/0814474578/debuggingrule-20">Debugging</a> and <a href="http://www.amazon.com/Why-Programs-Fail-Systematic-Debugging-ebook/dp/B0092L8LCW/">Why Programs Fail</a> to learn more and hone this skill. You can see the slides and related resources at Stuart&rsquo;s <a href="https://github.com/stuarthalloway/presentations/wiki/Debugging-with-the-Scientific-Method">wiki page</a>.</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
