<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8337447265046837037</id><updated>2024-09-08T08:29:16.234-07:00</updated><category term="clojure def"/><category term="Clojure var"/><category term="assoc-in"/><category term="clojure update-in"/><category term="clojure.main"/><category term="def"/><category term="destructuring bind"/><category term="embedded REPL"/><category term="enclojure"/><category term="frequency table"/><category term="in-place editing"/><category term="inner item"/><category term="interactive application"/><category term="let"/><category term="redefining function"/><category term="remote REPL"/><category term="sequences"/><category term="update-in"/><category term="worker function"/><title type='text'>Clojure 101</title><subtitle type='html'>Clojure adds functional programming to the popular JVM environment. I had always liked C++/C# over Java, thus did not exploit the full potential of the JVM world. Clojure has enabled me to use the vast extensive Java libraries in my real-world applications.  I will be dropping any reusable clojure snippets here as I come across them.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://clojure101.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://clojure101.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Narayan Singhal</name><uri>http://www.blogger.com/profile/11122589411879568472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV_36PGONrhlY5RbHij4dAFmCwpmGXdyCojg3vMN8J5OkRHXzEgFP4bbhgMC7Rh5hDHuod98E_pk09T2OkMr6RJ4Qrn_STPJ0SGdKO1jVnAYhYPjd7FQC29k0SWTR-Rw/s1600-r/ns01c_65x100_l_10x.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8337447265046837037.post-1116112634368545826</id><published>2009-05-21T08:07:00.001-07:00</published><updated>2009-05-22T06:54:27.084-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="clojure.main"/><category scheme="http://www.blogger.com/atom/ns#" term="embedded REPL"/><category scheme="http://www.blogger.com/atom/ns#" term="enclojure"/><category scheme="http://www.blogger.com/atom/ns#" term="interactive application"/><category scheme="http://www.blogger.com/atom/ns#" term="remote REPL"/><title type='text'>Embedding a Clojure REPL in your production application</title><content type='html'>You can create an interactive production application by embedding a Clojure REPL in your application. This can help you inspect and interrogate the running application for runtime status, allow you to make bug fixes and monitor running code.&lt;div&gt;&lt;br /&gt;&lt;div&gt;When working on the open source project &lt;a href=&quot;http://code.google.com/p/enclojure-clojure-lib/&quot;&gt;enclojure-clojure-lib&lt;/a&gt;, we created a org.enclojure.repl library which have all the necessary server and client functions for creating a socket based clojure.main/repl in your application.&lt;br /&gt;&lt;br /&gt;You can add the following code in your application which starts a socket REPL at the speicified port and wait for a connection.&lt;br /&gt;&lt;br /&gt;;Use specified socket&lt;br /&gt;(def server-socket (org.enclojure.repl.main/run-repl-server 11345))&lt;br /&gt;&lt;br /&gt;;Use next available socket port&lt;br /&gt;(def server-socket (org.enclojure.repl.main/run-repl-server 0))&lt;br /&gt;(def server-port (.getLocalPort server-socket))&lt;br /&gt;&lt;br /&gt;You can have your monitoring application - connect to the remote REPL as follows:&lt;br /&gt;(&lt;a href=&quot;http://clojure101.blogspot.com/2009/04/destructuring-binding-support-in-def.html&quot;&gt;def+&lt;/a&gt; {:keys [repl-fn result-fn close-fn]} (create-repl-client host port))&lt;br /&gt;&lt;br /&gt;create-repl-client returns a map:&lt;br /&gt;{:repl-fn repl-fn&lt;br /&gt;:result-fn result-fn&lt;br /&gt;:close-fn close-fn}&lt;br /&gt;&lt;br /&gt;You can listen to the incoming socket data using the result-fn in another thread:&lt;br /&gt;(.start (Thread. #(write-to-window (result-fn))))&lt;br /&gt;&lt;br /&gt;You can send the command to the remote REPL as follows:&lt;br /&gt;(repl-fn &quot;(give-me-status)&quot;)&lt;br /&gt;&lt;br /&gt;To close this client connection you call&lt;br /&gt;(close-fn)&lt;br /&gt;&lt;br /&gt;You can use the following command to shutdown the remote REPL server&lt;br /&gt;(repl-fn &quot;(org.enclojure.repl.main/close-server)&quot;)&lt;br /&gt;&lt;br /&gt;If you use &lt;a href=&quot;http://www.enclojure.org/&quot;&gt;Enclojure&lt;/a&gt; Plugin in Netbeans - You can create a REPL window connected to your REPL enabled application. Check out the &lt;a href=&quot;http://www.enclojure.org/REPLSupport&quot;&gt;Remote unmanaged REPLs&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: bold; &quot;&gt;Embedding a Clojure REPL in your application for Local use (Non-socket)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Sometimes you also want to create a REPL for use with in your application. For example: Enclojure has a Netbeans IDE REPL which is running in Netbeans process and hence can manipulate the Netbeans IDE via the REPL. This helped us with the Enclojure plugin development. You can create a REPL for local use in Application as follows:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;(def+ {:keys [repl-fn result-fn]} (create-clojure-repl))&lt;br /&gt;&lt;br /&gt;You can use the repl-fn and result-fn as explained before. Following is the code snippet copied from the &lt;a href=&quot;http://code.google.com/p/enclojure-clojure-lib/source/browse/trunk/org.enclojure.repl/src/org/enclojure/repl/main.clj&quot;&gt;org.enclojure.repl.main&lt;/a&gt;. create-clojure-repl is wrapping the clojure.main/repl to start the REPL in a thread. This is the function used in both local and remote Socket based REPL.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:small;&quot;&gt;(def *printStackTrace-on-error* false)&lt;br /&gt;&lt;br /&gt;(defn is-eof-ex? [throwable]&lt;br /&gt;(and (instance? clojure.lang.LispReader$ReaderException throwable)&lt;br /&gt;(or&lt;br /&gt;(.startsWith (.getMessage throwable) &quot;java.lang.Exception: EOF while reading&quot;)&lt;br /&gt;(.startsWith (.getMessage throwable) &quot;java.io.IOException: Write end dead&quot;))))&lt;br /&gt;&lt;br /&gt;(defn create-clojure-repl []&lt;br /&gt;&quot;This function creates an instance of clojure repl using piped in and out.&lt;br /&gt;It returns a map of two functions repl-fn and result-fn - first function&lt;br /&gt;can be called with a valid clojure expression and the results are read using&lt;br /&gt;the result-fn.&quot;&lt;br /&gt;(let [cmd-wtr (PipedWriter.)&lt;br /&gt;        result-rdr (PipedReader.)&lt;br /&gt;        piped-in (clojure.lang.LineNumberingPushbackReader. (PipedReader. cmd-wtr))&lt;br /&gt;        piped-out (PrintWriter. (PipedWriter. result-rdr))&lt;br /&gt;        repl-thread-fn #(binding [*printStackTrace-on-error* *printStackTrace-on-error*&lt;br /&gt;                                                       *in* piped-in&lt;br /&gt;                                                       *out* piped-out&lt;br /&gt;                                                       *err* *out*]&lt;br /&gt;               (try&lt;br /&gt;                 (clojure.main/repl&lt;br /&gt;                   :init (fn [] (in-ns &#39;user))&lt;br /&gt;                   :read (fn [prompt exit]&lt;br /&gt;                           (read))&lt;br /&gt;                   :caught (fn [e]&lt;br /&gt;                             (when (is-eof-ex? e)&lt;br /&gt;                               (throw e))&lt;br /&gt;                             (if *printStackTrace-on-error*&lt;br /&gt;                               (.printStackTrace e *out*)&lt;br /&gt;                               (prn (clojure.main/repl-exception e)))&lt;br /&gt;                             (flush))&lt;br /&gt;                   :need-prompt (constantly true))&lt;br /&gt;                 (catch clojure.lang.LispReader$ReaderException ex&lt;br /&gt;                   (prn &quot;REPL closing&quot;))&lt;br /&gt;                 (catch java.lang.InterruptedException ex)&lt;br /&gt;                 (catch java.nio.channels.ClosedByInterruptException ex)))]&lt;br /&gt;(.start (Thread. repl-thread-fn))&lt;br /&gt;{:repl-fn (fn [cmd]&lt;br /&gt;     (if (= cmd &quot;:CLOSE-REPL&quot;)&lt;br /&gt;       (do&lt;br /&gt;         (.close cmd-wtr)&lt;br /&gt;         (.close result-rdr))&lt;br /&gt;       (do&lt;br /&gt;         (.write cmd-wtr cmd)&lt;br /&gt;         (.flush cmd-wtr))))&lt;br /&gt;;//??Using CharArrayWriter to build the string from each read of one byte&lt;br /&gt;;Once there is nothing to read than this function returns the string read.&lt;br /&gt;;Using partial so that CharArrayWriter is only created and once and reused.&lt;br /&gt;;There could be better way.&lt;br /&gt;:result-fn (partial&lt;br /&gt;       (fn [wtr]&lt;br /&gt;         (.write wtr (.read result-rdr))&lt;br /&gt;         (if (.ready result-rdr)&lt;br /&gt;           (recur wtr)&lt;br /&gt;           (let [result (.toString wtr)]&lt;br /&gt;             (.reset wtr)&lt;br /&gt;             result)))&lt;br /&gt;       (CharArrayWriter.))}))&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://clojure101.blogspot.com/feeds/1116112634368545826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://clojure101.blogspot.com/2009/05/creating-clojure-repl-in-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default/1116112634368545826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default/1116112634368545826'/><link rel='alternate' type='text/html' href='http://clojure101.blogspot.com/2009/05/creating-clojure-repl-in-your.html' title='Embedding a Clojure REPL in your production application'/><author><name>Narayan Singhal</name><uri>http://www.blogger.com/profile/11122589411879568472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV_36PGONrhlY5RbHij4dAFmCwpmGXdyCojg3vMN8J5OkRHXzEgFP4bbhgMC7Rh5hDHuod98E_pk09T2OkMr6RJ4Qrn_STPJ0SGdKO1jVnAYhYPjd7FQC29k0SWTR-Rw/s1600-r/ns01c_65x100_l_10x.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8337447265046837037.post-7878802100418783064</id><published>2009-04-17T13:53:00.000-07:00</published><updated>2009-04-21T10:57:29.280-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="clojure update-in"/><category scheme="http://www.blogger.com/atom/ns#" term="frequency table"/><category scheme="http://www.blogger.com/atom/ns#" term="sequences"/><title type='text'>Frequency table from sequences</title><content type='html'>&lt;p&gt;Following function creates the frequency table from the given sequences.&lt;/p&gt;&lt;pre&gt;(defn frequency-table  [&amp; seqs]&lt;br /&gt; (let [count-fn (fn [s item]&lt;br /&gt;                  (update-in s [item] #(if % (inc %) 1)))]&lt;br /&gt;   (reduce #(reduce count-fn %1 %2) {} seqs)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(frequency-table [1 2 3])&lt;br /&gt;=&gt; {3 1, 2 1, 1 1}&lt;br /&gt;&lt;br /&gt;(frequency-table [&quot;fred&quot; &quot;ethel&quot; &quot;lucy&quot;] [&quot;lucy&quot; &quot;rick&quot;] [&quot;lucy&quot; &quot;ethel&quot; &quot;john&quot;])&lt;br /&gt;=&gt; {&quot;john&quot; 1, &quot;rick&quot; 1, &quot;lucy&quot; 3, &quot;ethel&quot; 2, &quot;fred&quot; 1}&lt;br /&gt;&lt;br /&gt;(frequency-table &#39;(1 2 3) #{4 2 1})&lt;br /&gt;=&gt; {4 1, 3 1, 2 2, 1 2}&lt;br /&gt;&lt;br /&gt;(frequency-table {:a 1 :b 3} {:a 1 :b 4})&lt;br /&gt;=&gt; {[:b 4] 1, [:b 3] 1, [:a 1] 2}</content><link rel='replies' type='application/atom+xml' href='http://clojure101.blogspot.com/feeds/7878802100418783064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://clojure101.blogspot.com/2009/04/frequency-table-from-sequences.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default/7878802100418783064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default/7878802100418783064'/><link rel='alternate' type='text/html' href='http://clojure101.blogspot.com/2009/04/frequency-table-from-sequences.html' title='Frequency table from sequences'/><author><name>Narayan Singhal</name><uri>http://www.blogger.com/profile/11122589411879568472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV_36PGONrhlY5RbHij4dAFmCwpmGXdyCojg3vMN8J5OkRHXzEgFP4bbhgMC7Rh5hDHuod98E_pk09T2OkMr6RJ4Qrn_STPJ0SGdKO1jVnAYhYPjd7FQC29k0SWTR-Rw/s1600-r/ns01c_65x100_l_10x.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8337447265046837037.post-2401770414578691440</id><published>2009-04-15T17:48:00.001-07:00</published><updated>2009-04-15T17:51:30.407-07:00</updated><title type='text'>Sorting the list of sequences using max-key</title><content type='html'>(max-key k x y)&lt;p&gt;max-key applies the k function (which should return integer) to the rest of the arguments and returns the argument which yields the greatest number. This can be used to bubble the largest sequence to the front. &lt;/p&gt;&lt;p&gt;(max-key count #{1 2 3} #{4 5})&lt;br /&gt;=&amp;gt; #{1 2 3}&lt;/p&gt;&lt;p&gt;(max-key count #{1 2 3} #{4 5 6 7})&lt;br /&gt;=&amp;gt; #{4 5 6 7}&lt;/p&gt;&lt;p&gt;(apply max-key count &#39;(#{3 4 5} #{1 2} #{3}))&lt;br /&gt;=&amp;gt; #{3 4 5}&lt;/p&gt;&lt;p&gt;Following function takes a list of sequences and return them in the order of their size. So the sequence with most number of elements are returned first.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;(defn sort-seqs [seqs]&lt;br /&gt; (lazy-seq&lt;br /&gt;   (when-not (empty? seqs)&lt;br /&gt;     (let [largest-seq (apply max-key count seqs)]&lt;br /&gt;       (cons largest-seq (sort-seqs (remove #(identical? largest-seq %) seqs)))))))&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;(sort-seqs &#39;(#{3} #{3 4 5} #{1 2}))&lt;br /&gt;=&amp;gt; (#{3 4 5} #{1 2} #{3})&lt;/p&gt;&lt;p&gt;(sort-seqs &#39;([1 2] [3] [4 5 6 7]))&lt;br /&gt;=&amp;gt; ([4 5 6 7] [1 2] [3])&lt;/p&gt;&lt;p&gt;(sort-seqs &#39;({:a 1} {a 2 :b 4} {:c 5}))&lt;br /&gt;=&amp;gt; ({a 2, :b 4} {:c 5} {:a 1})&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://clojure101.blogspot.com/feeds/2401770414578691440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://clojure101.blogspot.com/2009/04/sorting-list-of-sequences-using-max-key.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default/2401770414578691440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default/2401770414578691440'/><link rel='alternate' type='text/html' href='http://clojure101.blogspot.com/2009/04/sorting-list-of-sequences-using-max-key.html' title='Sorting the list of sequences using max-key'/><author><name>Narayan Singhal</name><uri>http://www.blogger.com/profile/11122589411879568472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV_36PGONrhlY5RbHij4dAFmCwpmGXdyCojg3vMN8J5OkRHXzEgFP4bbhgMC7Rh5hDHuod98E_pk09T2OkMr6RJ4Qrn_STPJ0SGdKO1jVnAYhYPjd7FQC29k0SWTR-Rw/s1600-r/ns01c_65x100_l_10x.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8337447265046837037.post-5511589236567595220</id><published>2009-04-09T14:39:00.001-07:00</published><updated>2009-04-10T17:41:20.160-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="assoc-in"/><category scheme="http://www.blogger.com/atom/ns#" term="clojure def"/><category scheme="http://www.blogger.com/atom/ns#" term="in-place editing"/><category scheme="http://www.blogger.com/atom/ns#" term="inner item"/><category scheme="http://www.blogger.com/atom/ns#" term="update-in"/><title type='text'>Manipulating an inner item - (in-place editing)</title><content type='html'>If you have nested associative structure than using &lt;span style=&quot;font-style: italic;&quot;&gt;assoc-in&lt;/span&gt; and &lt;span style=&quot;font-style: italic;&quot;&gt;update-in&lt;/span&gt; you can manipulate the inner structured item and get back a newly nested structure.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;update-in&lt;/span&gt; takes the sequence of keys to find the location and a function to apply to the old value at that location:&lt;br /&gt;&lt;p&gt;(def m {:a [1 2 3]})&lt;br /&gt;(update-in m [:a] conj 4)&lt;br /&gt;=&amp;gt; {:a [1 2 3 4]}&lt;/p&gt;&lt;p&gt;Nested map update&lt;br /&gt;(def m {:a {:b [1 2 3]}})&lt;br /&gt;(update-in m [:a :b] conj 4)&lt;br /&gt;=&amp;gt; {:a {:b [1 2 3 4]}}&lt;/p&gt;&lt;p&gt;Apply merge function to an inner map&lt;br /&gt;(def m {:a 1 :config {:b 1}})&lt;br /&gt;(update-in m [:config] merge {:b 3})&lt;br /&gt;=&amp;gt;  {:a 1, :config {:b 3}}&lt;/p&gt;We can also apply the same functions to the vectors also. Vectors are associative maps and index are the keys.&lt;br /&gt;&lt;br /&gt;(def v [:a {:c 2, :b 1} :d])&lt;br /&gt;(v 2)&lt;br /&gt;=&amp;gt; :d    ;Item at the 3rd index&lt;br /&gt;&lt;br /&gt;We can use both sequential and associative de-structuring binds on vectors:&lt;br /&gt;(let [{fred 2} v]&lt;br /&gt;fred)&lt;br /&gt;=&amp;gt;  :d&lt;br /&gt;&lt;p&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;assoc-in&lt;/span&gt; also takes the sequence of keys and a new value. The following code is locating the 2nd item in the vector. &lt;span style=&quot;font-style: italic;&quot;&gt;assoc-in&lt;/span&gt; is adding the [:rows 42] key value pair to the found map and &lt;span style=&quot;font-style: italic;&quot;&gt;update-in&lt;/span&gt; is applying &lt;span style=&quot;font-style: italic;&quot;&gt;assoc &lt;/span&gt;to the found map with the given key value pairs.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;(assoc-in v [1 :rows] 42)&lt;br /&gt;=&amp;gt;  [:a {:rows 42, :c 2, :b 1} :d]&lt;/p&gt;&lt;p&gt;(update-in v [1] assoc :rows 42 :cols 21)&lt;br /&gt;=&amp;gt;  [:a {:cols 21, :rows 42, :c 2, :b 1} :d]&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://clojure101.blogspot.com/feeds/5511589236567595220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://clojure101.blogspot.com/2009/04/manipulating-inner-item-in-place.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default/5511589236567595220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default/5511589236567595220'/><link rel='alternate' type='text/html' href='http://clojure101.blogspot.com/2009/04/manipulating-inner-item-in-place.html' title='Manipulating an inner item - (in-place editing)'/><author><name>Narayan Singhal</name><uri>http://www.blogger.com/profile/11122589411879568472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV_36PGONrhlY5RbHij4dAFmCwpmGXdyCojg3vMN8J5OkRHXzEgFP4bbhgMC7Rh5hDHuod98E_pk09T2OkMr6RJ4Qrn_STPJ0SGdKO1jVnAYhYPjd7FQC29k0SWTR-Rw/s1600-r/ns01c_65x100_l_10x.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8337447265046837037.post-5539344307527672701</id><published>2009-04-09T12:31:00.000-07:00</published><updated>2009-04-09T14:40:49.961-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Clojure var"/><category scheme="http://www.blogger.com/atom/ns#" term="redefining function"/><category scheme="http://www.blogger.com/atom/ns#" term="worker function"/><title type='text'>Long term relationship function - Var object</title><content type='html'>When you pass a function to another function as parameter than the value of the function var is passed. So if you redefine the passed function - the other function still sees the old defined function and doesn&#39;t use the new function. So if you want to establish a long term relationship between the two functions - you need to pass the Var object itself and not its value.&lt;br /&gt;e.g.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(defn worker []&lt;br /&gt; (Thread/sleep 2000)&lt;br /&gt; (prn &quot;not working&quot;))&lt;/pre&gt;Try two commands on the repl:&lt;br /&gt;user&gt; worker&lt;br /&gt;#&amp;lt;user$worker__319 user$worker__319@cbb3fa&amp;gt;&lt;br /&gt;&lt;br /&gt;user&gt; (var worker)&lt;br /&gt;#&#39;user/worker&lt;br /&gt;&lt;br /&gt;user&gt; #&#39;worker&lt;br /&gt;#&#39;user/worker&lt;br /&gt;&lt;br /&gt;The reader macro #&#39;x expands to (var x). If you have the following function which calls the worker function in a thread:&lt;br /&gt;&lt;pre&gt;(defn worker-thread [worker-fn]&lt;br /&gt;(.start (Thread. #(dotimes [i 10] (worker-fn)))))&lt;/pre&gt;Launch the worker thread&lt;br /&gt;&lt;br /&gt;user&gt; (worker-thread worker)&lt;br /&gt;&lt;br /&gt;Fix the worker function:&lt;br /&gt;&lt;pre&gt;(defn worker []&lt;br /&gt;(Thread/sleep 2000)&lt;br /&gt;(prn &quot;working&quot;))&lt;/pre&gt;You will see that the thread still printing &quot;not working&quot; every 5 seconds.&lt;br /&gt;&lt;br /&gt;If you had launched the worker thread as follows:&lt;br /&gt;&lt;br /&gt;user&gt; (worker-thread #&#39;worker)&lt;br /&gt;&lt;br /&gt;and now you fix the function:&lt;br /&gt;&lt;pre&gt;(defn worker []&lt;br /&gt;(Thread/sleep 2000)&lt;br /&gt;(prn &quot;really working&quot;))&lt;/pre&gt;Thread will now print the new &quot;really printing&quot; message.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://clojure101.blogspot.com/feeds/5539344307527672701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://clojure101.blogspot.com/2009/04/long-term-relationship-function-var.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default/5539344307527672701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default/5539344307527672701'/><link rel='alternate' type='text/html' href='http://clojure101.blogspot.com/2009/04/long-term-relationship-function-var.html' title='Long term relationship function - Var object'/><author><name>Narayan Singhal</name><uri>http://www.blogger.com/profile/11122589411879568472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV_36PGONrhlY5RbHij4dAFmCwpmGXdyCojg3vMN8J5OkRHXzEgFP4bbhgMC7Rh5hDHuod98E_pk09T2OkMr6RJ4Qrn_STPJ0SGdKO1jVnAYhYPjd7FQC29k0SWTR-Rw/s1600-r/ns01c_65x100_l_10x.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8337447265046837037.post-7954320772717328237</id><published>2009-04-01T13:17:00.000-07:00</published><updated>2009-04-01T13:49:39.267-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="clojure def"/><category scheme="http://www.blogger.com/atom/ns#" term="def"/><category scheme="http://www.blogger.com/atom/ns#" term="destructuring bind"/><category scheme="http://www.blogger.com/atom/ns#" term="let"/><title type='text'>Destructuring binding in def</title><content type='html'>A lot of times when I am debugging a clojure function in REPL. I end up doing defs for all my lets and if my let is using the destructuring bind than it become a little tedious process. The following macro helps me substitute the  let with def+ to define the symbols in my REPL:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;   style=&quot;  ;font-family:Verdana;font-size:13px;&quot;&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;(defmacro def+&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;  &quot;def with binding (def+ [{:keys [a b d]} {:a 1 :b 2 :d 3}])&quot;&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;  [bindings]&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;  (let [let-expr (macroexpand `(let ~bindings))&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;        vars (filter #(not (.contains (str %) &quot;__&quot;))&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;               (map first (partition 2 (second let-expr))))&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;        def-vars (map (fn [v] `(def ~v ~v)) vars)]&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;    (concat let-expr def-vars)))&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;;Example usage:&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;(def+ [a 1 b 2])&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;(def+ [{:keys [a b]} {:a 1 :b 2}])&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;(def+ [z 1&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;          {:keys [a b]} {:a 1 :b 2}])&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;margin-top: 0px; margin-bottom: 0px; &quot;&gt;This should not be used in the final code - though it will work - but probably using in REPL is a better use for this macro.&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://clojure101.blogspot.com/feeds/7954320772717328237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://clojure101.blogspot.com/2009/04/destructuring-binding-support-in-def.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default/7954320772717328237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8337447265046837037/posts/default/7954320772717328237'/><link rel='alternate' type='text/html' href='http://clojure101.blogspot.com/2009/04/destructuring-binding-support-in-def.html' title='Destructuring binding in def'/><author><name>Narayan Singhal</name><uri>http://www.blogger.com/profile/11122589411879568472</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjV_36PGONrhlY5RbHij4dAFmCwpmGXdyCojg3vMN8J5OkRHXzEgFP4bbhgMC7Rh5hDHuod98E_pk09T2OkMr6RJ4Qrn_STPJ0SGdKO1jVnAYhYPjd7FQC29k0SWTR-Rw/s1600-r/ns01c_65x100_l_10x.jpg'/></author><thr:total>3</thr:total></entry></feed>