<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>(david-mcneil.com :blog)</title><generator>Tumblr (3.0; @davidmcneil)</generator><link>http://david-mcneil.com/</link><item><title>Understanding Datomic?</title><description>&lt;p&gt;In the Datomic unsession last night at ClojureWest Stu and Rich hosted a Q&amp;amp;A on Datomic. I appreciated their time and I now feel I have a better grasp of what they are doing with Datomic.&lt;/p&gt;

&lt;p&gt;In particular I felt enlightened by Stu&amp;#8217;s question: &amp;#8220;which provides faster data access, a fast local spinning drive or an SSD attached via a fat network pipe?&amp;#8221;&lt;/p&gt;

&lt;p&gt;I hadn&amp;#8217;t focused on this aspect of their approach. In particular I was not aware that Amazon&amp;#8217;s DynamoDB is SSD based.&lt;/p&gt;

&lt;p&gt;So the way I understand what Datomic does is that it allows the traditional database server to be distributed across many server machines (i.e. Datomic peers). Writes still go through a single server for consistency, but reads can go against a cluster of machines. This is possible because Amazon&amp;#8217;s SSD backed DynamoDB offers network access to storage at speeds that historically required local disks. So as I understand it:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;Datomic is at the front of a technology wave that is crashing. Spinning disks are out and SSDs are in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can practically think of a distributed SSD cluster on a fat network pipe as the equivalent of a shared hard drive in terms of performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This means that we can fire up many servers to read from that &amp;#8220;shared &amp;amp; distributed&amp;#8221; drive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once we can start up many servers we have a distributed database server that offers ACID writes through a single server with failover.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now that we have a distributed data server we have an abundance of processing on the database server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With an abundance of database server processing power we can move the application code onto the database servers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;To my way of thinking the description above makes it more clear to me what Datomic is enabling and why it is possible. It seems many people that talk about Datomic get hung up on thinking of Datomic peers as traditional clients. To me it seems that Datomic peers are more like traditional database servers.&lt;/p&gt;

&lt;p&gt;I wonder if my description above is correct? I wonder if positioning peers as servers would be an easier &amp;#8220;sell&amp;#8221;?&lt;/p&gt;</description><link>http://david-mcneil.com/post/19455436291</link><guid>http://david-mcneil.com/post/19455436291</guid><pubDate>Sat, 17 Mar 2012 10:56:00 -0500</pubDate><category>clojure datomic</category></item><item><title>Using Datomic in Clojure: Baby Steps</title><description>&lt;p&gt;I ported over the first few steps of the in-memory &lt;a href="http://www.datomic.com/company/resources/tutorial"&gt;Datomic tutorial&lt;/a&gt; to Clojure: &lt;a href="https://gist.github.com/2060731"&gt;&lt;a href="https://gist.github.com/2060731"&gt;https://gist.github.com/2060731&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To run this code do something like:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;p&gt;download the &lt;a href="http://www.datomic.com/product/downloads"&gt;datomic zip&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;follow the datomic README to install the datomic jar to your local maven repo (in the mvn incantation change &amp;#8220;datomic.jar&amp;#8221; to match the local file name from the datomic zip)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;setup a lein project something like (I looked in the datomic pom.xml file to see what version of Clojure was required):&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;pre&gt;
(defproject datomic-tutorial "1.0.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.4.0-beta3"]
                 [com.datomic/datomic "0.1.2753"]]
  :dev-dependencies [[swank-clojure "1.4.0-SNAPSHOT"]])
&lt;/pre&gt;

&lt;p&gt;At first I tried to run this on a version of Clojure 1.3 and nothing worked.&lt;/p&gt;

&lt;p&gt;I assume that there are Clojure protocols that we can use instead of the Java interfaces but I haven&amp;#8217;t tracked them down yet.&lt;/p&gt;</description><link>http://david-mcneil.com/post/19453481409</link><guid>http://david-mcneil.com/post/19453481409</guid><pubDate>Sat, 17 Mar 2012 10:12:00 -0500</pubDate><category>clojure</category></item><item><title>Clojure Robot DSL</title><description>&lt;p&gt;The code from my “Building a DSL in Clojure For Controlling a Lego MindStorm / Arduino Robot&amp;#8221; talk at &lt;a href="http://lambdalounge.org/2012/01/31/hadoop-clojure-robots/"&gt;Lambda Lounge&lt;/a&gt; on February 2, 2012 is &lt;a href="https://github.com/david-mcneil/bolo"&gt;up on github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The talk had a few points:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;playing with Lego MindStorm and Arduino based robots is great fun&lt;/li&gt;
&lt;li&gt;they are very effective tools for teaching kids to program and to start to understand engineering&lt;/li&gt;
&lt;li&gt;a DSL built in Clojure can give kids the the same level of &amp;#8220;tinkerability&amp;#8221; in the programming language as they have with the hardware&lt;/li&gt;
&lt;li&gt;creating a new type in Clojure (a List object that is associative) is a way to get a featureful DSL with very little code&lt;/li&gt;
&lt;/ul&gt;&lt;hr&gt;&lt;p&gt;The first file to checkout is &lt;a href="https://github.com/david-mcneil/bolo/blob/master/src/bolo/op_demo.clj"&gt;op_demo.clj&lt;/a&gt;. This file introduces the new Clojure type that the DSL is built on, a Clojure &amp;#8220;operator&amp;#8221;. An operator is similar to a Clojure record, except it presents itself as a List instead of as a Map.&lt;/p&gt;

&lt;script src="https://gist.github.com/1739528.js"&gt; &lt;/script&gt;&lt;p&gt;With that as our base, we can now introduce the operators that will make up our language.&lt;/p&gt;

&lt;script src="https://gist.github.com/1739531.js"&gt; &lt;/script&gt;&lt;p&gt;Let&amp;#8217;s see what we can do with these operators:&lt;/p&gt;

&lt;script src="https://gist.github.com/1739536.js"&gt; &lt;/script&gt;&lt;p&gt;This example shows a technique for creating a DSL that nestles tightly down into Clojure.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;No parser is needed; the Clojure reader reads the program.&lt;/li&gt;
&lt;li&gt;No compiler is needed; the Clojure evaluator will walk the tree of expressions.&lt;/li&gt;
&lt;li&gt;We get macros for free.&lt;/li&gt;
&lt;li&gt;Our programs are data that can be programatically accessed.&lt;/li&gt;
&lt;li&gt;We can implement multiple targets for the language by implementing the operators in multiple namespaces.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;With respect to teaching kids to program, this approach is a natural fit to the robots. The kids can:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Define the language they will use. This can be made simpler for younger kids and more advanced for older kids.&lt;/li&gt;
&lt;li&gt;Implement the operators for their language.&lt;/li&gt;
&lt;li&gt;Learn that programs are just data to be generated and manipulated.&lt;/li&gt;
&lt;li&gt;Go as deep as they care to with creating a real compiler by defining operators for control-flow, variable bindings, etc.&lt;/li&gt;
&lt;li&gt;Get hooked on Lisp!&lt;/li&gt;
&lt;/ul&gt;</description><link>http://david-mcneil.com/post/17044248397</link><guid>http://david-mcneil.com/post/17044248397</guid><pubDate>Sat, 04 Feb 2012 13:28:00 -0600</pubDate><category>clojure</category></item><item><title>Clojure: Creating a Custom Map Type</title><description>&lt;p&gt;As presented at today&amp;#8217;s St. Louis Clojure Cljub meeting.&lt;/p&gt;

&lt;script src="https://gist.github.com/1684980.js"&gt; &lt;/script&gt;</description><link>http://david-mcneil.com/post/16535755677</link><guid>http://david-mcneil.com/post/16535755677</guid><pubDate>Thu, 26 Jan 2012 14:47:00 -0600</pubDate><category>clojure</category></item><item><title>Clojure defrecord2 code update</title><description>&lt;p&gt;I updated the &lt;a href="https://github.com/david-mcneil/defrecord2"&gt;defrecord2&lt;/a&gt; code. It now includes the following:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;record zipper support&lt;/li&gt;
&lt;li&gt;record matchure support&lt;/li&gt;
&lt;li&gt;dissoc2 preserves record type&lt;/li&gt;
&lt;li&gt;universal record constructor&lt;/li&gt;
&lt;li&gt;defined record? predicate&lt;/li&gt;
&lt;/ul&gt;</description><link>http://david-mcneil.com/post/5288275795</link><guid>http://david-mcneil.com/post/5288275795</guid><pubDate>Sat, 07 May 2011 19:17:47 -0500</pubDate><category>clojure</category></item><item><title>defrecord improvements - feedback</title><description>&lt;p&gt;In the course of doing Clojure development I have made extensive use of records and have &lt;a href="http://david-mcneil.com/post/958196603/enhanced-clojure-records-part-2"&gt;extended them in many was&lt;/a&gt;. So I was excited to see a proposal from the Clojure Core team for &lt;a href="http://clojure02.managed.contegix.com/display/design/defrecord+improvements"&gt;defrecord improvements&lt;/a&gt;. It looks like a good start, below are my thoughts and questions about the proposal.&lt;/p&gt;

&lt;h2&gt;1) Variety of forms&lt;/h2&gt;

&lt;p&gt;One question that arises is how to understand the difference between the various forms. For example these two forms:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#myns.MyRecord[1 2]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(MyRecord. 1 2)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As best I can understand it, the first form would have the validation function applied but the second would not.&lt;/p&gt;

&lt;p&gt;Furthermore as a literal form, the first can only include constants. So for instance the following use of a function call would not be valid in the first syntax:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(MyRecord. 1 (+ 1 1))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you need to write expressions to compute field values and want the validation function to be applied then you use one of the factory functions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(myns/-&amp;gt;MyRecord 1 (+ 1 1))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I assume that the position forms will require all of the fields to be provided? If so, the initialization values will only be relevant to the map forms.&lt;/p&gt;

&lt;p&gt;My understanding of the proposal is that the literal record syntax is a general syntax for Java objects. So the object created by&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(java.util.Locale. "en" "US") 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;could be expressed in the literal syntax as&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#java.util.Locale["en" "US"]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, it doesn&amp;#8217;t seem to me to be generally possible to know which contructor to use for a given object so I am not sure when this literal syntax will be used for printing (non-record) Java objects.&lt;/p&gt;

&lt;h2&gt;2) Factory function naming&lt;/h2&gt;

&lt;p&gt;I realize that the names in the proposals are just placeholders&amp;#8230; my preference is to not use &amp;#8220;-&amp;gt;&amp;#8221; (which could easily be confused with the threading macro &amp;#8220;-&amp;gt;&amp;#8221;) in the names and to name the functions with lower-case-dashed versions of the record names instead of CamelCase versions. For my sense of aesthetics this makes the use of record factory functions look like &amp;#8220;normal&amp;#8221; function calls. Furthermore, I value the ability to specify the name of the factory functions at the time the record is defined.&lt;/p&gt;

&lt;h2&gt;3) Validation&lt;/h2&gt;

&lt;p&gt;One of the forms of validation that we have found particularly helpful is to validate the names of the fields passed into the map factory function. If the map contains a key that is not a record field name then an exception is thrown. It is possible to add additional, non field-name keys, with assoc.&lt;/p&gt;

&lt;p&gt;In addition I think it is useful to allow a validation function to be defined as part of the defrecord.&lt;/p&gt;

&lt;h2&gt;4) Writing records&lt;/h2&gt;

&lt;p&gt;I value an option to exclude the namespace from the printed from of the records. Instead of this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(myns/-&amp;gt;MyRecord 1 2)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;They would optionally print as:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(-&amp;gt;MyRecord 1 2)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is useful when printing deeply nested trees of records because it trims a potentially long namespace identifier from every object&amp;#8217;s output.&lt;/p&gt;

&lt;p&gt;Finally, we have found it useful to suppress nil values when printing records with the map factory form. Again this makes the output less verbose.&lt;/p&gt;

&lt;h2&gt;5) Mutators&lt;/h2&gt;

&lt;p&gt;Beyond the initial creation of records we have found it useful to provide functions to create new record objects from existing objects. For example, the syntax could be:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(def x (myns/map-&amp;gt;MyRecord {:a 1}))
(myns/map-&amp;gt;MyRecord x {:b 2})
;; -&amp;gt; (myns/-&amp;gt;MyRecord 1 2)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By virtue of going through the factory function the validations are applied. As opposed to using assoc directly in which case the validations are not applied.&lt;/p&gt;

&lt;p&gt;Related to this is the idea of a universal constructor, e.g. named &amp;#8220;new-record&amp;#8221;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(def x (myns/map-&amp;gt;MyRecord {:a 1}))
(new-record x {:b 2})
;; -&amp;gt; (myns/-&amp;gt;MyRecord 1 2)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This allows a new record object to be created from a record object without knowing the type of the object. We have found this useful for writing generic code to handle record objects.&lt;/p&gt;

&lt;p&gt;Finally we have found it useful to define a dissoc function that removes a key from a record object, but produces a record object as the result.&lt;/p&gt;

&lt;p&gt;So instead of this default behavior from Clojure:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(class (dissoc (map-&amp;gt;MyRecord {:a 1 :b 2}) :b))
;; -&amp;gt; clojure.lang.PersistentArrayMap
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We would get:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(class (dissoc2 (map-&amp;gt;MyRecord {:a 1 :b 2}) :b))
;; -&amp;gt; myns.MyRecord
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;6) record?&lt;/h2&gt;

&lt;p&gt;We have found it useful to define a record? predicate function that reports whether a given object is a record object:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(record? (map-&amp;gt;MyRecord {:a 1 :b 2}))
;; -&amp;gt; true
(record? "hello")
;; -&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;7) walking records&lt;/h2&gt;

&lt;p&gt;We have extended defrecord to define prewalk and postwalk support and this has proven useful (despite the fact that pre/postwalk are semi-deprecated).&lt;/p&gt;

&lt;h2&gt;8) zipper support&lt;/h2&gt;

&lt;p&gt;We have extended defrecord to generate multi-method implementations for each record class to participate in a zip-record function that allows zippers to be used to navigate record trees. We have used this feature extensively in our product to manipulate record trees.&lt;/p&gt;

&lt;h2&gt;9) matchure support&lt;/h2&gt;

&lt;p&gt;We have extended defrecord to support &lt;a href="https://github.com/dcolthorp/matchure"&gt;matchure&lt;/a&gt;. Specifically all records participate in a multi-method that allows them to be used with a &amp;#8220;match-record&amp;#8221; of our creation that delegates to matchure if-match . For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(match-record [(map-&amp;gt;MyRecord {:a 1 :b ?b})
               (map-&amp;gt;MyRecord {:a 1 :b 2})]
                           b)
;; -&amp;gt; 2
&lt;/code&gt;&lt;/pre&gt;</description><link>http://david-mcneil.com/post/4403345585</link><guid>http://david-mcneil.com/post/4403345585</guid><pubDate>Wed, 06 Apr 2011 19:37:00 -0500</pubDate><category>clojure</category></item><item><title>Clojure Protocol Adapters</title><description>&lt;p&gt;Once you start using Clojure protocols to capture abstractions
it is natural to want to define implementations of higher level
protocols in terms of the lower level protocols. But, Clojure does not
allow protocols to be extended to other protocols. At the Clojure Conj
in 2010 Rich Hickey mentioned an approach to this problem in which a
protocol is extended to Object as a &amp;#8220;catch all&amp;#8221;. Then if the protocol is
used with an object that satisfies protocol X dynamically extend the
class of the object to protocol Y.&lt;/p&gt;

&lt;p&gt;For example, consider a low-level protocol for a Dog:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defprotocol Dog
  (bark [_]))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And a higher level protocol for an Animal:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defprotocol Animal
  (speak [_]))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We would like to be able to write something like the following to
define how a Dog can participate in the Animal protocol.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(adapt-protocol Dog Animal
                (speak [dog]
                       (bark dog)))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I have written a module, named
&lt;a href="https://github.com/david-mcneil/clojure-adapt"&gt;clojure-adapt&lt;/a&gt;, that
provides this adapt-protocol capability.&lt;/p&gt;

&lt;p&gt;The adapt-protocol call registers the adapter functions in a
global map that is keyed by the protocols Animal and Dog. The
Animal protocol is extended to the base Object class with
implementation functions that consult the global adapter map and
dynamically extend the Animal protocol to the classes of objects that
satisfy the Dog protocol.&lt;/p&gt;

&lt;p&gt;If we have an object that satisfies the Dog protocol, for example, a String:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(extend-protocol Dog String
                 (bark [s] (str "arf " s)))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then we can use the Animal functions on the Dog:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(speak "Fido")
=&amp;gt; "arf Fido"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The adapters are only used if the object does not satisfy the
protocol. So if a protocol is extended to a class, then the adapters
are not used on that class even if objects of the class satisfy the protocol being
adapted.&lt;/p&gt;

&lt;p&gt;For example, if the Animal protocol and the Dog protocol are extended
to the Date class the adapter is not used.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(extend-protocol Dog java.util.Date
                 (bark [d] (str "dog as of " (.getTime d))))

(extend-protocol Animal java.util.Date
                 (speak [d] (str "animal as of " (.getTime d))))

(bark (java.util.Date. (long 100)))
=&amp;gt; "dog as of 100"

(speak (java.util.Date. (long 100)))
=&amp;gt; "animal as of 100"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When the Animal function, speak, is called on a Date object the
adapter is not used even though the Date satisfies the Dog
protocol. This is because the Date class is already participating in
the Animal protocol.&lt;/p&gt;

&lt;p&gt;The adapt-protocol call is tricky to use during development because
once an adapter is &amp;#8220;installed&amp;#8221; for a class subsequent calls to
adapt-protocol do not affect the class. One work-around to this is
to refine an adapter by using extend-protocol with a test class. Once
the adapter is working properly then register it for use via adapt-protocol.&lt;/p&gt;</description><link>http://david-mcneil.com/post/3495351254</link><guid>http://david-mcneil.com/post/3495351254</guid><pubDate>Thu, 24 Feb 2011 21:13:00 -0600</pubDate><category>clojure</category></item><item><title>Implementation "inheritance" in Clojure</title><description>&lt;p&gt;Clojure records and protocols eschew
inheritance. For details see the &amp;#8220;Datatypes and protocols are opinionated&amp;#8221; section on the &lt;a href="http://clojure.org/datatypes"&gt;Clojure datatypes page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are used to Java style type inheritance you
might be surprised that there is no explicit record/protocol mechanism
for defining one type as a &amp;#8220;sub-type&amp;#8221; of another and inheriting the
super-type&amp;#8217;s implementation. You might even think that Clojure
datatypes are less powerful than Java clasess&amp;#8230; but you would be
wrong.&lt;/p&gt;

&lt;p&gt;The trick is that Clojure allows the implementation of a protocol to
be specified as a map. Just a simple, standard Clojure map that maps
function names to implementations. Since implementations are
expressed as maps, the surprising place to look for information on implementation
&amp;#8220;inheritance&amp;#8221; is just the functions that operate on maps. For example:
assoc and merge.&lt;/p&gt;

&lt;script src="https://gist.github.com/661983.js"&gt; &lt;/script&gt;&lt;p&gt;Notice in the example that a TrainedDog contains a Dog as a
member. This, combined with an implementation of to-dog that returns
the TrainedDog&amp;#8217;s Dog, allows the functions defined in base-behavior to
also operate on TrainedDogs.&lt;/p&gt;

&lt;p&gt;Clojure maps are constructed using the full power of the Clojure
language. Maps can be combined in ways that emulate Java&amp;#8217;s single inheritance
model or more complex multiple inheritance models and mixins. Combine
maps in any way needed to do what you need.&lt;/p&gt;

&lt;p&gt;This is a great example of embracing standard Clojure datatypes as the
means of abstraction for a problem (in this case, the problem is &amp;#8220;how to specify type implementations&amp;#8221;) and gaining the full power of Clojure as a consequence.&lt;/p&gt;

&lt;p&gt;(This was presented at the October 2010&amp;#160;&lt;a href="http://clojurecljub.wordpress.com/"&gt;Clojure Cljub&lt;/a&gt; )&lt;/p&gt;</description><link>http://david-mcneil.com/post/1475458103</link><guid>http://david-mcneil.com/post/1475458103</guid><pubDate>Wed, 03 Nov 2010 20:36:00 -0500</pubDate></item><item><title>Clojure dynamic variables and Java ThreadLocals</title><description>&lt;p&gt;At &lt;a href="http://clojurecljub.wordpress.com/"&gt;Clojure Cljub&lt;/a&gt; we talked about dynamic variables being like Java ThreadLocals. Which led to the question of whether they were really ThreadLocals. After a cursory look at the Clojure 1.2 source, the answer appears to be: &amp;#8220;yes&amp;#8221;. Each binding is not itself a ThreadLocal, but the dynamic values of a Var appear to be rooted in a ThreadLocal named &amp;#8220;dvals&amp;#8221;.&lt;/p&gt;

&lt;p&gt;From &lt;a href="http://github.com/clojure/clojure/blob/1.2.x/src/jvm/clojure/lang/Var.java"&gt;src/jvm/clojure/lang/Var.arg&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public final class Var extends ARef implements IFn, IRef, Settable{
  ...
  static ThreadLocal&amp;lt;Frame&amp;gt; dvals = new ThreadLocal&amp;lt;Frame&amp;gt;(){
  ....
  public static Associative getThreadBindings(){
    Frame f = dvals.get();
    IPersistentMap ret = PersistentHashMap.EMPTY;
    for(ISeq bs = f.bindings.seq(); bs != null; bs = bs.next())
      {
        IMapEntry e = (IMapEntry) bs.first();
        Var v = (Var) e.key();
        Box b = (Box) e.val();
        ret = ret.assoc(v, b.val);
      }
      return ret;
    }
&lt;/code&gt;&lt;/pre&gt;</description><link>http://david-mcneil.com/post/1439050822</link><guid>http://david-mcneil.com/post/1439050822</guid><pubDate>Sat, 30 Oct 2010 08:54:05 -0500</pubDate><category>clojure</category></item><item><title>Create default xmodmap</title><description>&lt;p&gt;From &lt;a href="http://blacketernal.wordpress.com/set-up-key-mappings-with-xmodmap/"&gt;http://blacketernal.wordpress.com/set-up-key-mappings-with-xmodmap/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;xmodmap -pke &amp;gt; default-modmap
xmodmap -pm &amp;gt;&amp;gt; default-modmap
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then edit the end of the default-modmap file to be formatted like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;add shift =      Shift_L  Shift_R
add lock  =      Caps_Lock
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then the resulting file can be loaded via:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;xmodmap default-modmap
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is useful for restoring the default key maps after you have messed them up. This is particularly useful if your custom xmodmap file is not idempotent.&lt;/p&gt;</description><link>http://david-mcneil.com/post/1424946010</link><guid>http://david-mcneil.com/post/1424946010</guid><pubDate>Thu, 28 Oct 2010 13:29:54 -0500</pubDate></item><item><title>clojure-conj day 2 - notes</title><description>&lt;h2&gt;Aaron Bedra - Clojure in the field&lt;/h2&gt;

&lt;p&gt;A couple of the main issues to address:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Web frameworks - too many to pick from, need to coordinate these and need better docs&lt;/li&gt;
&lt;li&gt;Dependency management - Lein is a good start, but we need more. Also Clojars is too hard to search.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Stuart Sierra - Macro Club&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://stuartsierra.com/download/2010-10-23-clojure-conj-macro-club.pdf"&gt;slides&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;clojure.test uses macros. This is confusing at times. For example, &amp;#8220;thrown?&amp;#8221; is not a var. It is interpreted by the &amp;#8220;is&amp;#8221; macro. This is surprising because it looks like a function call when it is used and this is one of the down-sides of macros: surprising behavior.&lt;/p&gt;

&lt;p&gt;lazytest is Stuart&amp;#8217;s replacement for clojure.test. He went through macros, protocols, etc. looking for good abstractions for tests and ended up falling back to the powerful, core Clojure constructs:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;functions - represent tests&lt;/li&gt;
&lt;li&gt;sequences - represent test suites&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;He is still struggling with test contexts that perform setup/teardown around tests. The problem is having a good way to get the context state into the tests. There are macros to accomplish this but they are surprising because they establish new scoping rules.&lt;/p&gt;

&lt;p&gt;In summary:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;use Clojure&amp;#8217;s core types as abstractions (functions are the most powerful)&lt;/li&gt;
&lt;li&gt;use macros for sugar&lt;/li&gt;
&lt;li&gt;don&amp;#8217;t violate user&amp;#8217;s expectations &lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Lightning Talks&lt;/h2&gt;

&lt;p&gt;Zach from Runa talked about &lt;a href="http://github.com/ztellman/aleph"&gt;Aleph&lt;/a&gt;. An asynchronous web server built on &amp;#8220;channels&amp;#8221; which are unidirectional pub/sub queues.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://tech.puredanger.com/"&gt;Alex Miller&lt;/a&gt; from &lt;a href="http://revelytix.com/"&gt;Revelytix&lt;/a&gt; described how to use Clojure zippers to process trees of Records. Great talk.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/bradford/infer"&gt;Infer&lt;/a&gt; from Bradford Cross is a very approachable machine learning library for Clojure.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://limelight.8thlight.com/"&gt;limelight&lt;/a&gt; is a rich client GUI framework.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.hazelcast.com/"&gt;Hazelcast&lt;/a&gt; is a Java dynamic clustering library.&lt;/p&gt;

&lt;h2&gt;Mark McGranaghan - Ring&lt;/h2&gt;

&lt;p&gt;Model web requests and responses with Clojure concepts:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;app( request-map ) -&amp;gt; response-map&lt;/li&gt;
&lt;li&gt;the app is a Clojure function&lt;/li&gt;
&lt;li&gt;the request and response are Clojure maps&lt;/li&gt;
&lt;li&gt;&amp;#8220;middleware&amp;#8221; is implemented as higher-order-functions&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;They produced &lt;a href="http://github.com/mmcgrana/ring/raw/master/SPEC"&gt;~120 line &amp;#8220;spec&amp;#8221;&lt;/a&gt; and from there an entire ecosystem of libraries and frameworks has grown. Now it is possible to deploy a Ring app that mixes in components from a variety of locations and they all work together in one stack.&lt;/p&gt;

&lt;p&gt;The essence of Clojure is &lt;em&gt;composable abstractions&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you want to build powerful apps you need to get the underlying abstractions right.&lt;/p&gt;

&lt;h2&gt;Rich Hickey - Keynote - Step away from the computer&lt;/h2&gt;

&lt;p&gt;When was the last time you thought hard about a problem for an hour, day, month, year?&lt;/p&gt;

&lt;p&gt;When have you confidently sat down to implement something for the first time?&lt;/p&gt;

&lt;p&gt;The point he made by the end of the talk was something like: if you will think hard and well about a problem and write down what you learn then you will position yourself to confidently implement a solution on your first attempt&lt;/p&gt;

&lt;p&gt;We commonly talk about the cheapest place to fix bugs is at development time. But, it is cheaper to fix bugs at &lt;em&gt;design&lt;/em&gt; time. The biggest problems in software are ones of &lt;em&gt;misconception&lt;/em&gt;. The developer has wrong ideas about the problem or the solution. Automated testing cannot provide a direct answer for the question of &amp;#8220;whether this is a good idea?&amp;#8221;&lt;/p&gt;

&lt;p&gt;Analysis and Design&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;not UML, not a process, not waterfall, step before &amp;#8220;go do it!&amp;#8221;&lt;/li&gt;
&lt;li&gt;identify and state the problem (verbally or in written form)&lt;/li&gt;
&lt;li&gt;critically assess proposed solutions&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;We should be solving problems, not adding features. Will the features solve a problem? Or will the features create a problem? &lt;em&gt;Avoiding&lt;/em&gt; a problem is not the same as &lt;em&gt;solving&lt;/em&gt; a problem.&lt;/p&gt;

&lt;p&gt;Problem solving is a skill which can be learned and practiced. See &lt;a href="http://en.wikipedia.org/wiki/How_to_Solve_It"&gt;&amp;#8220;How to Solve It&amp;#8221;&lt;/a&gt; Is it better to be good at problem solving or methodology X?&lt;/p&gt;

&lt;p&gt;Understand the problem:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;facts, context, constraints (known and unknown), questions to find unknown unknowns, related problems&lt;/li&gt;
&lt;li&gt;understand previous attempts to solve the problem&lt;/li&gt;
&lt;li&gt;goal is to work incrementally ahead of the best known solution to the problem&lt;/li&gt;
&lt;li&gt;write this down&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Be discerning:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;are there problems in your solution? If so, solve these.&lt;/li&gt;
&lt;li&gt;identify tradeoffs. Often stated tradeoffs just identify deficiencies in a solution. To properly understand tradeoffs it is necessary to have &lt;em&gt;at least&lt;/em&gt; two alternative solutions in hand&lt;/li&gt;
&lt;li&gt;write this down&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Focus is needed to think well:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;the computer is a distraction&lt;/li&gt;
&lt;li&gt;balls will be dropped while you are focusing deeply on a problem. This is part of the process.&lt;/li&gt;
&lt;li&gt;feed your &lt;em&gt;background mind&lt;/em&gt; by thinking a lot about the problem with the &lt;em&gt;waking mind&lt;/em&gt;. This will establish an agenda for the background mind to work.&lt;/li&gt;
&lt;li&gt;since the mind can only focus on ~7 items at a time, write down the aspects of a problem. This will allow you to quickly swap some of the items in and out of your mind. Maybe use pictures for this (not prescribing UML). Go over this repeatedly so you internalize it and can think about it long and hard.&lt;/li&gt;
&lt;li&gt;closing your eyes and removing other sensory inputs facilitates thinking well&lt;/li&gt;
&lt;li&gt;&amp;#8230; wait for a solution to come&lt;/li&gt;
&lt;li&gt;since it is not always practical to wait, pipeline. Get several problems going at once. Switch tasks when you are stuck.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Once an idea for a solution has come:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;try it&lt;/li&gt;
&lt;li&gt;code it&lt;/li&gt;
&lt;li&gt;this should involve little typing&lt;/li&gt;
&lt;li&gt;since you have thought about it enough this should be confident coding&lt;/li&gt;
&lt;li&gt;feedback (e.g. from test results) is important but don&amp;#8217;t lean on it&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;David Liebke - Concurrency to parallelism&lt;/h2&gt;

&lt;p&gt;The &lt;a href="http://data-sorcery.org/2010/10/23/clojureconj/"&gt;slides&lt;/a&gt; are very well down and contain much of the content of the presentation.&lt;/p&gt;

&lt;p&gt;Concurrency is about managing access to shared state.&lt;/p&gt;

&lt;p&gt;Parallelism is about making use of multiple processors.&lt;/p&gt;

&lt;p&gt;pmap&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;parallel meets lazy&lt;/li&gt;
&lt;li&gt;weakness - if there is a slow consumer then it degenerates (because the worker threads stop working ahead) [is that really a weakness if there is no consumer to use the results yet?]&lt;/li&gt;
&lt;li&gt;weakness - one slow processor can slow the entire process (maybe this is more of a theoretical problem?)&lt;/li&gt;
&lt;li&gt;it is more useful on long-running functions&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;fork join&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;based on &lt;a href="http://www.google.com/url?sa=t&amp;amp;source=web&amp;amp;cd=1&amp;amp;sqi=2&amp;amp;ved=0CBcQFjAA&amp;amp;url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.42.1918%26rep%3Drep1%26type%3Dpdf&amp;amp;ei=mpnFTKv2Ocj9nge5jYjQCQ&amp;amp;usg=AFQjCNE7T9egnKbvT5dNTCadRJBI-mZioQ"&gt;work of Doug Lea&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;each worker has a double ended queue (deque) of work&lt;/li&gt;
&lt;li&gt;workers can &amp;#8220;steal&amp;#8221; from other workers when they are out of work. This provides some load balancing across threads.&lt;/li&gt;
&lt;li&gt;implemented in Clojure in fjvtree&lt;/li&gt;
&lt;li&gt;in order to make pvfilter on a pvreduce work it is necessary to make the reduce function associative and it needs to handle intermediate results (which might be in a different from that the leaf inputs)&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Chas Emerick - Continuous deployment&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://cemerick.com/2010/11/02/continuous-deployment-of-clojure-web-applications/"&gt;slides&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First principle - get your beautiful creating into the hands of your customers&lt;/p&gt;

&lt;p&gt;Paths to deploying your apps:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&amp;#8220;system admin&amp;#8221; - unrepeatable, manual, undocumented, high priesthood &amp;lt;- horrible&lt;/li&gt;
&lt;li&gt;&amp;#8220;roll your own&amp;#8221; automated system - typically the default solution, not really a solution, just yak-shaving&lt;/li&gt;
&lt;li&gt;community standards - this is where you want to be, stay close to the herd&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Varying levels of community standards:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;vertically intergrated solution. This is the best, use it if you can. e.g. Google App Engine, Heroku, Azure&lt;/li&gt;
&lt;li&gt;more general tools. e.g. Chef or Puppet. But you need to use a non-Clojure language to express tasks.&lt;/li&gt;
&lt;li&gt;Clojure specific tools: jclouds (with Clojure wrappers), Pallet&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a href="http://github.com/hugoduncan/pallet"&gt;Pallet&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;pure Clojure&lt;/li&gt;
&lt;li&gt;uses &lt;a href="http://github.com/jclouds/jclouds"&gt;jclouds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;similar to Chef&lt;/li&gt;
&lt;li&gt;&amp;#8220;crates&amp;#8221; (instead of recipes) are idempotent tasks that are &amp;#8220;just&amp;#8221; Clojure and totally composable&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Don&amp;#8217;t deploy to production on Jetty (ok to use it for development). Instead use Tomcat, JBoss, or Glassfish, etc.&lt;/p&gt;

&lt;p&gt;Automate the build, test, and deploy process.&lt;/p&gt;

&lt;h2&gt;Stuart Halloway - Simplicity&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/downloads/stuarthalloway/clojure-presentations/Clojure-Simplicity.pdf"&gt;slides&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The word &amp;#8220;simple&amp;#8221; has been severely abused:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;it does not mean counting things (i.e. &amp;#8220;this is simple because it has &lt;x&gt;&lt;foos&gt;&amp;#8221;)&lt;/foos&gt;&lt;/x&gt;&lt;/li&gt;
&lt;li&gt;it does not make sense for it to mean: how productive can a newbie be (e.g. kazoo vs violin). This is no way to build a career.&lt;/li&gt;
&lt;li&gt;it does not mean that something is familiar to us&lt;/li&gt;
&lt;li&gt;it does not mean that something is minimal (although this is often a valuable characteristic)&lt;/li&gt;
&lt;li&gt;it does not mean uncomplicated&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So is the definition hopelessly subjective? No. It has an objective definition that should inform our designs and is fundamental to what we are trying to do.&lt;/p&gt;

&lt;p&gt;Simple means: not compound&lt;/p&gt;

&lt;p&gt;See &lt;a href="http://en.wikipedia.org/wiki/Studies_in_Words"&gt;&amp;#8220;Studies in Words&amp;#8221;&lt;/a&gt; by C.S. Lewis in which he talks about verbicide and how the meaning of words change over time. Specifically it examines the history of the meaning of the word &amp;#8220;simple&amp;#8221;&lt;/p&gt;

&lt;p&gt;[&amp;#8230; I had to leave early, so I missed the 2nd half of the presentation.]&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit&lt;/strong&gt; - Added link to Chas&amp;#8217; slides.
&lt;strong&gt;Edit&lt;/strong&gt; - Added link to Stuart Halloway&amp;#8217;s slides.&lt;/p&gt;</description><link>http://david-mcneil.com/post/1398718149</link><guid>http://david-mcneil.com/post/1398718149</guid><pubDate>Mon, 25 Oct 2010 10:19:00 -0500</pubDate><category>clojure</category></item><item><title>clojure-conj day 1 notes</title><description>&lt;p&gt;My rough notes of the messages I heard during day 1 (October 22, 2010) of clojure-conj.&lt;/p&gt;

&lt;h2&gt;Fogus - Roots of Clojure&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.slideshare.net/fogus/fertile-ground-the-roots-of-clojure"&gt;slides&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A list (some of it vaguely chronological) of the language environment in which Clojure was created:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;1994 - Rich praised C++ strong typing&lt;/li&gt;
&lt;li&gt;Perl arose as a language that tied the web together&lt;/li&gt;
&lt;li&gt;Paul Graham sang the praises of Lisp&lt;/li&gt;
&lt;li&gt;Java was born. Took developers half way to Lisp, but ended up on the wrong half.&lt;/li&gt;
&lt;li&gt;Ruby, Python, and JavaScript opened the minds of many to dynamic languages&lt;/li&gt;
&lt;li&gt;The Kingdom-of-Nouns is dominant, although alternative views are present in languages like Dylan, CLIPS, and Lisp&lt;/li&gt;
&lt;li&gt;Rich&amp;#8217;s &lt;a href="http://wiki.jvmlangsummit.com/images/a/ab/HickeyJVMSummit2009.pdf"&gt;&amp;#8220;Are we there yet?&amp;#8221; talk&lt;/a&gt; challenged the predominance of OO thinking. Referenced the work of Alfred North Whitehead&amp;#8217;sf &lt;a href="http://en.wikipedia.org/wiki/Process_and_Reality"&gt;&amp;#8220;Process and Reality&amp;#8221;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Prolog and Datalog&lt;/li&gt;
&lt;li&gt;Test Driven Development - Should everything be test-driven? Test Driven Dentistry?&lt;/li&gt;
&lt;li&gt;Haskell has the important idea of laziness&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/MonetDB"&gt;MonetDB&lt;/a&gt; (&amp;#8220;an open source column-oriented database&amp;#8230; designed to provide high performance on complex queries against large databases, e.g. combining tables with hundreds of columns and multi-million rows&amp;#8221;)&lt;/li&gt;
&lt;li&gt;Databases offer 
** Multi-version concurrency control
** Snapshot isolation
** Transactions&lt;/li&gt;
&lt;li&gt;ML - idea of isolating the point of change&lt;/li&gt;
&lt;li&gt;Erlang - shares many ideas with Clojure except Clojure is more open because it separates data from the functions that operate on it&lt;/li&gt;
&lt;li&gt;Rich has read &amp;#8220;all&amp;#8221; of the papers from the 1970&amp;#8217;s and 1980&amp;#8217;s&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Luke VanderHart - Zippers&lt;/h2&gt;

&lt;p&gt;Good talk that made me appreciate the beauty of zippers.&lt;/p&gt;

&lt;p&gt;Zipper overview:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Generic tree walking/editing&lt;/li&gt;
&lt;li&gt;Purely functional, fast, and elegant&lt;/li&gt;
&lt;li&gt;&lt;em&gt;tree of data&lt;/em&gt; + &lt;em&gt;focus on specific location&lt;/em&gt; = &lt;em&gt;zipper&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;edits happen at the point of focus of the zipper. It is not necessary to re-create the tree to that point. It is like an &amp;#8220;inside out glove&amp;#8221;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Zipper implementation:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Zippers are implemented as a thin wrapper around existing Clojure structures. &lt;/li&gt;
&lt;li&gt;Creating a zipper on a tree does not copy the tree into a new data structure. Instead zipper functions are applied to the existing tree.&lt;/li&gt;
&lt;li&gt;Code demonstrates effective use of metadata, first class functions, and destructuring&lt;/li&gt;
&lt;li&gt;The &amp;#8220;rest of the tree&amp;#8221; (beside the node that is focused on) is stored in a &amp;#8220;path&amp;#8221;&lt;/li&gt;
&lt;li&gt;Metadata stores zipper functions (children, branch?, make-node)&lt;/li&gt;
&lt;li&gt;Zipper data structure is very easy to explore (not a byzantine structure)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Zippers in use:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Luke used them to create a word processor in which each version of the document was stored in a zipper. This made it easy to get to the past state of the document at any point in time.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Christophe Grand - DSLs&amp;#160;!= macros&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://vrac.cgrand.net/DSL.pdf"&gt;slides&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Talk was packed with API design tips based on real-world experience.&lt;/p&gt;

&lt;p&gt;Christophe is the creator of Enlive, Moustache, and Parsely.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Writing DSLs is hard&lt;/li&gt;
&lt;li&gt;Try to use macros&lt;/li&gt;
&lt;li&gt;Now you have two problems!&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Is it a DSL or an API? In a sense every API is a DSL. It is a continuum, but the key attributes of a DSL are:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;succinct notation for data or logic&lt;/li&gt;
&lt;li&gt;usually declarative&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;For his products:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;users complained about macros
** behavior was too surprising
** they were not composable&lt;/li&gt;
&lt;li&gt;users don&amp;#8217;t want a DSL, then want data values&lt;/li&gt;
&lt;li&gt;values + functional-core = DSL success
** values - allow users to define their data values&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;rely on Clojure for lexical scope (avoid creating new scope types via macros) and control flow&lt;/li&gt;
&lt;li&gt;use closures and higher order functions. Don&amp;#8217;t worry if it is ugly. Icing can be added later&lt;/li&gt;
&lt;li&gt;no macros - macros are like premature optimization. They provide too much rope to hang yourself with.&lt;/li&gt;
&lt;li&gt;start with data&lt;/li&gt;
&lt;li&gt;give domain-specific semantics to Clojure&amp;#8217;s datatypes (e.g. vectors, maps, etc.). But don&amp;#8217;t try and give domain-specific meanings to lists or symbols.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;e.g. - Enlive - he removed 1/2 of the macros and the result was a cleaner, faster system.&lt;/p&gt;

&lt;p&gt;Two legitimate cases for macros. But even for these avoid them:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;control flow - instead use closures and delays&lt;/li&gt;
&lt;li&gt;binding - decouple binding via capturing [I don&amp;#8217;t understand this point, but Christophe mentioned he might blog more details about this later.]&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Christophe provided an example of a &lt;a href="http://github.com/cgrand/regex"&gt;DSL for building regexes&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;In the example, the function &amp;#8220;regex&amp;#8221; is like eval for the DSL&lt;/li&gt;
&lt;li&gt;Helper functions in the DSL are like macros in the DSL&lt;/li&gt;
&lt;li&gt;Make the regex function idempotent so it can be called on input and if necessary the input will be &amp;#8220;eval&amp;#8217;d&amp;#8221; to a regex. This is analogous to how the core sequence functions convert their args into sequences.&lt;/li&gt;
&lt;li&gt;Small tip - when the implementation of the DSL is optimizing the input data structure be sure to check vars not symbols to recognize the DSL&amp;#8217;s functions. This avoids colliding with other functions of the same name.  &lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Tom Faulhaber - Flow&lt;/h2&gt;

&lt;p&gt;Flow is the opposite of feeling frustrated and passive. Instead things feel easy and natural.&lt;/p&gt;

&lt;p&gt;Lisp promotes flow:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;homoiconic - computer as a canvas, manipulate the language itself&lt;/li&gt;
&lt;li&gt;symbolic - &amp;#8220;&lt;/li&gt;
&lt;li&gt;REPL - machine becomes a partner&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Functional programming promotes flow:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;immutability&lt;/li&gt;
&lt;li&gt;composition&lt;/li&gt;
&lt;li&gt;horizontal abstractions - [I think this refers to things like sequences which are pervasive in Clojure code.]&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;These allow you to build new abstractions with familiar mechanisms. It is easy to pick up tools from the Clojure toolbox and start manipulating data.&lt;/p&gt;

&lt;p&gt;The focus in on dataflow, not flow-charts.&lt;/p&gt;

&lt;p&gt;Good examples of flow in Clojure embody flow in both their implementation and their use. This means:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;consistent granularity of data&lt;/li&gt;
&lt;li&gt;consistent, comfortable toolset&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Code examples that embody flow:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href="http://infolace.blogspot.com/2009/08/simple-webhooks-with-clojure-and-ring.html"&gt;fill-queue&lt;/a&gt;
** treat asynchronous events like a seq&lt;/li&gt;
&lt;li&gt;enlive
** read the source to see mind blowing code&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Sean Devlin - Protocols&lt;/h2&gt;

&lt;p&gt;Examples of using protocols to get homogeneous behavior on heterogeneous types.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;treating dates, strings, longs, etc. as &amp;#8220;dates&amp;#8221;&lt;/li&gt;
&lt;li&gt;making variants of map, etc. that return the same type of object they accept. So calling map on a String produces a String.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;When to use Protocols over multi-methods:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;for performance&lt;/li&gt;
&lt;li&gt;to get different behavior in different namespaces&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Chouser - Finger Trees&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://github.com/Chouser/talk-finger-tree/blob/master/finger-trees.pdf"&gt;slides&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great talk.&lt;/p&gt;

&lt;p&gt;Implementation of ideas expressed in an academic paper in Haskell code. Finger trees are another persistent collection type that in some cases are more suitable than the built in Clojure types. In particular they are customizable and allow the creation of different kinds of data structures.&lt;/p&gt;

&lt;p&gt;For example, you can build a double-list with finger trees:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;a list you where you can use (first, rest, pop, peek) both ends without losing the type of the structure&lt;/li&gt;
&lt;li&gt;get the count&lt;/li&gt;
&lt;li&gt;lookup items in O(n)&lt;/li&gt;
&lt;li&gt;split/replace/remove/insert in O(log n)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;These are built by defining the &amp;#8220;meter&amp;#8221; to use for the finger-tree. A single meter function is allowed but it can effectively be the composition of several functions. The meter defines how to split the tree and how to access indexed items in the tree.&lt;/p&gt;

&lt;p&gt;The finger tree implementation in Clojure is not finished yet. Still needs to handle metadata and equality.&lt;/p&gt;

&lt;h2&gt;technomancy - Leiningen&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://p.hagelb.org/conj-2010-slides.org.html"&gt;slides&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additional lein features:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;checkouts - like multi-module projects, but ad-hoc and opt-in. You can tell lein to use some files in a local &amp;#8220;checkouts&amp;#8221; sub-directory to satisfy a dependency.&lt;/li&gt;
&lt;li&gt;shell wrappers - [for starting a project-less swank?]&lt;/li&gt;
&lt;li&gt;test selectors - allow conditional test execution - e.g. for tagging long-running integration tests&lt;/li&gt;
&lt;li&gt;tasks - just functions. Use eval-in-project to get JVM isolation between user tasks and lein itself&lt;/li&gt;
&lt;li&gt;hooks - use Robert Hooke to customize tasks that are outside of your control (otherise just use functions to customize it)&lt;/li&gt;
&lt;li&gt;plug-ins - jars that define tasks or include hooks&lt;/li&gt;
&lt;li&gt;lein int - an interactive shell for lein tasks&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Community building:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;identify low-hanging fruit to make it easy for people to contribute&lt;/li&gt;
&lt;li&gt;provide a developer guide&lt;/li&gt;
&lt;li&gt;accept patches promptly&lt;/li&gt;
&lt;li&gt;make commit rights easy to get&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Laurent Petit - Counterclockwise&lt;/h2&gt;

&lt;p&gt;They now have 80% of paredit.&lt;/p&gt;

&lt;h2&gt;Rich Hickey - New Clojure Features&lt;/h2&gt;

&lt;p&gt;Focus of new features is performance, but the results also offer better semantics (!). They are breaking changes. A key to the performance improvements is to produce code that Hotspot will optimize.&lt;/p&gt;

&lt;p&gt;Unified primitives and boxed numbers&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;both act like primitives unless you use bigint operands&lt;/li&gt;
&lt;li&gt;bigints are contagious&lt;/li&gt;
&lt;li&gt;local numbers are represented as either longs or doubles (not shorts or ints)&lt;/li&gt;
&lt;li&gt;+, -, &amp;#8230; are non-promoting operators&lt;/li&gt;
&lt;li&gt;+&amp;#8217;, -&amp;#8216;, &amp;#8230; are promoting operators &amp;lt;- don&amp;#8217;t use these, they are just hear to keep people from whining, instead use contagion (as an aside, &amp;#8217; is now a valid character in identifiers)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Align map key equality with number equality&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;the problem is that if a map key is Long(42) a lookup on Int(42) will fail even though Long(42) is numerically equal to Int(42)&lt;/li&gt;
&lt;li&gt;this has been a nagging problem&lt;/li&gt;
&lt;li&gt;the roots of the problem are in Java. This is how map equality is defined and there is no way to fix the root problem&lt;/li&gt;
&lt;li&gt;the solution is: when maps are accessed via Java they will provide the expected (bad semantics), but when they are accessed via Clojure functions they will make map equality match numerical equality&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Bindings &amp;amp; threads&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;current problem is that bindings only apply to the thread that creates them. So if a thread pool is used somewhere down the call stack (e.g. with pmap) then the bindings are lost.&lt;/li&gt;
&lt;li&gt;vars have root values&lt;/li&gt;
&lt;li&gt;bindings create a mapping from that var (they don&amp;#8217;t change the root binding) to a &amp;#8220;box&amp;#8221;. Using set! the value in the box can be changed. Every time a new binding is executed, a new box is created.&lt;/li&gt;
&lt;li&gt;bindings assume a single-threaded model&lt;/li&gt;
&lt;li&gt;the key to making bindings work across threads is to make the &amp;#8220;boxes&amp;#8221; thread safe&lt;/li&gt;
&lt;li&gt;the solution is: the thread that established the binding can use set! to change the value, all other threads get read-only access to the binding. So sub-threads (i.e. threads enlisted in part of an overall &amp;#8220;task&amp;#8221;) can point to the same binding map as their &amp;#8220;parent&amp;#8221; thread. NOTE: They are not really child threads because typically they are threads from a pool.&lt;/li&gt;
&lt;li&gt;this is intimately related to the &amp;#8220;scopes&amp;#8221; problem in which we would like to create resource scopes (e.g. to close a file, etc) around lazy sequences, in which case the resource needs to be closed in a location far from the lexical scope where the resource is used.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Pay for what you use &amp;amp; dynamic variables&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;the current &amp;#8220;def&amp;#8221; is too powerful because it always creates vars which can be dynamically bound. This is &amp;#8220;unfair&amp;#8221; in that even if this dynamicity is not needed, the user still incurs a performance cost every time the variable is accessed.&lt;/li&gt;
&lt;li&gt;most defs are functions that are not going to be rebound&lt;/li&gt;
&lt;li&gt;every var access incurs some costs to determine if the variable has been dynamically bound&lt;/li&gt;
&lt;li&gt;solution: require the developer to explicitly identify defs that need to be dynamic (stylistically - the names of these variables and functions should include earmuffs, e.g. &lt;em&gt;foo&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Clojure will &amp;#8220;presume stability&amp;#8221;&lt;/li&gt;
&lt;li&gt;but, to accomodate the development-time use-case of redefining functions regularly: at the start of each function invocation a single check will be made against a var-universe-counter to make sure that no vars have been refdefined (any time a var is changed the var-universe-counter will be incremented). For long running functions they should be invoked with #&amp;#8217; to trigger a check of the var-universe-counter.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Functions &amp;amp; primitives&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Currently pulling code out to a function causes the args and return values to be boxed.&lt;/li&gt;
&lt;li&gt;solution: add type hints to the args and return values to indicate primitives. The return value type hint is placed just before the arg vector to accommodate multiple arities.&lt;/li&gt;
&lt;li&gt;future work will handle making higher order functions (e.g. map, reduce) preserve primitive performance.&lt;/li&gt;
&lt;/ul&gt;</description><link>http://david-mcneil.com/post/1393750407</link><guid>http://david-mcneil.com/post/1393750407</guid><pubDate>Sun, 24 Oct 2010 19:48:27 -0500</pubDate><category>clojure</category></item><item><title>Enhanced Clojure records (part 2)</title><description>&lt;p&gt;Following up on my efforts to &lt;a href="http://david-mcneil.com/post/765563763/enhanced-clojure-records"&gt;enhance clojure records&lt;/a&gt; I put the &lt;a href="http://github.com/david-mcneil/defrecord2"&gt;second version of the code on github&lt;/a&gt;. Now record fields are printed in the same order they were defined. I also made it print nil values that are added to the record as long as they are not one of the &amp;#8220;native&amp;#8221; fields in the record.&lt;/p&gt;</description><link>http://david-mcneil.com/post/958196603</link><guid>http://david-mcneil.com/post/958196603</guid><pubDate>Sun, 15 Aug 2010 12:47:00 -0500</pubDate></item><item><title>Ubuntu systray icons missing</title><description>&lt;p&gt;I spent some time today tracking down an issue in which several systray icons disappeared from my Ubuntu system. The solution was to add the Notification Area item back  to the panel.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ubuntuforums.org/showthread.php?t=1072833"&gt;http://ubuntuforums.org/showthread.php?t=1072833&lt;/a&gt;&lt;/p&gt;</description><link>http://david-mcneil.com/post/928736691</link><guid>http://david-mcneil.com/post/928736691</guid><pubDate>Mon, 09 Aug 2010 17:08:27 -0500</pubDate></item><item><title>Enhanced Clojure records</title><description>&lt;p&gt;&lt;a href="http://clojure.org/datatypes"&gt;Clojure records&lt;/a&gt; are a mechanism for creating data abstractions.&lt;/p&gt;

&lt;script src="http://gist.github.com/462582.js"&gt;&lt;/script&gt;&lt;p&gt;Records are instantiated with a list of the field values:&lt;/p&gt;

&lt;script src="http://gist.github.com/462586.js"&gt;&lt;/script&gt;&lt;p&gt;Explicit nils are required to create a record without some field:&lt;/p&gt;

&lt;script src="http://gist.github.com/462587.js"&gt;&lt;/script&gt;&lt;p&gt;Records are immutable, but new ones can be created by mutating an existing record&lt;/p&gt;

&lt;script src="http://gist.github.com/462589.js"&gt;&lt;/script&gt;&lt;p&gt;Multiple fields can be set by merging a map into a record&lt;/p&gt;

&lt;script src="http://gist.github.com/462590.js"&gt;&lt;/script&gt;&lt;p&gt;Notice that records print in a format that cannot be evaluated. Evaluating the printed form throws an exception.&lt;/p&gt;

&lt;script src="http://gist.github.com/462591.js"&gt;&lt;/script&gt;&lt;p&gt;My understanding is that a future Clojure will address some of the current shortcomings with records, but in the meantime&amp;#8230;&lt;/p&gt;

&lt;p&gt;The code below provides a generic mechanism for enhancing records in the following ways:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Generate constructor functions that take maps.&lt;/li&gt;
&lt;li&gt;Print records in a form that can be evaluated.&lt;/li&gt;
&lt;/ul&gt;&lt;script src="http://gist.github.com/462593.js"&gt;&lt;/script&gt;&lt;p&gt;The new defrecord2 macro is invoked like defrecord:&lt;/p&gt;

&lt;script src="http://gist.github.com/462594.js"&gt;&lt;/script&gt;&lt;p&gt;This generates a constructor function that takes a map. Using named parameters is clearer than the positional constructors that are provided by plain records.&lt;/p&gt;

&lt;script src="http://gist.github.com/462595.js"&gt;&lt;/script&gt;&lt;p&gt;It is not necessary to pass nils in for the missing fields.&lt;/p&gt;

&lt;script src="http://gist.github.com/462597.js"&gt;&lt;/script&gt;&lt;p&gt;The enhanced records can be mutated by passing in a map of new values:&lt;/p&gt;

&lt;script src="http://gist.github.com/462598.js"&gt;&lt;/script&gt;&lt;p&gt;And of course the records are now printing in a form that can be evaluated. This works both from print and from pprint:&lt;/p&gt;

&lt;script src="http://gist.github.com/462600.js"&gt;&lt;/script&gt;&lt;p&gt;A final benefit of defrecord2 is that the records can be used without importing the underlying record class. This avoids a bit of &lt;a href="http://tech.puredanger.com/2010/06/30/using-records-from-a-different-namespace-in-clojure/"&gt;import complexity&lt;/a&gt;.&lt;/p&gt;</description><link>http://david-mcneil.com/post/765563763</link><guid>http://david-mcneil.com/post/765563763</guid><pubDate>Sat, 03 Jul 2010 09:11:00 -0500</pubDate><category>clojure</category></item><item><title>Wrapping Clojure in a Java API </title><description>&lt;p&gt;How to wrap some Clojure code in a Java API? Googling on this leads
first to a solution
that involves invoking methods on clojure.lang.RT from Java. This
&lt;em&gt;might&lt;/em&gt; make sense for launching a Clojure program from Java, but it is
strikes me as a crude tool for trying to build an API.&lt;/p&gt;

&lt;h2&gt;Protocols and Datatypes&lt;/h2&gt;

&lt;p&gt;Clojure &lt;a href="http://clojure.org/datatypes"&gt;protocols and datatypes&lt;/a&gt; create
Java interfaces and classes behind the scenes so they are a possible
solution:&lt;/p&gt;

&lt;script src="http://gist.github.com/435812.js"&gt;&lt;/script&gt;&lt;p&gt;An issue I encountered with this approach is that the type hints are
not included in the Java interface.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;javap -classpath target/classes demo.impl.boat.Boat
&lt;/code&gt;&lt;/pre&gt;

&lt;script src="http://gist.github.com/435834.js"&gt;&lt;/script&gt;&lt;p&gt;Even when I provide type hints to define the method arguments and
return values the resulting interface has these all typed as
Objects. So this fails to provide a nice interface for Java apps to
consume.&lt;/p&gt;

&lt;h2&gt;gen-class and gen-interface&lt;/h2&gt;

&lt;p&gt;Clojure provides the gen-class and gen-interface macros to produce
Java classes and interfaces. Typically the gen-class usage is shown
embedded in a namespace definition like this example from the &lt;a href="http://clojure.org/compilation"&gt;Clojure site&lt;/a&gt;:&lt;/p&gt;

&lt;script src="http://gist.github.com/435814.js"&gt;&lt;/script&gt;&lt;p&gt;For my use this feels a bit cumbersome because it&amp;#8217;s most natural
progression would lead to a Clojure file per Java class/interface. I
prefer to avoid that sprawl by invoking gen-class and gen-interface directly.&lt;/p&gt;

&lt;script src="http://gist.github.com/435822.js"&gt;&lt;/script&gt;&lt;p&gt;This gives tight control of the Java classes and interfaces
produced:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Java constructs are not just side effects of a Clojure construct, but rather are directly produced&lt;/li&gt;
&lt;li&gt;definitions are not spread out across files unnecessarily&lt;/li&gt;
&lt;li&gt;namespaces of Clojure files do not need to match the Java packages of the resulting classes/interfaces.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;For example, the resulting interface looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;javap -classpath target/classes demo.api.Store
&lt;/code&gt;&lt;/pre&gt;

&lt;script src="http://gist.github.com/435842.js"&gt;&lt;/script&gt;&lt;p&gt;Overall this is a very satisfying solution. The real beauty of the solution is that a precise Java API is produced without leaving the comfort of Clojure!&lt;/p&gt;

&lt;p&gt;Here is a sample of how the API looks from Java:&lt;/p&gt;

&lt;script src="http://gist.github.com/435825.js"&gt;&lt;/script&gt;&lt;h2&gt;Protocols and Datatypes Revisited&lt;/h2&gt;

&lt;p&gt;The syntax for defining a datatype is nicer than the
magic-coincidental-naming of the gen-class approach. So another viable
choice is to define a datatype that implements a Java interface. This
combines precise control of the Java interface with the nice datatype
syntax.&lt;/p&gt;

&lt;script src="http://gist.github.com/435830.js"&gt;&lt;/script&gt;&lt;h2&gt;Further Investigation&lt;/h2&gt;

&lt;p&gt;As I write this I am asking questions on the Clojure mailing list and
it seems there are more options to explore with definterface and a new
feature, under development, that allows functions to be defined as
static&amp;#8230;&lt;/p&gt;</description><link>http://david-mcneil.com/post/691347818</link><guid>http://david-mcneil.com/post/691347818</guid><pubDate>Sat, 12 Jun 2010 14:41:00 -0500</pubDate><category>clojure</category></item><item><title>"… “ns” and “in-ns” have special evaluation rules.  In general, they..."</title><description>“… “ns” and “in-ns” have special evaluation rules.  In general, they 
don’t work as you’d expect in block expressions such as “do” or “let”. 
If you want to create namespaces programatically, use “create-ns” and 
“intern”.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;&lt;a href="http://stuartsierra.com/"&gt;&lt;a href="http://stuartsierra.com/"&gt;http://stuartsierra.com/&lt;/a&gt;&lt;/a&gt; on &lt;a href="http://groups.google.com/group/clojure"&gt;&lt;a href="http://groups.google.com/group/clojure"&gt;http://groups.google.com/group/clojure&lt;/a&gt;&lt;/a&gt;&lt;/em&gt;</description><link>http://david-mcneil.com/post/561189549</link><guid>http://david-mcneil.com/post/561189549</guid><pubDate>Fri, 30 Apr 2010 11:33:00 -0500</pubDate></item><item><title>Clojure - repeated function application</title><description>&lt;p&gt;In Clojure I was looking for a compact syntax to repeatedly apply the&lt;br/&gt;result of a function to a series of arguments. This led me to explore&lt;br/&gt;various mechanisms:&lt;br/&gt;&lt;br/&gt;&amp;#8221;-&amp;gt;&amp;#8221; threads a value through as the 2nd value in a series of expressions.&lt;br/&gt;&lt;br/&gt;(-&amp;gt; 20 (+ , 1) (* , 2) (/ , 21) (println ,))&lt;br/&gt;;; prints &amp;#8220;2&amp;#8221; (which is ((20+1)*2)/21)&lt;br/&gt;&lt;br/&gt;Clojure treats the &amp;#8220;,&amp;#8221; as whitespace, so that is simply added so the&lt;br/&gt;reader of the code can see where the previous value will be plugged&lt;br/&gt;into each expression. The println call is added to demonstrate that&lt;br/&gt;this macro works not just with mathematical operators, but with any&lt;br/&gt;function call.&lt;br/&gt;&lt;br/&gt;&amp;#8220;&amp;#187;&amp;#8221; similarly threads a value through but does it to the 3rd position&lt;br/&gt;rather than the 2nd.&lt;br/&gt;&lt;br/&gt;(-&amp;#187; 20 (+ 1 ,) (* 2 ,) (/ 168 ,) (println ,))&lt;br/&gt;;; prints &amp;#8220;4&amp;#8221; (which is (168 / ((20+1)*2)))&lt;br/&gt;&lt;br/&gt;&amp;#8220;comp&amp;#8221; composes functions and allows for similar functionality, but&lt;br/&gt;with more power and more syntax:&lt;br/&gt;&lt;br/&gt;((comp #(/ 168&amp;#160;%) #(* 2&amp;#160;%) #(+ 1&amp;#160;%)) 20)&lt;br/&gt;;;=&amp;gt; 4&lt;br/&gt;&lt;br/&gt;Partial functions can be used instead of lambdas:&lt;br/&gt;&lt;br/&gt;((comp (partial / 168) (partial * 2) (partial + 1)) 20)&lt;br/&gt;;;=&amp;gt; 4&lt;br/&gt;&lt;br/&gt;However, none of these accomplish what I want, which is to repeatedly&lt;br/&gt;apply the result of a function to the arguments. For example, for&lt;br/&gt;dealing with functions like this:&lt;br/&gt;&lt;br/&gt;(def foo&lt;br/&gt;   (fn [x]&lt;br/&gt;     (fn [y]&lt;br/&gt;       (fn [z]&lt;br/&gt;         (+ x y z)))))&lt;br/&gt;&lt;br/&gt;I find it best to not tie my head in knots trying to think of a&lt;br/&gt;function that returns a function that returns&amp;#8230; Rather, just think of&lt;br/&gt;it as something which can be applied repeatedly and with each&lt;br/&gt;application fill in the next nested level of arguments:&lt;br/&gt;&lt;br/&gt;(((foo 1) 2) 3)&lt;br/&gt;;;=&amp;gt; 6&lt;br/&gt;&lt;br/&gt;And this is the kind of expression I am trying to simplify. I want a&lt;br/&gt;cleaner syntax for it. The idea is to make a general version of a&lt;br/&gt;function like this:&lt;br/&gt;&lt;br/&gt;(defn apply-repeatedly-v0 [f x y z]&lt;br/&gt; (((f x) y) z))&lt;br/&gt;&lt;br/&gt;(apply-repeatedly-v0 foo 1&amp;#160;2 3)&lt;br/&gt;;;=&amp;gt; 6&lt;br/&gt;&lt;br/&gt;Of course it needs to handle a variable number of arguments:&lt;br/&gt;&lt;br/&gt;(defn apply-repeatedly [f &amp;amp; args]&lt;br/&gt; (loop [f f args args]&lt;br/&gt;  (if (first args)&lt;br/&gt;    (recur (f (first args)) (rest args))&lt;br/&gt;    f)))&lt;br/&gt;&lt;br/&gt;All of the following are equivalent:&lt;br/&gt;&lt;br/&gt;((((apply-repeatedly foo) 1) 2) 3)&lt;br/&gt;(((apply-repeatedly foo 1) 2) 3)&lt;br/&gt;((apply-repeatedly foo 1&amp;#160;2) 3)&lt;br/&gt;(apply-repeatedly foo 1&amp;#160;2 3)&lt;br/&gt;;;=&amp;gt; 6&lt;br/&gt;&lt;br/&gt;For nicer syntax the function can be given a shorter name:&lt;br/&gt;&lt;br/&gt;(defn&amp;#160;&amp;#187; [&amp;amp; args] (apply apply-repeatedly args))&lt;br/&gt;&lt;br/&gt;Repeated applications can be expressed as:&lt;br/&gt;&lt;br/&gt;(&amp;#187; foo 1&amp;#160;2 3)&lt;br/&gt;;;=&amp;gt; 6&lt;br/&gt;&lt;br/&gt;For example, this can be used to express S/K combinator code more&lt;br/&gt;nicely. If K and S are defined as:&lt;br/&gt;&lt;br/&gt;(def K&lt;br/&gt;   (fn [x]&lt;br/&gt;     (fn [y] x )))&lt;br/&gt;&lt;br/&gt;(def S&lt;br/&gt;   (fn [x]&lt;br/&gt;     (fn [y]&lt;br/&gt;       (fn [z]&lt;br/&gt;         ((x z) (y z))))))&lt;br/&gt;&lt;br/&gt;Then instead of writing code like this:&lt;br/&gt;&lt;br/&gt;(((S K) K) 13)&lt;br/&gt;;;=&amp;gt; 13&lt;br/&gt;&lt;br/&gt;Write:&lt;br/&gt;&lt;br/&gt;(&amp;#187; S K K 13)&lt;br/&gt;;;=&amp;gt; 13&lt;br/&gt;&lt;br/&gt;And &amp;#8220;I&amp;#8221; can be defined as:&lt;br/&gt;&lt;br/&gt;(defn I [x] (&amp;#187; S K K x))&lt;br/&gt;&lt;br/&gt;Or in the cleaner, if more obscure, point-free style as:&lt;br/&gt;- Hide quoted text -&lt;br/&gt;(def I (&amp;#187; S K K))&lt;br/&gt;&lt;br/&gt;(I 27)&lt;br/&gt;;;=&amp;gt; 27&lt;/p&gt;</description><link>http://david-mcneil.com/post/461654394</link><guid>http://david-mcneil.com/post/461654394</guid><pubDate>Sun, 21 Mar 2010 15:57:00 -0500</pubDate><category>clojure</category></item><item><title>Clojure - destructuring nested maps</title><description>&lt;p&gt;I was writing a Clojure function that was passed a nested map like this:&lt;/p&gt;
&lt;p&gt;(def input {&amp;#8220;results&amp;#8221;&lt;br/&gt;   {&amp;#8220;data&amp;#8221;&lt;br/&gt;    [{&amp;#8220;x&amp;#8221; { &amp;#8220;value&amp;#8221; 100}&lt;br/&gt;      &amp;#8221;y&amp;#8221; { &amp;#8220;value&amp;#8221; 105}}&lt;br/&gt;     {&amp;#8220;x&amp;#8221; { &amp;#8220;value&amp;#8221; 203}&lt;br/&gt;      &amp;#8221;y&amp;#8221; { &amp;#8220;value&amp;#8221; 219}}&lt;br/&gt;     {&amp;#8220;x&amp;#8221; { &amp;#8220;value&amp;#8221; 345}&lt;br/&gt;      &amp;#8221;y&amp;#8221; { &amp;#8220;value&amp;#8221; 378}}]}})&lt;/p&gt;
&lt;p&gt;I was pleased to write the following, compact code to tease it apart and extract the data:&lt;/p&gt;
&lt;p&gt;(let [{{rows &amp;#8220;data&amp;#8221;} &amp;#8220;results&amp;#8221;} input]&lt;br/&gt;  (for [{x &amp;#8220;x&amp;#8221;&lt;br/&gt;            y &amp;#8220;y&amp;#8221;} rows]&lt;br/&gt;            ((juxt x y) &amp;#8220;value&amp;#8221;)))&lt;/p&gt;
&lt;p&gt;;;=&amp;gt; ([100&amp;#160;105] [203&amp;#160;219] [345&amp;#160;378])&lt;/p&gt;
&lt;p&gt;The first line shows nested map destructuring.&lt;/p&gt;
&lt;p&gt;Then the for loop shows regular map desctructuring.&lt;/p&gt;
&lt;p&gt;Finally the juxt call was used to access the value of each of the fields.&lt;/p&gt;</description><link>http://david-mcneil.com/post/461564364</link><guid>http://david-mcneil.com/post/461564364</guid><pubDate>Sat, 20 Mar 2010 15:02:50 -0500</pubDate><category>clojure</category></item><item><title>Out of the Tarpit : comments</title><description>&lt;p&gt;This &lt;a href="http://technomancy.us/127"&gt;technomancy blog entry&lt;/a&gt; links to a &lt;a href="http://tomfaulhaber.blip.tv/"&gt;video of Rich Hickey&lt;/a&gt; talking at a user conference. It includes the thought provoking quote (taken out of context) along the lines of &amp;#8220;clojure is not bug-free, but it is not bad&amp;#8230; considering it has no tests&amp;#8221;. Rich makes the assertion that his time is better spent thinking about implementing his code correctly rather than writing tests around it. To better understand his position, I followed the &lt;a href="http://technomancy.us/127"&gt;link from technomancy&lt;/a&gt; to the &lt;a href="http://web.mac.com/ben_moseley/frp/paper-v1_01.pdf"&gt;Out of the Tarpit&lt;/a&gt; paper.&lt;/p&gt;
&lt;p&gt;The paper is interesting. It helped clarify my thoughts on managing state and accidental complexity. I particularly appreciated the description of how stateful logic contaminates the functions it is called from. Below are specific points I noted:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Abstract Data Types considered harmful&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;p 52 - Abstract data types are inevitably tailored to a particular purpose. They hinder referential transparency (the attribute of a function in which it only depends on data passed in at the top) because they cause the caller to pass in more data than is really needed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Separate Infrastructure from Application Specification&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Build an infrastructure, then build a specification for the application and execute the specification. A variation on the theme of: build a DSL for problem space, then implement your app in that language.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Essential State&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The only essential state is that state input directly from the user. All other data can be derived from this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Separate state and behavior&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;p 44 - The authors advocate separating the state and behavior of the system (obviously, in direct conflict with one of the core OO tenets).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Power Corrupts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;P 12 - Language power corrupts. An argument for language constraints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Separation Pure Logic from Control&lt;/strong&gt;&lt;br/&gt;P 34 - Separate the pure logic (code with no state) from the &amp;#8220;control&amp;#8221;. One of the motivations for doing this is so that these separate parts of the application can be coded in different languages. The power of the language used for each can be restricted. This facilitates reasoning about the application (e.g. state can be ignored in the &amp;#8220;logic&amp;#8221; portions of the application). This culminates in the diagram on p 35 that shows 3 top-level components of the system.&lt;/p&gt;</description><link>http://david-mcneil.com/post/448771132</link><guid>http://david-mcneil.com/post/448771132</guid><pubDate>Sun, 14 Mar 2010 19:31:00 -0500</pubDate><category>clojure</category></item></channel></rss>

