<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Higher-Order &#187; General</title>
	<atom:link href="http://blog.higher-order.net/category/general/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.higher-order.net</link>
	<description>topics: functional programming, concurrency, web-development, REST, dynamic languages</description>
	<lastBuildDate>Mon, 19 Jul 2010 06:45:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Conj-labs Clojure lessons part i</title>
		<link>http://blog.higher-order.net/2010/07/04/conj-labs-clojure-lessons-part-i/</link>
		<comments>http://blog.higher-order.net/2010/07/04/conj-labs-clojure-lessons-part-i/#comments</comments>
		<pubDate>Sun, 04 Jul 2010 07:43:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[circuit breaker]]></category>
		<category><![CDATA[Clojure]]></category>
		<category><![CDATA[protocols]]></category>

		<guid isPermaLink="false">http://blog.higher-order.net/?p=589</guid>
		<description><![CDATA[I attended the first conj-labs in Brussels, June 23-25. It was three days of intense Clojure learning with Clojure profiles: Christophe Grand and Lau Jensen. I must say it exceeded my expectations! Everyone was great and I really feel it took my Clojure to the next level. This post describes some mistakes I&#8217;ve made in [...]]]></description>
			<content:encoded><![CDATA[<p>I attended the <a href="http://www.conj-labs.eu/">first conj-labs in Brussels, June 23-25</a>. It was three days of intense Clojure learning with Clojure profiles: <a href="http://clj-me.cgrand.net/">Christophe Grand</a> and <a href="http://www.bestinclass.dk/">Lau Jensen</a>. I must say it exceeded my expectations! Everyone was great and I really feel it took my Clojure to the next level.</p>
<p>This post describes some mistakes I&#8217;ve made in the Clojure circuit breaker project, and how I managed to fix them, mostly due to guidance from Christophe. </p>
<p>The following is an (embarrassingly long) list of issues that my <a href="http://blog.higher-order.net/2010/05/05/circuitbreaker-clojure-1-2/">previous version of circuit breaker</a> had. I think others can learn from my mistakes.</p>
<p><strong>Platform speed protocol functions.</strong> In order for a protocol function reaching a datatype to run at platform call-speed, the datatype must inline the protocol implementation. In the old version, I extended the state transitions protocol to the circuit breaker states using (extend &#8230;): this is usually 3-4x times slower than platform-speed method calls (but can be much slower when cache misses). I now inline the protocol extension to the states.</p>
<p>This inlining gave a new problem. I had two data types, say A and B, where A creates an instance of B and B creates an instance of A in the implementation of the inlined protocol functions. You can&#8217;t have this type of &#8220;mutually recursive data types&#8221; since they are compiled on the fly to Java classes. The fix was to&#8230;</p>
<p><strong>Create factory functions for your data types.</strong> There are at least two reasons for this. First a factory function can do processing of its arguments (e.g. pre condition), say for validation. The data type constructors can&#8217;t have any logic. Second, as noted by Alex Miller on his blog: <a href="http://tech.puredanger.com/2010/06/30/using-records-from-a-different-namespace-in-clojure/&#038;">to use data types defined in another namespace you must import them</a>. But you can use require/use to bring the factory functions into your namespace. </p>
<p><strong>I thought I knew: protocols aren&#8217;t interfaces (and Java interop).</strong>. I used a protocol: CircuitBreakerTransitions to model the states. The protocol contains functions needed for state transition on various events. I extended the protocol to my states, e.g., </p>
<pre><code>
(defrecord ClosedState [policy fail-count]
  CircuitBreakerTransitions
  ...)
</code></pre>
<p>It inlines the protocol so the generated class implements the protocol&#8217;s backing interface: It&#8217;s fast and works great. </p>
<p>The problem appeared when I wanted to expose a Java API for the circuit breaker: one of the API methods getCurrentState returns the current state &#8211; now, the question is what is its signature? My first attempt was public CircuitBreakerTransitions getCurrentState(). Now what is wrong?</p>
<p>The problem is that my protocol can be extended to reach other types. Those types may or may not inline the protocol functions, and hence it is possible for the protocol to reach a type which doesn&#8217;t implement the CircuitBreakerTransitions interface&#8230; So should I just return &#8220;Object&#8221; &#8211; that isn&#8217;t really useful. </p>
<p>I haven&#8217;t implemented a solution yet, but this is what I am thinking. Keep the type: CircuitBreakerTransitions getCurrentState(), but in my Java-interop (gen-class), the function that implements getCurrentState should grab the state s from the circuit breaker. Now I know that (satisfies? CircuitBreakerTransitions s) is true, but (instance? (:on-interface CircuitBreakerTransitions) s) may be false. If it is true, I simply return it. Otherwise: reify  CircuitBreakerTransitions by delegating to the protocol functions on s. This may sound a bit wierd at first, but I think of it like creating a new object that satisfies the interface by dynamically dispatching to s.</p>
<p><strong>Type-hits are for removing reflection, not enforcing type safety</strong> My first iteration tried to type-hint the records, e.g.,</p>
<pre><code>
(defrecord ClosedState [^TransitionPolicy policy ^int fail-count])
</code></pre>
<p>This is just plain terrible <img src='http://blog.higher-order.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  First, those hints are ignored (but may be used in later versions of Clojure). Second, int isn&#8217;t suported in the current version of Clojure. Third, TransitionPolicy is a protocol &#8211; and, yes, protocol&#8217;s aren&#8217;t interfaces (see above): problem being again if I supply an object that satisfies the protocol but doesn&#8217;t implement the backing interface. Ugh.<br />
The reason I put the hints wasn&#8217;t to remove reflection, it was for the generated constructor to have types (which is a valid thing to want, but unsupported now). But it is the wrong approach for the reasons above. </p>
<p>The right thing is to remove hints and expose a factory function which checks that the first argument satisfies the TransitionPolicy protocol and that the second argument is non-negative.</p>
<p><strong>Premature optimization</strong>. My circuit breaker implementation tried to optimize a corner-case for the swap! function: suppose you (swap! state f) and f applied to the current state is identically the same state. Then there is no reason to do a compare-and-set!. My transition-by! function implemented this optimization. However, this was a premature optimization that changes the semantics of time (wow, Clojure really is powerful <img src='http://blog.higher-order.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). The fundamental question is this:  [s] -f-> [s] (where s is a state and f is a side-effect free function that advances time), is this transition really advancing time? (it isn&#8217;t observable, is it?&#8230;)</p>
<p>Anyway, I&#8217;ve never benchmarked the code so it was a premature optimization leading to less understandable code. Also, as <a href="http://twitter.com/chopmo">Jacob</a> and I discussed in the plane home: it actually skews the behavior of the circuit breaker to prefer switching states rather than staying in the same state &#8211; something that you may or may-not want.</p>
<p>Finally an off-topic: It is now possible to build the Clojure circuit breaker including AOT compilation of Java interop classes. I ran into a problem with lein where the order of namespaces in :namespaces isn&#8217;t preserved. This is a problem when you are gen-interfacing in one file and gen-class :implements that interface in another.</p>
<p>I&#8217;ve created a very simple patch to lein to preserve the order.</p>
<p><a href="http://blog.higher-order.net/wp-content/uploads/2010/07/0001-don-t-convert-namespaces-aot-to-a-set-as-it-does-n.patch.txt">http://blog.higher-order.net/wp-content/uploads/2010/07/0001-don-t-convert-namespaces-aot-to-a-set-as-it-does-n.patch.txt</a></p>
<p>Phil is applying this patch so it should be out soon. Until then, if you don&#8217;t want to patch lein, there is a step-by-step guide to repl AOT compilation in the <a href="http://github.com/krukow/clojure-circuit-breaker">README</a>.</p>
<p>Those interested can grab the latest code.</p>
<p><a href="http://github.com/krukow/clojure-circuit-breaker">http://github.com/krukow/clojure-circuit-breaker</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.higher-order.net/2010/07/04/conj-labs-clojure-lessons-part-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Is it just me or is this important</title>
		<link>http://blog.higher-order.net/2010/06/16/is-it-just-me-or-is-this-important/</link>
		<comments>http://blog.higher-order.net/2010/06/16/is-it-just-me-or-is-this-important/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 12:22:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.higher-order.net/?p=582</guid>
		<description><![CDATA[for all JVM-based languages http://www.infoq.com/news/2010/06/azul_ori?]]></description>
			<content:encoded><![CDATA[<p>for all JVM-based languages<br />
<a href="http://www.infoq.com/news/2010/06/azul_ori">http://www.infoq.com/news/2010/06/azul_ori</a>?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.higher-order.net/2010/06/16/is-it-just-me-or-is-this-important/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>clj-ds: Clojure&#8217;s persistent data structures for Java</title>
		<link>http://blog.higher-order.net/2010/06/11/clj-ds-clojures-persistent-data-structures-for-java/</link>
		<comments>http://blog.higher-order.net/2010/06/11/clj-ds-clojures-persistent-data-structures-for-java/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 13:45:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[persistent data structures]]></category>

		<guid isPermaLink="false">http://blog.higher-order.net/?p=575</guid>
		<description><![CDATA[One of the appealing features of Clojure is the pervasive use of (efficient!) persistent data structures. (In previous posts I&#8217;ve shed some light on how PersistentHashMap and PersistentVector are implemented, although some of that information is slightly dated now). There are many advantages to programming with persistent data structures (which implies immutability) but that isn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>One of the appealing features of Clojure is the pervasive use of (efficient!) persistent data structures. (In previous posts I&#8217;ve shed some light on how <a href="http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice/">PersistentHashMap</a> and <a href="http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/">PersistentVector</a> are implemented, although some of that information is slightly dated now).</p>
<p>There are many advantages to programming with persistent data structures (which implies immutability) but that isn&#8217;t the topic of this post&#8230; Currently the Clojure data structures are implemented in Java, so in principle they should be usable also outside of Clojure, say from Java.  However, in practice it is inconvenient (see below). </p>
<p>I&#8217;ve created the project clj-ds to make Clojure&#8217;s data structures available in a more practical form to other JVM languages than Clojure. The <a href="http://github.com/krukow/clj-ds/raw/master/README">README</a> file from the <a href="http://github.com/krukow/clj-ds">clj-ds GitHub project</a> explains the motivation:</p>
<p><strong>Advantages of clj-ds when constrained to working with Java</strong> (as opposed to just including clojure.jar)</p>
<p>* Currently the Clojure data structures are implemented in Java. In the future,<br />
all of Clojure will be implemented in Clojure itself (known as &#8220;Clojure-in-Clojure&#8221;).<br />
This has many advantages for Clojure, but when it happens the data structures will<br />
probably be even more intertwined with the rest of the language,<br />
and may be even more inconvenient to use in a Java context.</p>
<p>The clj-ds project will maintain Java versions of the code, and where possible attempt<br />
to &#8220;port&#8221; improvements made in the Clojure versions back into clj-ds. Thus keeping maintained<br />
versions of the Java data structures. </p>
<p>* In the current Clojure version, calling certain methods on PersistentHashMap requires<br />
loading the entire Clojure runtime, including the bootstrap process. This takes about one second.<br />
This means that the first time one of these methods is called, a Java user will experience a<br />
slight delay (and a memory-usage increase). Further, many of the Clojure runtime<br />
Java classes are not needed when only support for persistent data structures<br />
is wanted (e.g., the compiler).</p>
<p>* The clj-ds library is not dependent on the Clojure runtime nor does it run any<br />
Clojure bootstrap process, e.g., the classes that deal with compilation have been removed.<br />
This results in a smaller library, and the mentioned delay does not occur.</p>
<p>* Clojure is a dynamically typed language. Java is statically typed, and supports<br />
&#8216;generics&#8217; from version 5. A Java user would expect generics support from a Java<br />
data structure library, and the Clojure version doesn&#8217;t have this.<br />
clj-ds will support generics.</p>
<p>* Finally, a slight improvement.  Certain of the Clojure data structure methods use Clojure&#8217;s &#8216;seq&#8217; abstraction. In the implementation of the Java &#8216;iterator&#8217; pattern. It is possible, to make<br />
slightly more efficient iterators using a tailor made iterator. clj-ds does this.</p>
<p>Code: <a href="http://github.com/krukow/clj-ds">http://github.com/krukow/clj-ds</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.higher-order.net/2010/06/11/clj-ds-clojures-persistent-data-structures-for-java/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Stomple RC1: Combining WebSockets and Reliable Messaging</title>
		<link>http://blog.higher-order.net/2010/06/01/stomple-rc1-combining-websockets-and-reliable-messaging/</link>
		<comments>http://blog.higher-order.net/2010/06/01/stomple-rc1-combining-websockets-and-reliable-messaging/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 20:30:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.higher-order.net/?p=541</guid>
		<description><![CDATA[I&#8217;ve finished Release Candidate 1 for Stomple, my JavaScript Stomp library which uses WebSockets to access compatible Stomp Message Brokers (which includes JMS providers via StompConnect). Stomple is heavily inspired by Jeff Mesnil&#8217;s great stomp-websocket, but aims to be feature complete and to provide a high-level API which is more customizable, robust and easy to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve finished <a href="http://github.com/krukow/stomple">Release Candidate 1 for Stomple</a>, my JavaScript <a href="http://stomp.codehaus.org/Protocol">Stomp</a> library which uses WebSockets to access compatible Stomp Message Brokers (which includes JMS providers via <a href="http://stomp.codehaus.org/StompConnect">StompConnect</a>). Stomple is heavily inspired by Jeff Mesnil&#8217;s great <a href="http://jmesnil.net/stomp-websocket/doc/">stomp-websocket</a>, but aims to be feature complete and to provide a high-level API which is more customizable, robust and easy to use. </p>
<p><strong>What</strong>? From the <a href="http://stomp.codehaus.org/Home">Stomp website</a>:<br />
<blockquote>Stomp provides an interoperable wire format so that any of the available Stomp Clients can communicate with any Stomp Message Broker to provide easy and widespread messaging interop among languages, platforms and brokers.</p></blockquote>
<p>As mentioned, this includes JMS. Stomple is a JavaScript library which enables using browsers that support WebSockets as messaging clients, e.g., subscribing to an JMS topic in a JavaScript program running inside Chrome. </p>
<p>Websocket communication has less overhead than HTTP when HTTP semantics aren&#8217;t needed. More importantly, WebSockets allow the <em>server</em> to push updates to the browser (as opposed to the usual HTTP request-response paradigm). For a simple example, see the <a href="http://screencast.com/t/NzdmMGJj">screen cast of the &#8220;transactional chat example&#8221;</a> where chat messages are pushed from the server to participating clients.</p>
<p><strong>Why</strong> release Stomple when there is already stomp-websocket? First of all, Jeff did an excellent job with stomp-websocket. However, I wanted additional features and more production maturity (e.g., support for timeouts, various low- and high-level callbacks and automatic receipts). </p>
<p><strong>A few notable features:</strong></p>
<ul>
<li>Customizability and Callbacks. A key value of Stomple is that it shouldn&#8217;t cut off access to any low-level functionality. Hence everything is customizable and accessible to the user code. All core functions support success and failure callbacks. Further, there are low-level callbacks: <tt>socketOpen, socketMessage, socketClose, socketError</tt> corresponding to the low-level websocket events. These can be used to customize behaviour for special use-cases. At a higher-level, there are callbacks <tt>onConnect, connectFailed, onError, onReceipt</tt> correspoding to the Stomp events.</li>
<li>Automatic receipts. If  <tt>client.autoReceipt</tt> is true (which it is by default), then all Stomp messages sent to the server include an automatically generated &#8216;receipt&#8217; header. In the Stomp protocol, this causes the server to send a receipt for each message it receives, hence reassuring that the message has been received. If not enabled, the client can&#8217;t be sure the message is actually received. </li>
<li>Timeouts. By default all messages sent to the server are associated with a (configurable) 8 second timeout. So for example, suppose you subscribe to a destination, but do not receive a server receipt within 8 seconds: then your failure callback is called with reason &#8216;timeout&#8217; and information about the message that failed. This way you are guaranteed that either your success or failure callback will always be called (but not both <img src='http://blog.higher-order.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). These time-outs are pervasive and configurable per API call.</li>
<li>Transaction management. In Stomp, transactions are started using the &#8216;BEGIN&#8217; frame, corresponding to a begin function in Stomple. When you call begin, you don&#8217;t have to specify a transaction-id: if you don&#8217;t, one will be generated automatically for you. Further, any API calls made between a begin and a commit/abort automatically use this transaction identifier, hence grouping the calls in the same transaction (unless, of course, you explicitly provide a different or no transaction id). Further, this nests arbitrarily, and works in a stack-like manner (e.g., begin, begin, send, associates send with inner-most begin). </li>
<li>Feature complete. Stomple aims to be feature complete. For example, it supports the recommended Stomp &#8216;content-length&#8217; header, where the current stomp-websocket version does not.</li>
<li>Correctness. Stomple is tested manually and has a growing automatic test-suite written in YUI3-test. Stomple passes JSLint.</li>
</ul>
<p>I decided not to build on Jeff&#8217;s library because when APIs become more complex, I prefer using configuration-objects since it makes code more readable and easy to maintain (most Stomple functions take a single object literal parameter which names the function&#8217;s &#8220;many arguments&#8221;).<br />
For example to create a Stomple client and to configure it to use destination &#8216;jms.topic.chat&#8217; as default use:</p>
<pre><tt><span class="keyword">var</span><span class="normal"> client </span><span class="symbol">=</span><span class="normal"> Stomple</span><span class="symbol">.</span><span class="function">create_client</span><span class="symbol">(</span><span class="cbracket">{</span>
<span class="normal">    url </span><span class="symbol">:</span><span class="normal"> </span><span class="string">"ws://localhost:61614/stomp"</span><span class="symbol">,</span>
<span class="normal">    destination </span><span class="symbol">:</span><span class="normal"> </span><span class="string">"jms.topic.chat"</span><span class="symbol">,</span>
<span class="normal">    login </span><span class="symbol">:</span><span class="normal"> </span><span class="string">"guest"</span><span class="symbol">,</span>
<span class="normal">    passcode </span><span class="symbol">:</span><span class="normal"> </span><span class="string">"guest"</span>
<span class="cbracket">}</span><span class="symbol">);</span>
</tt></pre>
<p>A different example of using single-argument configuration objects would be subscribe:</p>
<pre><tt><span class="normal">client</span><span class="symbol">.</span><span class="function">subscribe</span><span class="symbol">(</span><span class="cbracket">{</span>
<span class="normal">    success</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">(</span><span class="normal">frame</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span><span class="comment">//called if subscribe succeeds within timeout-period</span>
<span class="normal">        </span><span class="comment">//subscribe succeeded... do something</span>
<span class="normal">    </span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">    failure</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">(</span><span class="normal">spec</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span><span class="comment">//called if subscribe fails or times out</span>
<span class="normal">        console</span><span class="symbol">.</span><span class="function">log</span><span class="symbol">(</span><span class="normal">spec</span><span class="symbol">.</span><span class="normal">reason</span><span class="symbol">);</span>
<span class="normal">    </span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">    handler</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">(</span><span class="normal">msg</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span><span class="comment">//called when a message arrived ('this' is scope - see below) </span>
<span class="normal">        </span><span class="keyword">this</span><span class="symbol">.</span><span class="normal">received </span><span class="symbol">=</span><span class="normal"> msg</span><span class="symbol">.</span><span class="normal">body</span><span class="symbol">;</span><span class="comment">//"this" is "someObject"</span>
<span class="normal">    </span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">    scope</span><span class="symbol">:</span><span class="normal"> someObject</span>
<span class="cbracket">}</span><span class="symbol">);</span></tt></pre>
<p>Note by the way that if <tt>client.autoConnect</tt> is true (which it is by default), then you don&#8217;t have to explicitly connect. Stomple will automatically connect upon your first action. The subscribe function supports an optional destination parameter in-case a default wasn&#8217;t supplied when the client object was created (or in case you want to subscribe to a non-default destination). </p>
<p><strong>How</strong>?<br />
For each Stomp client frame  (command): SEND, SUBSCRIBE, UNSUBSCRIBE, BEGIN, COMMIT, ABORT,  ACK, DISCONNECT there are  corresponding lower-case functions on the client object, e.g., send, subscribe&#8230; Defaults are specified when creating the client object. For example.</p>
<pre><tt><span class="keyword">var</span><span class="normal"> client </span><span class="symbol">=</span><span class="normal"> Stomple</span><span class="symbol">.</span><span class="function">create_client</span><span class="symbol">(</span><span class="cbracket">{</span>
<span class="normal">    url </span><span class="symbol">:</span><span class="normal"> </span><span class="string">"ws://localhost:61614/stomp"</span><span class="symbol">,</span>
<span class="normal">    destination </span><span class="symbol">:</span><span class="normal"> </span><span class="string">"jms.topic.chat"</span><span class="symbol">,</span>
<span class="normal">    login </span><span class="symbol">:</span><span class="normal"> </span><span class="string">"guest"</span><span class="symbol">,</span>
<span class="normal">    passcode </span><span class="symbol">:</span><span class="normal"> </span><span class="string">"guest"</span><span class="symbol">,</span>
<span class="normal">    autoConnect</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">true</span><span class="symbol">,</span><span class="comment">//which is actually the default</span>
<span class="normal">    timeout</span><span class="symbol">:</span><span class="normal"> </span><span class="number">3000</span><span class="symbol">,</span>
<span class="normal">    autoReceipt</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">true</span><span class="comment">//which is actually the default</span>
<span class="normal">    </span><span class="comment">//...</span>
<span class="cbracket">}</span><span class="symbol">);</span>
</tt></pre>
<p>See Stomple.ClientPrototype for all overrides.</p>
<p>Once a client object is created, the user can issue commands. For example, in the chat example a typical sequence would be.</p>
<pre><tt><span class="normal">client</span><span class="symbol">.</span><span class="function">subscribe</span><span class="symbol">(</span><span class="cbracket">{</span>
<span class="normal">    handler </span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">(</span><span class="normal">msg</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span><span class="comment">//update screen on chat msg receiption</span>
<span class="normal">	    </span><span class="keyword">var</span><span class="normal"> c </span><span class="symbol">=</span><span class="normal"> document</span><span class="symbol">.</span><span class="function">getElementById</span><span class="symbol">(</span><span class="string">'content'</span><span class="symbol">);</span>
<span class="normal">	    c</span><span class="symbol">.</span><span class="normal">innerHTML </span><span class="symbol">=</span><span class="normal"> c</span><span class="symbol">.</span><span class="normal">innerHTML </span><span class="symbol">+</span><span class="normal"> </span><span class="string">'&lt;br&gt;'</span><span class="normal"> </span><span class="symbol">+</span><span class="normal"> msg</span><span class="symbol">.</span><span class="normal">body</span><span class="symbol">;</span>
<span class="normal">	</span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">	scope </span><span class="symbol">:</span><span class="normal"> anObjectIfNeeded</span><span class="symbol">,</span>
<span class="normal">	success </span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span><span class="comment">// did subscription succeed?</span>
<span class="normal">        </span><span class="comment">//send a test message</span>
<span class="normal">        client</span><span class="symbol">.</span><span class="function">send</span><span class="symbol">(</span><span class="cbracket">{</span>
<span class="normal">            body</span><span class="symbol">:</span><span class="normal"> </span><span class="string">"User krukow joined chatroom #stomple"</span><span class="symbol">,</span>
<span class="normal">            success</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">              console</span><span class="symbol">.</span><span class="function">log</span><span class="symbol">(</span><span class="string">"sent welcome message..."</span><span class="symbol">);</span><span class="normal">          </span>
<span class="normal">            </span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">            failure</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">              console</span><span class="symbol">.</span><span class="function">log</span><span class="symbol">(</span><span class="string">"Failed..."</span><span class="symbol">);</span>
<span class="normal">            </span><span class="cbracket">}</span>
<span class="normal">            </span>
<span class="normal">        </span><span class="cbracket">}</span><span class="symbol">);</span>
<span class="normal">	</span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">	failure </span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span><span class="comment">// did subscription fail?</span>
<span class="normal">		console</span><span class="symbol">.</span><span class="function">log</span><span class="symbol">(</span><span class="string">"sub fail"</span><span class="symbol">);</span>
<span class="normal">	</span><span class="cbracket">}</span>
<span class="cbracket">}</span><span class="symbol">);</span></tt></pre>
<p>Things are pretty straightforward from here (if you get Stomp <img src='http://blog.higher-order.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). For more advanced examples see the automated test-suite. Here is an example of a transaction.</p>
<pre><tt><span class="keyword">this</span><span class="symbol">.</span><span class="normal">client</span><span class="symbol">.</span><span class="function">begin</span><span class="symbol">(</span><span class="cbracket">{</span>
<span class="normal">    failure</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">        Y</span><span class="symbol">.</span><span class="normal">Assert</span><span class="symbol">.</span><span class="function">fail</span><span class="symbol">(</span><span class="string">"Begin transaction failed."</span><span class="symbol">);</span>
<span class="normal">    </span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">    success</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span><span class="normal"> </span>
<span class="normal">		</span><span class="keyword">for</span><span class="normal"> </span><span class="symbol">(</span><span class="normal">i</span><span class="symbol">=</span><span class="number">0</span><span class="symbol">;</span><span class="normal">i</span><span class="symbol">&lt;</span><span class="normal">N</span><span class="symbol">;</span><span class="normal">i</span><span class="symbol">+=</span><span class="number">1</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">			</span><span class="keyword">this</span><span class="symbol">.</span><span class="normal">client</span><span class="symbol">.</span><span class="function">send</span><span class="symbol">(</span><span class="cbracket">{</span>
<span class="normal">				body</span><span class="symbol">:</span><span class="normal"> </span><span class="string">""</span><span class="symbol">+</span><span class="normal">msgBodies</span><span class="symbol">[</span><span class="normal">i</span><span class="symbol">],</span>
<span class="normal">				failure</span><span class="symbol">:</span><span class="normal"> sendFailed</span>
<span class="normal">                </span><span class="comment">//we don't wait for receipts here... Socket provies order..</span>
<span class="normal">			</span><span class="cbracket">}</span><span class="symbol">);</span>
<span class="normal">		</span><span class="cbracket">}</span>
<span class="normal">        </span><span class="keyword">this</span><span class="symbol">.</span><span class="normal">client</span><span class="symbol">.</span><span class="function">commit</span><span class="symbol">(</span><span class="cbracket">{</span>
<span class="normal">            failure</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal">                Y</span><span class="symbol">.</span><span class="normal">Assert</span><span class="symbol">.</span><span class="function">fail</span><span class="symbol">(</span><span class="string">"Commit transaction failed."</span><span class="symbol">);</span>
<span class="normal">            </span><span class="cbracket">}</span><span class="symbol">,</span>
<span class="normal">            success</span><span class="symbol">:</span><span class="normal"> </span><span class="keyword">function</span><span class="symbol">()</span><span class="cbracket">{</span><span class="comment">//...</span>
<span class="normal">            </span><span class="cbracket">}</span>
<span class="normal">        </span><span class="cbracket">}</span><span class="symbol">);</span>
<span class="normal">    </span><span class="cbracket">}</span>
<span class="cbracket">}</span><span class="symbol">);</span></tt></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.higher-order.net/2010/06/01/stomple-rc1-combining-websockets-and-reliable-messaging/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>My son</title>
		<link>http://blog.higher-order.net/2010/05/24/my-son/</link>
		<comments>http://blog.higher-order.net/2010/05/24/my-son/#comments</comments>
		<pubDate>Mon, 24 May 2010 09:32:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.higher-order.net/2010/05/24/my-son/</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.higher-order.net/wp-content/uploads/2010/05/Frej_og_Far.jpg"><img src="http://blog.higher-order.net/wp-content/uploads/2010/05/Frej_og_Far.jpg" alt="My son and I" title="My son and I" width="768" height="1024" class="alignright size-full wp-image-524" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.higher-order.net/2010/05/24/my-son/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stomple: JMS via WebSockets</title>
		<link>http://blog.higher-order.net/2010/05/09/stomple-jms-via-websockets/</link>
		<comments>http://blog.higher-order.net/2010/05/09/stomple-jms-via-websockets/#comments</comments>
		<pubDate>Sun, 09 May 2010 20:22:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.higher-order.net/?p=507</guid>
		<description><![CDATA[I&#8217;ve spent a couple of days working on Stomple (pronounced &#8220;stumble&#8221;). Stomple aims to be an easy to use, full-featured and robust Stomp client for JavaScript. You can watch a screencast of the transactional chat example. Screencast of transactional chat. What is Stomp? Stomp provides an interoperable wire format so that any of the available [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve spent a couple of days working on <a href="http://github.com/krukow/stomple">Stomple</a> (pronounced &#8220;stumble&#8221;). Stomple aims to be an easy to use, full-featured and robust <a href="http://stomp.codehaus.org/Protocol">Stomp</a> client for JavaScript. </p>
<p>You can watch a screencast of the transactional chat example.<br />
<a href="http://screencast.com/t/NzdmMGJj">Screencast of transactional chat</a>.</p>
<p><strong>What is Stomp?</strong> Stomp provides an interoperable wire format so that any of the available Stomp Clients can communicate with any Stomp Message Broker to provide easy and widespread messaging interop among languages, platforms and brokers. </p>
<p>You can use any of the Stomp Clients to work with any JMS compliant message broker, for example <a href="http://www.jboss.org/hornetq">HornetQ</a>. There are <a href="http://stomp.codehaus.org/Clients">Stomp clients for many languages</a>, and Stomple adds JavaScript via WebSockets. This means that you can send and receive JMS messages directly in the browser (when it supports WebSockets). </p>
<p>Stomple is inspired by <a href="http://www.jmesnil.net/stomp-websocket/doc/">Jeff Mesnil&#8217;s cool stomp-websocket</a>, but I wanted more customization, feature-detection, a nicer API, and more robustness (e.g. timeouts) (and I wanted to write it myself <img src='http://blog.higher-order.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ). Just like Jeff&#8217;s client, Stomple is not directly a Stomp client since it runs over WebSockets which requires a handshake between the browser&#8217;s client and the server. This is supported by HornetQ and ActiveMQ (details in Jeff&#8217;s docs:  <a href="http://www.jmesnil.net/stomp-websocket/doc/">http://www.jmesnil.net/stomp-websocket/doc/</a>).</p>
<blockquote><p>This library is not a pure Stomp client. It is aimed to run on the Web Sockets protocol which is not TCP. Basically, the Web Sockets protocol requires a handshake  between the browser client and the server to ensure the browser&#8217;s &#8220;same-origin&#8221; security model remains in effect.</p>
<p>This means that this library can not connect to regular Stomp brokers since they would not understand the handshake initiated by the Web Socket which is not part of the Stomp protocol and would likely reject the connection.</p></blockquote>
<p>I&#8217;ll post more documentation soon, but stomple should be quite simple to use.</p>
<pre><tt>
if (Stomple) {//feature detection: is stomple available?
    Stomple.debug = true;//enable debug logging of messages
    var client = Stomple.create_client({
        url: "ws://localhost:61614/stomp",
        destination: "jms.topic.chat",
        login: "guest",
        passcode: "guest"
    });
    client.subscribe({
        handler: function(f) {
            console.log('received frame');
            console.log(f);
            console.log("Message: "+f.body);
            console.log("'this' is bound to 'scope'");
            console.log("Session:"+this.session);
            client.send({
                success: function() {},//handle successful send
                failure: function() {},//handle failed send
                timeout: 5000//wait max 5 seconds before failing
            });
        },
        scope: client,
        success: function() {//did subscription succeed?
            console.log("sub ok..");
        },
        failure: function() {//did subscription fail?
            console.log("sub fail");
        }
    });
} </tt></pre>
<p>Check it out on Github: <a href="http://github.com/krukow/stomple">http://github.com/krukow/stomple</a>.</p>
<p>More info to come <img src='http://blog.higher-order.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.higher-order.net/2010/05/09/stomple-jms-via-websockets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clojure: Rich Hickey and Stuart Halloway at JAOO</title>
		<link>http://blog.higher-order.net/2010/03/25/clojure-rich-hickey-and-stuart-halloway-at-jaoo/</link>
		<comments>http://blog.higher-order.net/2010/03/25/clojure-rich-hickey-and-stuart-halloway-at-jaoo/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 18:44:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.higher-order.net/?p=468</guid>
		<description><![CDATA[See Danish Clojure Users Group posting.]]></description>
			<content:encoded><![CDATA[<p>See <a href="http://clojure.higher-order.net/2010/03/rich-hickey-and-stuart-halloway-in-denmark/">Danish Clojure Users Group posting</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.higher-order.net/2010/03/25/clojure-rich-hickey-and-stuart-halloway-at-jaoo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VersionManager</title>
		<link>http://blog.higher-order.net/2010/01/22/version-manager/</link>
		<comments>http://blog.higher-order.net/2010/01/22/version-manager/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 15:10:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[namespacing]]></category>
		<category><![CDATA[with]]></category>

		<guid isPermaLink="false">http://blog.higher-order.net/?p=450</guid>
		<description><![CDATA[[update: First, my apologies to jdalton, my post was not meant to derail Fusebox, merely to show a different approach to similar problems. ] I read a post on Ajaxian about Fusebox, a JavaScript library which is described as: [...] The problem is that frameworks / libraries / third-party scripts may overwrite native methods or [...]]]></description>
			<content:encoded><![CDATA[<p>[update: First, my apologies to jdalton, my post was not meant to derail Fusebox, merely to show a different approach to similar problems. ]</p>
<p>I read a <a href="http://ajaxian.com/archives/de-fusing-javascript-natives-with-the-fusebox">post on Ajaxian</a> about <a href="http://github.com/jdalton/fusebox">Fusebox</a>, a JavaScript library which is described as:</p>
<blockquote><p>[...] The problem is that frameworks / libraries / third-party scripts may overwrite native methods or each other&#8217;s custom methods resulting in unpredictable outcomes. Fusebox, a limited version of the sandboxing component found in FuseJS, avoids these issues by creating sandboxed natives which can be extended without affecting the document natives.</p></blockquote>
<p>I think Fusebox is a good project. The code in this blog post shows a different approach which in some situations may be more useful and in others, it may not.</p>
<p>With Fusebox script developers avoid polluting the globals by writing their scripts using FuseBox and its wrappers. E.g, you write code with a &#8220;Fusebox prefix&#8221; like this:<br />
<code>
<pre>
  var fb = Fusebox();
  fb.Array.prototype.hai = function() {
    return fb.String("Oh hai, we have " + this.length + " items.");
  };
  fb.Array(1,2,3).hai(); // "Oh hai, we have 3 items."
  typeof window.Array.prototype.hai; // undefined

// like the native Array constructor the sandboxed constructor will return [ , , ]
  var a = fb.Array(3);
  // equiv to square-bracket notation [3]
  var b = fb.Array.create(3);
  // converting a native array to a sandboxed array
  var c = fb.Array.fromArray([1, 2, 3]);
</pre>
<p></code></p>
<p>That immediately reminded be of some work I&#8217;ve have been doing with colleague Jimmy Junker at Trifork (<tt>jju at trifork com</tt>) motivated by the following problem:</p>
<blockquote><p> In portal environments where multiple portlets want to use different JavaScript libraries or different versions of the same JavaScript libraries, you are very likely to run in to problems since almost all libraries (except later YUI versions) are designed to live in the global namespace.</p></blockquote>
<p>After a brainstorming session we developed a simple <em>prototype</em> (no pun intended), uninspiringly named &#8220;VersionManager&#8221;, with which we succeeded in loading two different versions of the PrototypeJS library. With VersionManager you can write code like this:<br />
<code>
<pre>
with (VersionManager.version("1.6.1")) {
//"1.6.1" refers to prototype which must have been loaded
  console.log("abcdaba".gsub("a","42"));// console.logs '42bcd42b42'
  console.log(typeof Object.extend);// console.logs 'function'
  $A([1,2,3])._each(function(x){
    console.log(x);
  });// console.logs '1','2','3'
}
VersionManager.clear();//otherwise previous version is lingering...
try {
  console.log(typeof "".gsub);
//console.logs 'function' <= this is generic delegating proxy function
  console.log("abcdaba".gsub("a","42"));//throws error
} catch (e) {
  console.log(e);
  //TypeError: "attempt call to delegate with no version defined (see documentation)"
}
console.log(typeof Object.extend);// console.logs 'undefined'
console.log(typeof $A);// console.logs 'undefined'
</pre>
<p></code></p>
<p>So version manager lets you load several libraries on the page, and sandboxes changes made to globals. By telling VersionManager which version you want to use for a particular block you code, you can use each of those libraries, <em>even if they define the same global variables or properties on the prototypes of objects,</em> e.g., <tt>Array.prototype</tt>. </p>
<p> VersionManager also creates sandboxes, but as opposed to Fusebox, what is sandboxed is "changes made to" the built-ins, and global variables defined. Also, the goal is not to avoid extending the prototypes, but almost the opposite: to allow several scripts/libraries that would otherwise conflict to live in the same page without seeing each other, even if they define the same global names or want to extend built-in prototypes in different ways.</p>
<p>With VersionManager you simply write regular user code, but wrap it in a with statement. This means that existing code can easily be rewritten.</p>
<p>The loaded "sandboxed" libraries must adhere to a few syntactic and semantic constraints.<br />
For an example, see a sandboxed version of prototypejs here</p>
<p><a href="http://github.com/krukow/versionmanager/blob/master/test/assets/prototype.js">Transformed prototypejs</a></p>
<p>The transformation applied to prototypejs is very simple and can be done automatically (i.e., it is easy to write a program that performs this script-transformation for you). It is a bit technical, but it results in is adding a declaration with-statement "header" at the beginning and a "footer" and the end. In fact, we are writing a program that transforms any JavaScript program/library into an equivalent one that adheres to these constraints. </p>
<p>An alpha version is on github. It is a proof-of-concept that shows that the fundamental approach seems to work. </p>
<p>jdalton pointed out a couple of things :</p>
<ul>
<li>You may run into problems with minifiers given that your code is wrapped in 'with'. However, you can minify the code first, and then wrap it.</li>
<li>It doesn't track changes to event or elements.</li>
</ul>
<p>So far, we've tested it only in latest Firefox and Safari, but I see no reason why it couldn't work in other recent browsers.  We have sucessfully loaded prototypejs in a sandbox, and managed to run all prototypejs unit tests successfully inside the sandbox.</p>
<p>Github project: <a href="http://github.com/krukow/versionmanager">http://github.com/krukow/versionmanager</a></p>
<p>/Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.higher-order.net/2010/01/22/version-manager/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Joy of Clojure</title>
		<link>http://blog.higher-order.net/2010/01/14/the-joy-of-clojure/</link>
		<comments>http://blog.higher-order.net/2010/01/14/the-joy-of-clojure/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 10:54:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.higher-order.net/?p=444</guid>
		<description><![CDATA[In case you haven&#8217;t noticed there is a very interesting Clojure book coming out, titled &#8220;The Joy of Clojure,&#8221; written by two very interesting authors that anyone hanging out in the Clojure community should know: Chris Houser and Michael Fogus. As an appetizer, the first chapter is available for free: Clojure—A Lisp for the Java [...]]]></description>
			<content:encoded><![CDATA[<p>In case you haven&#8217;t noticed there is a very interesting Clojure book coming out, titled &#8220;<a href="http://www.manning.com/fogus/">The Joy of Clojure</a>,&#8221;  written by two very interesting authors that anyone hanging out in the Clojure community should know: <a href="http://twitter.com/chrishouser">Chris Houser</a> and <a href="http://twitter.com/fogus">Michael Fogus</a>. </p>
<p>As an appetizer, the first chapter is available for free:</p>
<p><a href="http://www.manning.com/fogus/Fogus_MEAP_Ch1.pdf">Clojure—A Lisp for the Java Virtual Machine</a></p>
<p>I&#8217;ve read the first chapter and the book looks very promising! To quote the last paragraph of chapter one:</p>
<blockquote><p>We&#8217;ve talked a little about how this book will go beyond what Clojure is to why it&#8217;s designed the way it is and how that design can be exploited through idioms that will help you think in Clojure. So lets stop talking about what this book will do and get on with the doing.<br />
Fasten your seat belts.</p></blockquote>
<p>I&#8217;ve fastened my seat belt and ordered my copy <img src='http://blog.higher-order.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.higher-order.net/2010/01/14/the-joy-of-clojure/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Please help funding Clojure</title>
		<link>http://blog.higher-order.net/2009/12/15/please-help-funding-clojure/</link>
		<comments>http://blog.higher-order.net/2009/12/15/please-help-funding-clojure/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 05:32:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.higher-order.net/?p=439</guid>
		<description><![CDATA[Rich Hickey, creator of Clojure: As should be obvious, Clojure is a labor of love on my part. Started as a self-funded sabbatical project, Clojure has come to occupy me far more than full-time. However, Clojure does not have institutional or corporate sponsorship, and was not, and is not, the by-product of another profitable endeavor. [...]]]></description>
			<content:encoded><![CDATA[<p>Rich Hickey, creator of Clojure:</p>
<blockquote><p>As should be obvious, Clojure is a labor of love on my part. Started as a self-funded sabbatical project, Clojure has come to occupy me far more than full-time. However, Clojure does not have institutional or<br />
corporate sponsorship, and was not, and is not, the by-product of<br />
another profitable endeavor. I have borne the costs of developing<br />
Clojure myself, but 2009 is the last year I, or my family, can bear<br />
that. </p></blockquote>
<p>I would be such a shame if development were to slow down or stop completely because of such a small amount of money&#8230; So, please donate to the project. </p>
<p>See details,</p>
<p><a href="http://groups.google.com/group/clojure/t/cc77df25e98ce46b">http://groups.google.com/group/clojure/t/cc77df25e98ce46b</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.higher-order.net/2009/12/15/please-help-funding-clojure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
