<?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/"
	xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Clojure Study Group DC</title>
	<atom:link href="http://clojurestudydc.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://clojurestudydc.wordpress.com</link>
	<description>Learning the language of the future, today</description>
	<lastBuildDate>Wed, 07 Oct 2009 18:40:59 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='clojurestudydc.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/803d2662591b8754d8c745b2c9a73d0c?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Clojure Study Group DC</title>
		<link>http://clojurestudydc.wordpress.com</link>
	</image>
			<item>
		<title>Clojure training in Reston, with Rich and Stu, next year</title>
		<link>http://clojurestudydc.wordpress.com/2009/10/07/clojure-training-in-reston-with-rich-and-stu-next-year/</link>
		<comments>http://clojurestudydc.wordpress.com/2009/10/07/clojure-training-in-reston-with-rich-and-stu-next-year/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 18:36:47 +0000</pubDate>
		<dc:creator>goodmike</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[2010]]></category>
		<category><![CDATA[Halloway]]></category>
		<category><![CDATA[hickey]]></category>
		<category><![CDATA[training]]></category>

		<guid isPermaLink="false">http://clojurestudydc.wordpress.com/2009/10/07/clojure-training-in-reston-with-rich-and-stu-next-year/</guid>
		<description><![CDATA[Thanks to Paul for pointing this out: the Pragmatic Programmers training series is offering a 3-day training course in Reston, VA next year (date TBD). Clojure&#8217;s creator Rich Hickey and Stuart Halloway will be instructing. More information is at the Pragmatic Programmers site.
It looks like the course will assume you know something about Lisp or [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=140&subd=clojurestudydc&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Thanks to <a href="http://paulbarry.com">Paul</a> for pointing this out: the Pragmatic Programmers training series is offering a 3-day training course in Reston, VA next year (date TBD). Clojure&#8217;s creator <a href="http://www.lisp50.org/schedule/schedule/hickey.html">Rich Hickey</a> and <a href="http://www.nofluffjuststuff.com/conference/speaker/stuart_halloway">Stuart Halloway</a> will be instructing. <a href="http://pragmaticstudio.com/clojure">More information</a> is at the Pragmatic Programmers site.</p>
<p>It looks like the course will assume you know something about Lisp or Java and functional programming, and possibly concurrency, but nothing about Clojure. It&#8217;s going to go well beyond basics, though, and it&#8217;s a chance to ask Rick Hickey questions directly. </p>
<p>It&#8217;s going to be expensive, with the alumni/group discount rate still a hefty $1195. The early bird price is $1495. I&#8217;ve been to the Advanced Ruby course of the same dimensions and cost, and it was worth it. If you all want to join up, 3 or more of us can get the group rate and save a few hundred dollars each.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/clojurestudydc.wordpress.com/140/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/clojurestudydc.wordpress.com/140/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/clojurestudydc.wordpress.com/140/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/clojurestudydc.wordpress.com/140/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/clojurestudydc.wordpress.com/140/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/clojurestudydc.wordpress.com/140/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/clojurestudydc.wordpress.com/140/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/clojurestudydc.wordpress.com/140/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/clojurestudydc.wordpress.com/140/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/clojurestudydc.wordpress.com/140/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=140&subd=clojurestudydc&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://clojurestudydc.wordpress.com/2009/10/07/clojure-training-in-reston-with-rich-and-stu-next-year/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/42e0998c3077ba0ac435423941a3978e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">goodmike</media:title>
		</media:content>
	</item>
		<item>
		<title>Clojure 1.0 and git</title>
		<link>http://clojurestudydc.wordpress.com/2009/07/03/clojure-1-0-and-git/</link>
		<comments>http://clojurestudydc.wordpress.com/2009/07/03/clojure-1-0-and-git/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 22:06:28 +0000</pubDate>
		<dc:creator>goodmike</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://clojurestudydc.wordpress.com/?p=132</guid>
		<description><![CDATA[I&#8217;m chipping away at my Mashup project tasks, namely an OAuth library for Twitter and other providers of protected resources. But I wanted to pass on a concrete contribution, so here are some tips about taking advantage of Clojure&#8217;s availability through git, and how to put your clojure-contrib library in sync with the big Clojure [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=132&subd=clojurestudydc&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I&#8217;m chipping away at my Mashup project tasks, namely an OAuth library for Twitter and other providers of protected resources. But I wanted to pass on a concrete contribution, so here are some tips about taking advantage of Clojure&#8217;s availability through git, and how to put your clojure-contrib library in sync with the big Clojure 1.0 release.</p>
<p><span id="more-132"></span></p>
<h3>Clojure first</h3>
<p>Clojure 1.0 is released, and you can get it as a ZIP file:<br />
http://clojure.googlecode.com/files/clojure_1.0.0.zip</p>
<p>Unzip it, and everything you need is there, including a JAR file, clojure_1.0.0.jar.</p>
<p>I had to rename a few things, since my CLASSPATH expects a JAR called simply &#8216;clojure.jar&#8217; in a folder called &#8216;clojure&#8217;. After I renamed/backed up my existing clojure directory, I copied the unzipped clojure_1.0.0 folder into its place and renamed it. I also created a clojure.jar link, via <code>ln</code> to clojure_1.0.0.jar.</p>
<h3>clojure-contrib</h3>
<p>Now for the clojure-contrib. Stuart Sierra did us the favor of setting up a branch of clojure-contrib development that is intended to be compatible with the Clojure 1.0 release. <a href="http://groups.google.com/group/clojure/browse_frm/thread/86764263af1c2c71/9bcde2f934ac4bf4?lnk=gst&amp;q=contrib+branch+compatible#9bcde2f934ac4bf4" title="announcing a Clojure 1.0-compatible branch of clojure-contrib">Here&#8217;s Stuart&#8217;s announcement</a>. </p>
<p>First, I needed to clone the git repo. I renamed/backed up my old clojure-contrib folder and then issued this command:</p>
<p><code>&gt; git clone git://github.com/richhickey/clojure-contrib.git</code></p>
<p>This initialized a repository tracking the master branch. To get the latest 1.0-compatible code, I needed to track the branch &#8216;clojure-1.0-compatible&#8217;. Following <a href="http://hoth.entp.com/2009/1/21/git-track-is-where-its-at">advice from ENTP</a>, I determined the form of the command to issue was:</p>
<p><code>git branch --track local origin/remote &amp;&amp; git checkout local</code></p>
<p>For example, I decided to call my tracking branch &#8216;1.0&#8242;, so I issued:</p>
<p><code>&gt; git branch --track 1.0 origin/clojure-1.0-compatible &amp;&amp; git checkout 1.0</code></p>
<p>Then, to pull down a copy of this branch:</p>
<p><code>&gt; git pull</code></p>
<p>That&#8217;s all there is too it. Then I was ready to build my JAR&#8217;s:</p>
<p><code>&gt; ant -Dclojure.jar=../clojure/clojure.jar</code></p>
<p>First entirely painless Clojure update ever!</p>
<p>If you&#8217;re comfy with git, you&#8217;ll want to decide on whether to ignore the generated files or commit them. Of course, you can&#8217;t push to the remote source, so it really doesn&#8217;t matter.</p>
<p>Happy hacking!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/clojurestudydc.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/clojurestudydc.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/clojurestudydc.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/clojurestudydc.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/clojurestudydc.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/clojurestudydc.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/clojurestudydc.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/clojurestudydc.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/clojurestudydc.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/clojurestudydc.wordpress.com/132/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=132&subd=clojurestudydc&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://clojurestudydc.wordpress.com/2009/07/03/clojure-1-0-and-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/42e0998c3077ba0ac435423941a3978e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">goodmike</media:title>
		</media:content>
	</item>
		<item>
		<title>Date management for the mashup project</title>
		<link>http://clojurestudydc.wordpress.com/2009/06/24/date-management-for-the-mashup-project/</link>
		<comments>http://clojurestudydc.wordpress.com/2009/06/24/date-management-for-the-mashup-project/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 12:20:49 +0000</pubDate>
		<dc:creator>goodmike</dc:creator>
				<category><![CDATA[capstone]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[anchor project]]></category>
		<category><![CDATA[datetime]]></category>
		<category><![CDATA[java interop]]></category>
		<category><![CDATA[joda.time]]></category>
		<category><![CDATA[metadata]]></category>

		<guid isPermaLink="false">http://clojurestudydc.wordpress.com/?p=115</guid>
		<description><![CDATA[I&#8217;m posting the code I&#8217;ve written for date management in the mashup project. It&#8217;s just a sketch, really. There&#8217;s plenty of work to do to fill it out. But I wanted to post what I&#8217;ve got now.

Thanks to Keith, for his suggestion I use the joda.time library.
Organization: namespaces
I&#8217;ve broken the code out into a couple [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=115&subd=clojurestudydc&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I&#8217;m posting the code I&#8217;ve written for date management in the mashup project. It&#8217;s just a sketch, really. There&#8217;s plenty of work to do to fill it out. But I wanted to post what I&#8217;ve got now.</p>
<p><span id="more-115"></span></p>
<p>Thanks to Keith, for his suggestion I use the joda.time library.</p>
<h3>Organization: namespaces</h3>
<p>I&#8217;ve broken the code out into a couple of namespaces, and thus into different files. The files live in folders under a src directory that is on my development classpath. For instance, the date time utility functions in namespace <code>org.clojurestudydc.mashups.util.datetime</code> are in a file src/org/clojurestudydc/mashups/util/datetime.clj.</p>
<h3>Datetime wrangling</h3>
<p>So date parsing is a bitch because dates are expressed in so many formats. The joda.time library offers a way to parse datetime strings by describing them using different characters for different parts of the date and time. The details are here:<br />
<a href="http://joda-time.sourceforge.net/api-release/org/joda/time/format/DateTimeFormat.html">http://joda-time.sourceforge.net/api-release/org/joda/time/format/DateTimeFormat.html</a> </p>
<p>The <code>org.joda.time.format.DateTimeFormat</code> class has a factory method <code>forPattern</code> that takes a descriptive string in this format and returns a <code>DateTimeFormat</code> object ready to use on datetime strings that match the description. In Clojure, to make a <code>DateTimeFormat</code> object that handles RSS 1.0 datetime strings:</p>
<pre>user&gt; (def rss-10-fmt (org.joda.time.format.DateTimeFormat/forPattern
                     "yyyy-MM-dd'T'HH:mm:ssZZ"))
#'user/rss-10-fmt</pre>
<p>Then use the object&#8217;s <code>parseDateTime</code> method on a timestamp:</p>
<pre>user&gt; (.parseDateTime rss-10-fmt "2005-10-02T09:01:15-07:00")
#&gt;DateTime 2005-10-02T12:01:15.000-04:00&gt;</pre>
<p>One serious shortcoming of the <code>DateTimeFormat</code> class is that you can&#8217;t ask it to parse a timezone expressed as an acronym (EDT, e.g.). So, I have to search timestamps for these and convert them into numerical timezone descriptors (e.g. -0400). So I wrote a function <code>replace-timezone-abbreviation</code> and a datamap <code>timezones</code> for this. (Code follows below.)</p>
<p>Then I built a vector of descriptions of datetime formats. I only put in two, for illustration purposes: RFC822, which RSS 2.0 holds to (mostly), and ISO8601, the closest format to RSS 1.0. Each format is expressed as a datamap with a name, a regex (:rpattern), and a DateTimeFormat pattern (:dpattern). The rest of the code I wrote builds up functions that can process a seq of datamaps and return a copy with each datamap&#8217;s value for a given key converted from a string to a joda.time.DateTime object. The code uses the formats&#8217; regexes to select a format to use. I have placeholders in the code for &#8220;hints&#8221; of various kinds. The idea is that you could pass a format&#8217;s name, and the code would try that format out first. Pass a format, or seq of them, and the code would try to match with them first. Pass a function that can be applied to a string value to derive a joda.time.DateTime object, and the code would try applying it and only go on to the formats if some exception were returned.</p>
<h3>OK, so here&#8217;s the code</h3>
<pre>(ns org.clojurestudydc.mashups.util.datetime
    (:import (org.joda.time DateTime DateTimeComparator)
	     (org.joda.time.format DateTimeFormat)))

(defn date-comparator [] (DateTimeComparator/getInstance))

(def timezones {"AST" "-0400" "ADT" "-0300" "EST" "-0500" "EDT" "-0400" "CST" "-0600" "CDT" "-0500"
"MST" "-0700" "MDT" "-0600" "PST" "-0800" "PDT" "-0700"
"AST" "-0900" "ADT" "-0800" "HST" "-1000" "HDT" "-0900"})

(defn replace-timezone-abbreviation [datestring]
	(let [ptn   (re-pattern (apply str (interpose "|" (keys timezones))))
	      match (re-find ptn datestring)]
	  (if match
	    (.replace datestring match (timezones match))
	    datestring)))

(defstruct date-format-entry :name :rpattern :dpattern)

(def date-format-entries
     [(struct date-format-entry :RFC822
             #"\w\w\w, \d\d \w\w\w \d\d\d\d \d\d:\d\d:\d\d"
	      "EEE, dd MMM yyyy HH:mm:ss ZZ")
      (struct date-format-entry :ISO8601
             #"\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d-\d\d:\d\d"
	      "yyyy-MM-dd'T'HH:mm:ssZZ")])

(defn find-fmt-by-name [name &amp; entries]
  (filter #(= name (:name %)) (concat date-format-entries (first entries))))

(defn find-fmt-by-regex-match [datestring &amp; xtra-entries]
  (let [entries (concat date-format-entries (first xtra-entries))]
	(first (filter (complement #(empty?
                (re-seq (:rpattern %) datestring))) entries))))

(defn parse-string [datestring dpattern]
  (.parseDateTime (DateTimeFormat/forPattern dpattern)
                            (replace-timezone-abbreviation datestring)))

(defn parse-item [item datekey]
  (let [date-format-schema (find-fmt-by-regex-match (datekey item))]
    (if (nil? date-format-schema)
      item ;better to throw an exception
      (let [datestring (datekey item)
	    dpattern (:dpattern date-format-schema)
	    dvalue (parse-string datestring dpattern)]
	(assoc item datekey dvalue)))))

(defn parse-mapseq-date-values [mapseq datekey &amp; hints]
  (map #(parse-item % datekey) mapseq))</pre>
<p>Here&#8217;s how you&#8217;d use it on a seq of rss items like the cleaned-rss seq we built earlier:</p>
<pre>user&gt; (use 'org.clojurestudydc.mashups.util.datetime)
nil
user&gt; (def date-corrected-rss
                     (parse-mapseq-date-values cleaned-rss :pubDate))
#'user/date-corrected-rss
user&gt; (:pubDate (first date-corrected-rss))
#&lt;DateTime 2009-06-23T14:37:54.000-04:00&gt;</pre>
<h3>Sorting</h3>
<p>And here&#8217;s how I use the datetime functions to sort. I have more code in a namespace under &#8216;&#8230;.alterations.sorting&#8217;, as this code conceptually makes a copy of the structure with its items in a different order:</p>
<pre>(ns org.clojurestudydc.mashups.alterations.sorting
    (:require [org.clojurestudydc.mashups.util.datetime :as dt  ]))
...

(defn configure-sort-by-date-fn [date-key]
	(let [dt-comparator (dt/date-comparator)]
	  (fn [coll] (sort #(.compare
               dt-comparator (date-key %2) (date-key %1)) coll))))</pre>
<p>The function <code>configure-sort-by-date-fn</code> takes a key to use to locate datetime values in a datamap and returns a function that&#8217;s ready to sort a collection (seq) of datamaps. Here&#8217;s how it&#8217;s used:</p>
<pre>user&gt; (use 'org.clojurestudydc.mashups.alterations.sorting)
nil
user&gt; (def sort-rss-items (configure-sort-by-date-fn :pubDate))
#'user/sort-rss-items
user&gt; (map :pubDate (take 5 (sort-rss-items date-corrected-rss)))
(#&lt;DateTime 2009-06-23T15:28:45.000-04:00&gt;
 #&lt;DateTime 2009-06-23T15:06:41.000-04:00&gt;
 #&lt;DateTime 2009-06-23T15:02:38.000-04:00&gt;
 #&lt;DateTime 2009-06-23T15:02:27.000-04:00&gt;
 #&lt;DateTime 2009-06-23T14:52:36.000-04:00&gt;)</pre>
<h3>Marking structures generated by builders</h3>
<p>As a closing note, another &#8220;hint&#8221; for a transformer like the datetime parser could be a metadata tag denoting the origin of the structure (and thus the likely format of its values). So here&#8217;s an edit to the RSS builder that marks our collection of RSS items with origin &#8216;rss:</p>
<pre>(ns org.clojurestudydc.mashups.builders.rss)
...

(defn rss-reader [url]
  (let [xml (xml/parse url)
          zipper (zip/xml-zip xml)
          elements (-&gt; zipper zip/down zip/children)
          items (filter #(= :item (:tag %)) elements)]
    (with-meta (map select-contents items)
	       {:origin 'rss})))</pre>
<p>We&#8217;ll need something better than <code>concat</code> now to combine these maps: we have to combine their metadata too.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/clojurestudydc.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/clojurestudydc.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/clojurestudydc.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/clojurestudydc.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/clojurestudydc.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/clojurestudydc.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/clojurestudydc.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/clojurestudydc.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/clojurestudydc.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/clojurestudydc.wordpress.com/115/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=115&subd=clojurestudydc&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://clojurestudydc.wordpress.com/2009/06/24/date-management-for-the-mashup-project/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/42e0998c3077ba0ac435423941a3978e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">goodmike</media:title>
		</media:content>
	</item>
		<item>
		<title>A bit of Clojure at RubyNation 2009</title>
		<link>http://clojurestudydc.wordpress.com/2009/06/16/a-bit-of-clojure-at-rubynation-2009/</link>
		<comments>http://clojurestudydc.wordpress.com/2009/06/16/a-bit-of-clojure-at-rubynation-2009/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 20:51:38 +0000</pubDate>
		<dc:creator>goodmike</dc:creator>
				<category><![CDATA[announcement]]></category>
		<category><![CDATA[conference talk]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[reia]]></category>
		<category><![CDATA[relevance]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://clojurestudydc.wordpress.com/?p=111</guid>
		<description><![CDATA[Just a quick post to mention how Clojure was mentioned at the RubyNation conference in Reston last weekend.
I gave a lightning talk on day 2. Slides are posted. I only had 6 minutes, so I kept it brief. I don&#8217;t think I convinced a lot of the audience members to try it out. Afterwards, though, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=111&subd=clojurestudydc&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Just a quick post to mention how Clojure was mentioned at <a href="http://rubynation.org/">the RubyNation conference</a> in Reston last weekend.</p>
<p>I gave a lightning talk on day 2. <a href="http://clojure-study-dc.googlegroups.com/web/7clojure.key.pdf?gda=xRPx90IAAAA2TS-60ezd-_q3smQvRzgysCwicIej1H5EmnMv8_dpNsv4HODXPKaDo8g--NBuEIRV4u3aa4iAIyYQIqbG9naPgh6o8ccLBvP6Chud5KMzIQ">Slides are posted</a>. I only had 6 minutes, so I kept it brief. I don&#8217;t think I convinced a lot of the audience members to try it out. Afterwards, though, I got to talk to Aaron Bedra of Relevance, who was a technical editor for Stu&#8217;s book. He reports Clojure is actually in use on commercial projects. He&#8217;s a swell fellow.</p>
<p>Russ Olsen gave an impromptu talk at the end of the day about Clojure, Scala, Erlang, and Reia. Two things struck me about his approach to new languages. First, he gives a lot of important to &#8220;curb appeal&#8221;, or how nice the code looks. The parentheses bother him about Clojure and other lisps, same old story. The second thing, though, is the importance given to metaprogramming, which Ruby has brought into the forefront of a lot of developers&#8217; minds. As Russ pointed out, any Lisp makes metaprogramming easy. So that may be a selling point for Clojure among Rubyists.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/clojurestudydc.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/clojurestudydc.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/clojurestudydc.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/clojurestudydc.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/clojurestudydc.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/clojurestudydc.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/clojurestudydc.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/clojurestudydc.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/clojurestudydc.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/clojurestudydc.wordpress.com/111/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=111&subd=clojurestudydc&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://clojurestudydc.wordpress.com/2009/06/16/a-bit-of-clojure-at-rubynation-2009/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/42e0998c3077ba0ac435423941a3978e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">goodmike</media:title>
		</media:content>
	</item>
		<item>
		<title>Coding Meeting May 16th 1pm at HacDC</title>
		<link>http://clojurestudydc.wordpress.com/2009/05/15/coding-meeting-may-16th-1pm-at-hacdc/</link>
		<comments>http://clojurestudydc.wordpress.com/2009/05/15/coding-meeting-may-16th-1pm-at-hacdc/#comments</comments>
		<pubDate>Fri, 15 May 2009 14:34:21 +0000</pubDate>
		<dc:creator>goodmike</dc:creator>
				<category><![CDATA[capstone]]></category>
		<category><![CDATA[meeting]]></category>

		<guid isPermaLink="false">http://clojurestudydc.wordpress.com/?p=108</guid>
		<description><![CDATA[We&#8217;re meeting face-to-face again on Saturday, May 16th at 1pm, at HacDC&#8217;s meeting space in DC. We&#8217;ll be meeting to hack some code on our mashup project. Check out the group&#8217;s google group for discussion and code produced so far.
       <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=108&subd=clojurestudydc&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>We&#8217;re meeting face-to-face again on Saturday, May 16th at 1pm, at HacDC&#8217;s meeting space in DC. We&#8217;ll be meeting to hack some code on our mashup project. Check out the group&#8217;s google group for <a href="http://groups.google.com/group/clojure-study-dc">discussion and code</a> produced so far.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/clojurestudydc.wordpress.com/108/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/clojurestudydc.wordpress.com/108/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/clojurestudydc.wordpress.com/108/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/clojurestudydc.wordpress.com/108/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/clojurestudydc.wordpress.com/108/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/clojurestudydc.wordpress.com/108/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/clojurestudydc.wordpress.com/108/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/clojurestudydc.wordpress.com/108/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/clojurestudydc.wordpress.com/108/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/clojurestudydc.wordpress.com/108/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=108&subd=clojurestudydc&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://clojurestudydc.wordpress.com/2009/05/15/coding-meeting-may-16th-1pm-at-hacdc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/42e0998c3077ba0ac435423941a3978e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">goodmike</media:title>
		</media:content>
	</item>
		<item>
		<title>Capstone project: stepping back for a moment</title>
		<link>http://clojurestudydc.wordpress.com/2009/04/30/capstone-project-stepping-back/</link>
		<comments>http://clojurestudydc.wordpress.com/2009/04/30/capstone-project-stepping-back/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 14:50:37 +0000</pubDate>
		<dc:creator>goodmike</dc:creator>
				<category><![CDATA[capstone]]></category>
		<category><![CDATA[coding]]></category>

		<guid isPermaLink="false">http://clojurestudydc.wordpress.com/?p=92</guid>
		<description><![CDATA[We have a capstone project, a reworking in Clojure of some of the mashup features of Yahoo Pipes. At our last meeting, Luke VanderHart presented a framework for building and connecting components. I&#8217;m going to recap the framework as well as a few philosophical decisions we hammered out. But I&#8217;m also going to invite you [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=92&subd=clojurestudydc&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>We have a capstone project, a reworking in Clojure of <em>some</em> of the mashup features of Yahoo Pipes. At our last meeting, Luke VanderHart presented a framework for building and connecting components. I&#8217;m going to recap the framework as well as a few philosophical decisions we hammered out. But I&#8217;m also going to invite you to take a look at the code with me, with an eye towards 1) understanding each bit and 2) replaying the development of the framework by starting with simple building blocks. Luke and I both agree that the current framework, although awesome, has leapfrogged the kind of discussion and collaboration we want to foster in the study group. So I&#8217;m going to try an experiment with coding in public. On this blog, and soon on github, we&#8217;re going to build the framework again, together, feature by feature, always embracing the principle of the simplest thing that could possibly work. We&#8217;ll build up the might of Luke&#8217;s framework, but in a way that we get there together. And we&#8217;ll probably make it better from all being involved.<br />
<span id="more-92"></span><br />
First off, we haven&#8217;t agreed on a name for the capstone project, so I&#8217;m just going to call it the clojure mashup project, or the mashup project, or just the project. Luke has named his repo &#8220;flowjure&#8221;, and there&#8217;s a lot of &#8220;tubes&#8221; and &#8220;pipes&#8221; in the namespaces, but that&#8217;s immaterial right now. Don&#8217;t worry about the names.</p>
<p>Next, you can find Luke&#8217;s code on github: <a href="http://github.com/levand/flowjure/tree/master">http://github.com/levand/flowjure/tree/master</a></p>
<ol>
<li>If you don&#8217;t have git installed, install it</li>
<li>Decide where you want to put the cloned repository. I have a &#8216;clojure-dev&#8217; directory in my home directory.</li>
<li>clone the repository in that location: <code>clojure-dev$&gt; git clone git://github.com/levand/flowjure.git</code></li>
<li>Make sure your classpath &mdash; either your environment variable if you&#8217;re doing Clojure form the command line or in a configuration file for emacs or other editor &mdash; contains the path to <code>flowjure/src/</code>. In my case, that&#8217;s <code>/Users/michael/clojure-dev/flowjure/src</code></li>
</ol>
<p>Now let&#8217;s get started by going over a few things from the last meeting. </p>
<ul>
<li>The mashup project is component-based. For now, we&#8217;re trying out a strict policy of every component taking one or more inputs, either external resources like URIs or other project components, put only yielding one output, either a Clojure data structure or something intended for output from (and thus marking the completion of) the component chain. </li>
<li>The component chain operates in a &#8220;pull&#8221; style, with each component in the chain asking the component(s) immediately &#8220;upstream&#8221; to give them data.</li>
<li>Because of the amny-in/one-out structure of the components and the &#8220;pull&#8221; metaphor, the component chain can&#8217;t branch. Data funnels down to a single output</li>
</ul>
<p>Furthermore, Paul Barry described the different kinds of objects in the project in five categories:</p>
<ol>
<li>source (something external like an RSS feed or file), </li>
<li>builder (any format into internal representation), </li>
<li>collector/combiner (multiple inputs to one output), </li>
<li>transform (alter one input into one output),</li>
<li>formater/outputer (internal representation into any format)</li>
</ol>
<p>With this in mind, let&#8217;s look as the RSS reader in the file src/flowjure/components/rss.clj:</p>
<pre>
(ns flowjure.components.rss
  (:require [clojure.xml :as xml]
             [clojure.zip :as zip])
  (:use flowjure.engine))

(defn create-map
  "Creates a map object from an RSS 'item' entry"
  [item]
  (reduce (fn [acc it]
            (assoc acc (keyword-to-str (:tag it))
              (first (:content it)))) {} (:content item)))

(def-component {:name "rss"
                :category "Input"
                :description "Loads an RSS Feed"
                &#58;output-type "Record Sequence"
                :args {"url" {:doc "The URL of the RSS feed"
                              :type "String"
                              :min-required 1
                              :max-required 1}}}
  (fn [pipe pipe-args args]
    (let [xml (xml/parse (args "url"))
          zipper (zip/xml-zip xml)
          elements (-&gt; zipper zip/down zip/children)
          items (filter #(= :item (:tag %)) elements)]
      (map create-map items))))
</pre>
<h3>Part 1: Examining the code</h3>
<p>Now, fire up a REPL, because I&#8217;m going to walk you through the execution of the meat of this code, the five lines at the end. We&#8217;re going to have to wrangle with namespaces a bit, and I&#8217;m going to advocate using the pretty printer in clojure.contrib during our REPL session.</p>
<p>We start out with the xml and zip namespaces already available to us, as using <code>resolve</code> demonstrates:</p>
<pre>user&gt; (resolve 'clojure.xml/parse)
#'clojure.xml/parse
user&gt; (resolve 'clojure.zip/zipper)
#'clojure.zip/zipper
user&gt; (resolve 'clojure.zip/down)
#'clojure.zip/down</pre>
<p>The pretty-printer is in clojure.contrib, so we&#8217;ll need to get it into our current namespace with <code>use</code>:</p>
<pre>user&gt; (resolve 'clojure.contrib.pprint/pprint)
nil
user&gt; (use 'clojure.contrib.pprint)
nil
user&gt; (resolve 'clojure.contrib.pprint/pprint)
#'clojure.contrib.pprint/pprint</pre>
<p>See <a href="http://bc.tech.coop/blog/081029.html">http://bc.tech.coop/blog/081029.html</a> for more basics on namespaces.</p>
<p>See <a href="http://code.google.com/p/clojure-contrib/wiki/PprintApiDoc">http://code.google.com/p/clojure-contrib/wiki/PprintApiDoc</a> for API docs on the pretty printer.</p>
<p>Back to the code. Here are the lines I&#8217;m interested in right now:</p>
<pre>(let [xml (xml/parse url)
        zipper (zip/xml-zip xml)
        elements (-&gt; zipper zip/down zip/children)
        items (filter #(= :item (:tag %)) elements)] ...)</pre>
<p>Let&#8217;s call the lines in the function one at a time in the REPL.</p>
<p>First, use <code>xml/parse</code> to read the RSS available at a URL, let&#8217;s use &#8220;http://rss.cnn.com/rss/cnn_topstories.rss&#8221;, and convert it into a Clojure data map. That&#8217;s a powerful function!</p>
<pre>
user&gt; (clojure.xml/parse "http://rss.cnn.com/rss/cnn_topstories.rss")
{:tag :rss, :attrs {&#58;xmlns:media "http://search.yahoo.com/mrss/", &#58;xmlns:feedburner "http://rssnamespace.org/feedburner/ext/1.0", :version "2.0"}, :content [{:tag :channel, :attrs nil, :content [{:tag :title, :attrs nil, :content ["CNN.com"]} {:tag :link, :attrs nil, :content ["http://www.cnn.com/?eref=rss
[snip]</pre>
<p>Well, it&#8217;s a map, but it&#8217;s sure hard to read. Let&#8217;s take advantage of one of the pretty printers awesomer tools, the pp macro, which when called pretty-prints the last thing output (our ugly map)</p>
<pre>user&gt; (pp)
{:tag :rss,
 :attrs
 {&#58;xmlns:media "http://search.yahoo.com/mrss/",
  &#58;xmlns:feedburner "http://rssnamespace.org/feedburner/ext/1.0",
  :version "2.0"},
 :content
 [{:tag :channel,
   :attrs nil,
   :content
[snip]</pre>
<p>That&#8217;s better, although this thing is enormous. The thing to look for is &#8220;:tag :item&#8221; &#8212; that denotes an item, the elements that we&#8217;re after.</p>
<pre>
[snip]
{:tag :item,
     :attrs nil,
     :content
     [{:tag :title,
       :attrs nil,
       :content ["Mexico City shuts down venues due to swine flu"]}
      {:tag :guid,
       :attrs {:isPermaLink "false"},
       :content
       ["http://www.cnn.com/2009/HEALTH/04/28/swine.flu/index.html?eref=rss_topstories"]}
      {:tag :link,
       :attrs nil,
       :content
       ["http://rss.cnn.com/~r/rss/cnn_topstories/~3/kjZP0YJPYI0/index.html"]}
[snip]</pre>
<p>Now, Luke uses <code>xml.zip/xml-zip</code> to assemble the value for &#8216;zipper.&#8217; What&#8217;s <!--more-->xml-zip do? Let&#8217;s check the API docs:</p>
<pre>(xml-zip root)
Returns a zipper for xml elements (as from xml/parse), given a root element</pre>
<p>Huh. OK. Maybe we should evaluate our parsed XML and see what we get.</p>
<pre>user&gt; (pprint (clojure.zip/xml-zip (clojure.xml/parse "http://rss.cnn.com/rss/cnn_topstories.rss")))
[{:tag :rss,
  :attrs
  {&#58;xmlns:media "http://search.yahoo.com/mrss/",
   &#58;xmlns:feedburner "http://rssnamespace.org/feedburner/ext/1.0",
   :version "2.0"},
  :content
[snip]</pre>
<p>That looks pretty familiar. Zippers must print out as maps. We&#8217;ll have to take it on faith that internally it&#8217;s fancier than a map.</p>
<p>For convenience, let&#8217;s def a zipper variable to hold our Zipper.</p>
<pre>user&gt; (def zipper (clojure.zip/xml-zip (clojure.xml/parse "http://rss.cnn.com/rss/cnn_topstories.rss")))
#'user/zipper</pre>
<p>Now we use the <code>-&gt;</code> macro (called thread). Clojure&#8217;s English descriptions suffer from namespace collisions: thread, map &#8212; these things have multiple meanings. The <code>thread</code> macro is a way to line up functions:<br />
<code>(-&gt; zipper clojure.zip/down clojure.zip/children)</code> is the same as <code>(clojure.zip/children (clojure.zip/down zipper))</code>.</p>
<p>What do these do? According to the docs:</p>
<pre>(children loc)
Returns a seq of the children of node at loc, which must be a branch

(down loc)
Returns the loc of the leftmost child of the node at this loc, or nil if no children</pre>
<p>In other words, we get the children of the first child of the RSS XML root element as a seq. This is important: we have all the tag maps we want at the top level of the seq. We don&#8217;t have to do any digging now. This is what the seq looks like:</p>
<pre>({:tag :title, :attrs nil, :content ["CNN.com"]} [snip] {:tag :item, :attrs nil, :content [{:tag :title, :attrs nil, :content ["HHS secretary confirmed in midst of outbreak"]}]} [snip])</pre>
<p>Now we filter the tags for those with <code>:tag</code> value <code>:item</code>:</p>
<pre>user&gt; (def items (filter #(= :item (:tag %)) elements))
#'user/items
user&gt; (pprint (first items))
{:tag :item,
 :attrs nil,
 :content
 [{:tag :title,
   :attrs nil,
   :content ["HHS secretary confirmed in midst of outbreak"]}
  {:tag :guid,
   :attrs {:isPermaLink "false"},
   :content
   ["http://www.cnn.com/2009/POLITICS/04/28/sebelius.confirmation/index.html?eref=rss_topstories"]}
  {:tag :link,
   :attrs nil,
   :content
   ["http://rss.cnn.com/~r/rss/cnn_topstories/~3/dcHTwVYr0QU/index.html"]}
  {:tag :description,
   :attrs nil,
   :content
   ["The Senate today confirmed Kansas Gov. Kathleen Sebelius as secretary of
health and human services on a 65-31 vote. Sebelius takes office as swine flu
numbers climb worldwide. But confirming Sebelius, who met several obstacles
during confirmation hearings, doesn't bring the health team to 100 percent.
There are still no appointees in place for any of the department's 18 key jobs.
[snip]"]}
  {:tag :pubDate,
   :attrs nil,
   :content ["Tue, 28 Apr 2009 10:10:23 EDT"]}
  {:tag :feedburner:origLink,
   :attrs nil,
   :content
   ["http://www.cnn.com/2009/POLITICS/04/28/sebelius.confirmation/index.html?eref=rss_topstories"]}]}
</pre>
<p>Next,  the <code>create-map</code> helper function is applied to each element in the items collection (via <code>map</code>&#8211;again, many meanings) to get to the content in each of these <code>{:tag ...}</code> data maps.</p>
<p>Let&#8217;s just call the function&#8217;s body without defining it. And I&#8217;m removing the <code>keyword-to-str</code> call within Luke&#8217;s method to make things simpler:</p>
<pre>user&gt; (pprint (reduce (fn [acc it]
            (assoc acc (:tag it)
              (first (:content it)))) {} (:content (first items))))
{:feedburner:origLink
 "http://www.cnn.com/2009/POLITICS/04/28/sebelius.confirmation/index.html?eref=rss_topstories",
 :pubDate "Tue, 28 Apr 2009 10:10:23 EDT",
 :description
 "The Senate today confirmed Kansas Gov. Kathleen Sebelius as secretary of health and human services on a 65-31 vote. Sebelius takes office as swine flu numbers climb worldwide. But confirming Sebelius, who met several obstacles during confirmation hearings, doesn't bring the health team to 100 percent. There are still no appointees in place for any of the department's 18 key jobs.
<div>\n<a><img></img></a> ...",
 :link
 "http://rss.cnn.com/~r/rss/cnn_topstories/~3/dcHTwVYr0QU/index.html",
 :guid
 "http://www.cnn.com/2009/POLITICS/04/28/sebelius.confirmation/index.html?eref=rss_topstories",
 :title "HHS secretary confirmed in midst of outbreak"}
</pre>
<p>A better name for the <code>create-map</code> helper function might be &#8220;select-contents&#8221;</p>
<h3>Part 2: The simplest thing</h3>
<p>The current code in the  <code>tubes.components.rss</code> namespace adheres to a pretty highly generalized interface: the <code>defcomponent</code> macro takes a bunch of metadata, some of which is necessary for the rss component but some of which is not (we don&#8217;t really have to specify that a function that reads a url requires exactly one url string). The interface is complicated because of all the other components <code>defcompenent</code> could and will create. Similarly, the function that does the work, that for our use *is* the rss component, takes three arguments: a pipe, pipe-args, and plain old args. Again, these components have a consistent and sophisticated interface, because of what we may ask them to do tomorrow. But let&#8217;s not worry about tomorrow just now. </p>
<p>What&#8217;s the simplest thing that could work? Well, what do we need? We need to pass a URL to some component and get back a list of data maps, each containing the different pieces of content from each item tag in the feed.</p>
<p>OK, how about</p>
<pre>(ns tubes.components.rss
  (:require [clojure.xml :as xml]
             [clojure.zip :as zip]))

(defn select-contents
  "Creates a data map of the contents of an RSS 'item' entry"
  [item]
  (reduce (fn [acc it]
            (assoc acc (:tag it)
              (first (:content it)))) {} (:content item)))

(defn rss-reader [url]
  (let [xml (xml/parse url)
          zipper (zip/xml-zip xml)
          elements (-&gt; zipper zip/down zip/children)
          items (filter #(= :item (:tag %)) elements)]
      (map select-contents items)))</pre>
<p>Then, from the REPL:</p>
<pre>user&gt; (use 'tubes.components.rss)
nil
user&gt; (def cnn-rss (rss-reader "http://rss.cnn.com/rss/cnn_topstories.rss"))
#'user/cnn-rss</pre>
<p>Sure, it isn&#8217;t lazy. And it doesn&#8217;t support any kind of reuse &mdash; it&#8217;s use specific. But let&#8217;s add those things in as we need them. For now, we&#8217;re just exploring how the components work when we need them.</p>
<h3>What&#8217;s next?</h3>
<p>I&#8217;m going to propose a discussion on <a href="http://groups.google.com/group/clojure-study-dc">the mailing list</a> for the next week or so. I propose we take on one thing at a time, and pass code around. Please join us there. You don&#8217;t have to be a DC native at this point: the action is online.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/clojurestudydc.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/clojurestudydc.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/clojurestudydc.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/clojurestudydc.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/clojurestudydc.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/clojurestudydc.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/clojurestudydc.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/clojurestudydc.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/clojurestudydc.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/clojurestudydc.wordpress.com/92/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=92&subd=clojurestudydc&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://clojurestudydc.wordpress.com/2009/04/30/capstone-project-stepping-back/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/42e0998c3077ba0ac435423941a3978e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">goodmike</media:title>
		</media:content>
	</item>
		<item>
		<title>Unofficial Clojure 1.0 release candidate</title>
		<link>http://clojurestudydc.wordpress.com/2009/04/28/unofficial-clojure-10-release-candidate/</link>
		<comments>http://clojurestudydc.wordpress.com/2009/04/28/unofficial-clojure-10-release-candidate/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 17:43:42 +0000</pubDate>
		<dc:creator>fogus</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[1.0]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[clojure-contrib]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://clojurestudydc.wordpress.com/?p=89</guid>
		<description><![CDATA[Clojure 1.0 is on the way, and as a result a lot of activity is occurring in the Subversion repository.  Revision 1357 of the Clojure source was proclaimed the likely release candidate, although a few minor changes have been checked in since.  Likewise, clojure-contrib revision 723 is the likely release candidate corresponding to 1.0. It [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=89&subd=clojurestudydc&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Clojure 1.0 is on the way, and as a result a lot of activity is occurring in the Subversion repository.  Revision <span class="status-body"><span class="entry-content">1357 of the Clojure source was proclaimed the likely release candidate, although a few minor changes have been checked in since.  Likewise, clojure-contrib revision </span></span><span class="status-body"><span class="entry-content">723 is the likely release candidate corresponding to 1.0. </span></span>It should be interesting to watch what unfolds in the source until the actual release.</p>
<p><span class="status-body"><span class="entry-content">It&#8217;s not too late to contribute, and no contribution is too small.</span></span></p>
<p><span class="status-body"><span class="entry-content">-m</span></span></p>
<p><span class="status-body"><span class="entry-content"><br />
</span></span></p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/clojurestudydc.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/clojurestudydc.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/clojurestudydc.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/clojurestudydc.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/clojurestudydc.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/clojurestudydc.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/clojurestudydc.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/clojurestudydc.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/clojurestudydc.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/clojurestudydc.wordpress.com/89/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=89&subd=clojurestudydc&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://clojurestudydc.wordpress.com/2009/04/28/unofficial-clojure-10-release-candidate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5aa24eee4238e1e964210ed447e8dc91?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fogus</media:title>
		</media:content>
	</item>
		<item>
		<title>Meeting recap, Pipes/Tubes/Clinks, and next meeting info</title>
		<link>http://clojurestudydc.wordpress.com/2009/04/06/meeting-recap-pipestubesclinks-and-next-meeting-info/</link>
		<comments>http://clojurestudydc.wordpress.com/2009/04/06/meeting-recap-pipestubesclinks-and-next-meeting-info/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 15:32:24 +0000</pubDate>
		<dc:creator>goodmike</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://clojurestudydc.wordpress.com/?p=83</guid>
		<description><![CDATA[At our latest meeting, we discussed macros and adopted a capstone project, an open-source Clojure implementation of some of the functions of Yahoo Pipes.
Macros
Regarding macros, we touched on the chain of events when a Clojure program is evaluated: evaluation runs from top to bottom, and each S-expression is macro-expanded (if possible) and then evaluated. If [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=83&subd=clojurestudydc&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>At our latest meeting, we discussed macros and adopted a capstone project, an open-source Clojure implementation of some of the functions of Yahoo Pipes.</p>
<h3>Macros</h3>
<p>Regarding macros, we touched on the chain of events when a Clojure program is evaluated: evaluation runs from top to bottom, and each S-expression is macro-expanded (if possible) and then evaluated. If an expression expands into something that itself contains a macro, the the new macro expression will be expanded before it is evaluated. This allows a macro to use a previously defined function in the determination of its expansion. </p>
<p>&#8220;Macros&#8221; in Lisp are very different from &#8220;macros&#8221; in other languages, as they allow the programmer to use all the power of Lisp to determine the macro&#8217;s expansion. Macros are not first-class members of the Clojure language, however. You cannot use them as you use functions&#8211;you can not use them with map or apply, for example&#8211;because macroexpansion happens before an expression can be used in this way.</p>
<h3>Seeing stars</h3>
<p>We also talked about &#8220;star&#8221; functions and macros. The macroexpansion of an expression that uses &#8216;<code>and</code>&#8216; includes something called <code>let*</code>:</p>
<p><code>(macroexpand '(and 1 2 3))<br />
-&gt;(let* [and__2863 1]<br />
(if and__2863 (clojure.core/and 2 3) and__2863))</code></p>
<p>We concluded that you really aren&#8217;t supposed to see <code>let*</code>. You only do in this case because <code>macroexpand</code> completely expands the expression it is given, and it turns out that <code>let</code> is a macro whose definition includes the mysterious <code>let*</code>. In fact, a lot of Clojure&#8217;s core macros use &#8220;star&#8221; constructs that appear to be special forms. Some digging at the REPL confirmed that they are not symbols. Likely the &#8220;star&#8221; forms are transformed by the Clojure parser directly into Java. If you have some special knowledge about this, please post a comment or join our discussion group. We&#8217;d like to know more.</p>
<h3>Capstone project</h3>
<p>Luke presented the case for a project that implemented some of the Yahoo Pipes application. By general acclamation we adopted this project as our capstone. We&#8217;ve decided to spend the next two weeks hacking on the basic problems of the project ourselves, keeping in touch through the group mailing list. David set up a github repo for us, with a <a href="http://wiki.github.com/djwonk/tubes">wiki for collaboration</a>. There you can find the summary of our initial work on defining the project, thanks to Keith. Serge dug up <a href="http://pipes.yahoo.com/pipes/docs?doc=modules">Yahoo&#8217;s Pipes documentation</a>. </p>
<p>We&#8217;re calling this Tubes right now (as in &#8220;teh tubes&#8221;), but a final decision on the name (I&#8217;m not saying I don&#8217;t like Tubes) is one of many tasks we&#8217;re deferring. Right now we just want to get things moving. Personally, I expect Paul to have it all done by this afternoon.</p>
<h3>Multimethods on Sunday, April 19th, 1pm</h3>
<p>Our next meeting will be at least partly devoted to the final topic in Stu&#8217;s book: multimethods. Read chapter 8 of Programming Clojure and bring any questions or comments you&#8217;d like to discuss. Please notice two things about the next meeting date: 1) it is in <strong>two weeks</strong>, not three; and 2) <strong>it is on a Sunday</strong>. The location is still HacDC&#8217;s meeting space at St. Stephens, and the time is still 1pm. We hope to see you there.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/clojurestudydc.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/clojurestudydc.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/clojurestudydc.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/clojurestudydc.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/clojurestudydc.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/clojurestudydc.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/clojurestudydc.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/clojurestudydc.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/clojurestudydc.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/clojurestudydc.wordpress.com/83/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=83&subd=clojurestudydc&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://clojurestudydc.wordpress.com/2009/04/06/meeting-recap-pipestubesclinks-and-next-meeting-info/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/42e0998c3077ba0ac435423941a3978e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">goodmike</media:title>
		</media:content>
	</item>
		<item>
		<title>Project Proposal: Clojure Pipes</title>
		<link>http://clojurestudydc.wordpress.com/2009/03/30/project-proposal-clojure-pipes/</link>
		<comments>http://clojurestudydc.wordpress.com/2009/03/30/project-proposal-clojure-pipes/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 21:23:20 +0000</pubDate>
		<dc:creator>goodmike</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://clojurestudydc.wordpress.com/?p=80</guid>
		<description><![CDATA[This Saturday, April 4, at our face-to-face meeting at HacDC, member Luke VanderHart will informally present a case for a Yahoo Pipes-like content aggregator as a possible capstone project. Interested?
Read up on Pipes. 
Read Luke&#8217;s initial comments.
Of course, we&#8217;ll also discuss macros, including the material in Chapter 7 of Programming Clojure.
We hope to see you [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=80&subd=clojurestudydc&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This Saturday, April 4, at our face-to-face meeting at HacDC, member Luke VanderHart will informally present a case for a Yahoo Pipes-like content aggregator as a possible capstone project. Interested?</p>
<p>Read up on <a href="http://pipes.yahoo.com/pipes/">Pipes</a>. </p>
<p>Read <a href="http://groups.google.com/group/clojure-study-dc/msg/24795327b5b383fd">Luke&#8217;s initial comments</a>.</p>
<p>Of course, we&#8217;ll also discuss macros, including the material in Chapter 7 of <a href="http://www.pragprog.com/titles/shcloj/programming-clojure">Programming Clojure</a>.</p>
<p>We hope to see you there: 1PM at <a href="http://maps.google.com/maps/ms?ie=UTF8&amp;hl=en&amp;msa=0&amp;msid=112368426664365520724.00044a72684e313eb7ebd&amp;ll=38.932307,-77.03521&amp;spn=0.008813,0.007253&amp;z=17&amp;iwloc=00044a727d23d707d87b9">HacDC</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/clojurestudydc.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/clojurestudydc.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/clojurestudydc.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/clojurestudydc.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/clojurestudydc.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/clojurestudydc.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/clojurestudydc.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/clojurestudydc.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/clojurestudydc.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/clojurestudydc.wordpress.com/80/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=80&subd=clojurestudydc&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://clojurestudydc.wordpress.com/2009/03/30/project-proposal-clojure-pipes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/42e0998c3077ba0ac435423941a3978e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">goodmike</media:title>
		</media:content>
	</item>
		<item>
		<title>March 14 meeting recap, next meeting April 4</title>
		<link>http://clojurestudydc.wordpress.com/2009/03/16/march-14-meeting-recap-next-meeting-april-4/</link>
		<comments>http://clojurestudydc.wordpress.com/2009/03/16/march-14-meeting-recap-next-meeting-april-4/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 13:13:22 +0000</pubDate>
		<dc:creator>goodmike</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://clojurestudydc.wordpress.com/?p=67</guid>
		<description><![CDATA[We had another successful meeting at HacDC&#8217;s workshop on Saturday. We covered functional programming, walking through the concepts in the chapter from Programming Clojure and then putting them to work in translating a decision tree modeling program from Python to Clojure: watch for a separate announcement on how we will continue to work on that. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=67&subd=clojurestudydc&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>We had another successful meeting at HacDC&#8217;s workshop on Saturday. We covered functional programming, walking through the concepts in the chapter from Programming Clojure and then putting them to work in translating a decision tree modeling program from Python to Clojure: watch for a separate announcement on how we will continue to work on that. We had an especially good time unraveling this bit of code&#8230;</p>
<pre style="font-size:1.2em;">(def head-fibo (lazy-cat [0 1] (map + head-fibo
                                      (rest head-fibo))))</pre>
<p>&#8230;and understanding what&#8217;s less than optimal about it: that it keeps a reference to the head of a lazy sequence, and thus <code>(nth head-fibo x)</code> fails for large values of <code>x</code>.</p>
<p>Next, we&#8217;ll tackle macros on April 4th, at 1PM, at HacDC&#8217;s workshop. The reading is Chapter 7 of Programming Clojure. We&#8217;ll be looking at simple implementations of <code>defmacro</code> and reviewing different uses for macros. We may also tackle a bit of Paul&#8217;s proposed templating language, putting what we&#8217;ve learned to use. Hope to see you there!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/clojurestudydc.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/clojurestudydc.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/clojurestudydc.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/clojurestudydc.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/clojurestudydc.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/clojurestudydc.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/clojurestudydc.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/clojurestudydc.wordpress.com/67/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/clojurestudydc.wordpress.com/67/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/clojurestudydc.wordpress.com/67/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=clojurestudydc.wordpress.com&blog=5680575&post=67&subd=clojurestudydc&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://clojurestudydc.wordpress.com/2009/03/16/march-14-meeting-recap-next-meeting-april-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/42e0998c3077ba0ac435423941a3978e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">goodmike</media:title>
		</media:content>
	</item>
	</channel>
</rss>