<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" 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" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DkQAQ349eCp7ImA9WhFTGUk.&quot;"><id>tag:blogger.com,1999:blog-8825992</id><updated>2013-06-11T02:52:22.060-07:00</updated><category term="images" /><category term="amqp" /><category term="rst" /><category term="icons" /><category term="load-balancing" /><category term="news" /><category term="twisted" /><category term="seminars" /><category term="movies" /><category term="books" /><category term="codethink" /><category term="development" /><category term="soa" /><category term="apt-get" /><category term="community" /><category term="hosting" /><category term="events" /><category term="privacy" /><category term="lbaas" /><category term="zope3" /><category term="mirco-apps" /><category term="environments" /><category term="bottle" /><category term="pycon" /><category term="deferreds" /><category term="nevow" /><category term="combinator" /><category term="category theory" /><category term="gevent" /><category term="conch" /><category term="video" /><category term="virtual" /><category term="email" /><category term="minicom" /><category term="launchpad" /><category term="advocates" /><category term="solaris" /><category term="work" /><category term="cred" /><category term="training" /><category term="announcements" /><category term="scripting" /><category term="scheme" /><category term="reform" /><category term="dimensions" /><category term="visualization" /><category term="tornado" /><category term="java" /><category term="sbcl" /><category term="authentication" /><category term="hci" /><category term="graphics" /><category term="installs" /><category term="cffi" /><category term="spore" /><category term="rebar" /><category term="pymon" /><category term="philosophy" /><category term="lambda" /><category term="concurrency" /><category term="uist" /><category term="graph-theory" /><category term="networking" /><category term="sf" /><category term="rest" /><category term="health care" /><category term="io" /><category term="text" /><category term="tablets" /><category term="divmod" /><category term="λ-calculus" /><category term="vendors" /><category term="mac" /><category term="design" /><category term="mp3" /><category term="txamqp" /><category term="pymt" /><category term="ubuntu" /><category term="blogging" /><category term="sprints" /><category term="pydot" /><category term="uls" /><category term="conferences" /><category term="open-source" /><category term="json" /><category term="google" /><category term="subversion" /><category term="unity" /><category term="partnerships" /><category term="virtualization" /><category term="education" /><category term="multi-touch" /><category term="technology" /><category term="domains" /><category term="smtp" /><category term="auctions" /><category term="support" /><category term="pycon2005" /><category term="ec2" /><category term="apis" /><category term="actors" /><category term="messaging" /><category term="alchemy" /><category term="github" /><category term="hacking" /><category term="rhythmbox" /><category term="joxa" /><category term="sofware" /><category term="lua" /><category term="flask" /><category term="mplayer" /><category term="coroutines" /><category term="grid" /><category term="agents" /><category term="pycon2004" /><category term="mobile-computing" /><category term="node" /><category term="howtos" /><category term="jsonrpc" /><category term="content management" /><category term="frameworks" /><category term="ios" /><category term="planning" /><category term="systems" /><category term="internap" /><category term="zope" /><category term="gimp" /><category term="q-and-a" /><category term="latin" /><category term="metaclasses" /><category term="services" /><category term="physics" /><category term="code" /><category term="devops" /><category term="async" /><category term="usability" /><category term="hardware" /><category term="touch" /><category term="version-control" /><category term="toolkits" /><category term="generators" /><category term="math" /><category term="1-to-many" /><category term="psu" /><category term="heat" /><category term="rrd" /><category term="cl-async" /><category term="lambda calculus" /><category term="photoshop" /><category term="smalltalk" /><category term="cp/m" /><category term="mac os x" /><category term="repl" /><category term="gtk" /><category term="world" /><category term="txjsonrpc" /><category term="ssh" /><category term="notation" /><category term="music" /><category term="modules" /><category term="brew" /><category term="ml" /><category term="libraries" /><category term="publishing" /><category term="databases" /><category term="scoble" /><category term="turing" /><category term="logos" /><category term="rlwrap" /><category term="cgi" /><category term="words" /><category term="servers" /><category term="holden web" /><category term="parallelism" /><category term="lamp" /><category term="qt" /><category term="tea" /><category term="reblog" /><category term="pypy" /><category term="management" /><category term="mobile" /><category term="meetup" /><category term="installation" /><category term="finance" /><category term="standups" /><category term="documentation" /><category term="mantissa" /><category term="clojure" /><category term="erlang" /><category term="web" /><category term="validators" /><category term="gestures" /><category term="storage" /><category term="projects" /><category term="functions" /><category term="open source" /><category term="maintainers" /><category term="occupy" /><category term="freedom" /><category term="distributed systems" /><category term="lfe" /><category term="pop3" /><category term="threadpools" /><category term="bazaar" /><category term="applications" /><category term="iphone" /><category term="travel" /><category term="conversations" /><category term="society" /><category term="haskell" /><category term="storm" /><category term="sun" /><category term="stross" /><category term="safari" /><category term="humor" /><category term="half life" /><category term="lame" /><category term="anthropology" /><category term="serial" /><category term="klein" /><category term="business" /><category term="meego" /><category term="reviews" /><category term="threads" /><category term="rpc" /><category term="mysql" /><category term="psf" /><category term="pycon2012" /><category term="san francisco" /><category term="security" /><category term="bzr" /><category term="netbooks" /><category term="experiments" /><category term="pyrrd" /><category term="cloud" /><category term="natty" /><category term="links" /><category term="devs" /><category term="pycon2009" /><category term="trac" /><category term="libevent" /><category term="transparency" /><category term="genetic programming" /><category term="software" /><category term="o'reilly" /><category term="html" /><category term="errors" /><category term="packt" /><category term="templating" /><category term="pypi" /><category term="interviews" /><category term="operations" /><category term="release" /><category term="testing" /><category term="libev" /><category term="architecture" /><category term="ping.fm" /><category term="itunes" /><category term="computing" /><category term="recursion" /><category term="elixir" /><category term="deployment-poetry" /><category term="articles" /><category term="cgi twisted" /><category term="greenlets" /><category term="asynchronous" /><category term="tx" /><category term="utouch" /><category term="txamqp-sinfonia" /><category term="uds" /><category term="apple" /><category term="evolutionary programming" /><category term="maverick" /><category term="spoofs" /><category term="lucid" /><category term="einstein" /><category term="cern" /><category term="social" /><category term="graphs" /><category term="wearable-computing" /><category term="http" /><category term="graphviz" /><category term="user-interface" /><category term="gnome" /><category term="nextstep" /><category term="rrdtool" /><category term="commands" /><category term="agile" /><category term="kerl" /><category term="python" /><category term="cms" /><category term="internet" /><category term="debian" /><category term="python 3" /><category term="windows" /><category term="autoscaling" /><category term="smartphones" /><category term="ecnomics" /><category term="development frameworks" /><category term="presentations" /><category term="linux" /><category term="docutils" /><category term="miniturization" /><category term="book reviews" /><category term="openstack" /><category term="research" /><category term="rackspace" /><category term="vacation" /><category term="oscon" /><category term="tsf" /><category term="ajax" /><category term="hindi" /><category term="politics" /><category term="programming" /><category term="orchestration" /><category term="foundations" /><category term="culture" /><category term="human-resources" /><category term="games" /><category term="lisp" /><category term="monitoring" /><category term="readline" /><category term="rtf" /><category term="canonical" /><category term="ascii" /><category term="configuration management" /><category term="vde" /><category term="signals" /><category term="companies" /><category term="windowmaker" /><category term="programming methodologies" /><category term="meetups" /><category term="xorg" /><category term="tcp" /><category term="comet" /><category term="turing machine" /><category term="zenoss" /><category term="economics" /><category term="jobs" /><category term="qa" /><category term="hacks" /><category term="von neumann" /><category term="food" /><category term="headcrabs" /><category term="orm" /><category term="entertainment" /><category term="languages" /><category term="intellectual property" /><category term="history" /><category term="dreamhost" /><category term="fixes" /><category term="command line" /><category term="revolution" /><category term="data" /><category term="after-cloud" /><category term="landscape" /><category term="functional-programming" /><category term="utilities" /><category term="tahoe" /><title>Electric Duncan</title><subtitle type="html">i t   a l l   c o m e s   d o w n   t o   I / O ,   e v e n t u a l l y</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://technicae.cogitat.io/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>326</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ElectricDuncan" /><feedburner:info uri="electricduncan" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>39.735745</geo:lat><geo:long>-105.193374</geo:long><logo>http://farm7.staticflickr.com/6101/7022844219_1fb7d5271e_o.png</logo><feedburner:emailServiceId>ElectricDuncan</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><entry gd:etag="W/&quot;C0QHSH8zfip7ImA9WhBVF0s.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-434503138479121633</id><published>2013-04-23T16:55:00.000-07:00</published><updated>2013-04-23T16:55:39.186-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-23T16:55:39.186-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="openstack" /><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="development" /><category scheme="http://www.blogger.com/atom/ns#" term="autoscaling" /><category scheme="http://www.blogger.com/atom/ns#" term="community" /><category scheme="http://www.blogger.com/atom/ns#" term="planning" /><category scheme="http://www.blogger.com/atom/ns#" term="orchestration" /><category scheme="http://www.blogger.com/atom/ns#" term="lbaas" /><category scheme="http://www.blogger.com/atom/ns#" term="heat" /><category scheme="http://www.blogger.com/atom/ns#" term="configuration management" /><category scheme="http://www.blogger.com/atom/ns#" term="rackspace" /><title>OpenStack Developer Summit: Heat Followup</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-2hnHY6RH64w/UVxf7PCDPvI/AAAAAAAAAEI/F2fdJljI62g/s1600/openstack-logo52.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-2hnHY6RH64w/UVxf7PCDPvI/AAAAAAAAAEI/F2fdJljI62g/s1600/openstack-logo52.png" height="200" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
Folks are finally starting to recover from the OpenStack Developer Summit that was held in Portland, Oregon recently. All reports indicate that it was a truly phenomenal experience, record-breaking in many ways, and something that has inspired incredible enthusiasm within the community. And that's great news, since there's an enormous amount of work to be done this release ;-)&lt;br /&gt;
&lt;br /&gt;
Of particular &lt;a href="http://technicae.cogitat.io/2013/04/autoscale-and-orchestration-heat-of.html"&gt;importance to many&lt;/a&gt; in the community is the work around maturing the autoscaling feature in &lt;a href="https://wiki.openstack.org/wiki/Heat"&gt;OpenStack Heat&lt;/a&gt;. There was a fantastic session at the summit, facilitated by the bow-tied and most dapper Ken Wronkiewicz (&lt;a href="http://www.rackspace.com/blog/the-heat-is-on-for-autoscaling-at-openstack-summit-portland/"&gt;his notes from the Summit&lt;/a&gt; were published on the Rackspace blog). &lt;br /&gt;
&lt;br /&gt;
In preparation for the session, the following resources were created:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blueprints.launchpad.net/heat/+spec/heat-autoscaling"&gt;https://blueprints.launchpad.net/heat/+spec/heat-autoscaling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://etherpad.openstack.org/heat-autoscaling"&gt;https://etherpad.openstack.org/heat-autoscaling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://summit.openstack.org/cfp/details/172"&gt;http://summit.openstack.org/cfp/details/172&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
That one in the middle is important, as it is also where notes were taken during the actual session itself (see the section entitled "ODS Session Notes"). Devs at Rackspace have started going through the notes from the session and started planning work around this -- all of which will be carried on in the open, on the OpenStack mail list (tagged with "[Heat]"), on Freenode, and on &lt;a href="https://github.com/openstack/heat/"&gt;github&lt;/a&gt;/&lt;a href="https://review.openstack.org/#/q/status:open,n,z"&gt;gerrit&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The discussion at the Summit indicated strong interest in building a REST API for the existing autoscaling feature. Needless to say, there is a lot involved in this, touching upon significant OpenStack components like Quantum, LBaaS, and Ceilometer. Once the appropriate code is in place, a REST API will need to be created, features will need to be expanded/added, etc., and we'll be off and running :-)&lt;br /&gt;
&lt;br /&gt;
Lots to do, and lots of great energy and excitement around this to keep us all chugging through this cycle.&lt;br /&gt;
&lt;br /&gt;
On that note, we'd like to send out a special "thanks" to all the countless folks who worked so hard to make ODS happen. This event anchors us in a most excellent way, providing the insight and fuel that supports future development work so well!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=oL4onDmS1JI:NUlN-S1dlY0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=oL4onDmS1JI:NUlN-S1dlY0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=oL4onDmS1JI:NUlN-S1dlY0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=oL4onDmS1JI:NUlN-S1dlY0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=oL4onDmS1JI:NUlN-S1dlY0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=oL4onDmS1JI:NUlN-S1dlY0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=oL4onDmS1JI:NUlN-S1dlY0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=oL4onDmS1JI:NUlN-S1dlY0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/oL4onDmS1JI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/434503138479121633/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2013/04/openstack-developer-summit-heat-followup.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/434503138479121633?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/434503138479121633?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/oL4onDmS1JI/openstack-developer-summit-heat-followup.html" title="OpenStack Developer Summit: Heat Followup" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-2hnHY6RH64w/UVxf7PCDPvI/AAAAAAAAAEI/F2fdJljI62g/s72-c/openstack-logo52.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2013/04/openstack-developer-summit-heat-followup.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUNQn88eSp7ImA9WhBVF0g.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-5693343238430975953</id><published>2013-04-23T15:48:00.001-07:00</published><updated>2013-04-23T15:48:13.171-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-23T15:48:13.171-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="standups" /><category scheme="http://www.blogger.com/atom/ns#" term="agile" /><category scheme="http://www.blogger.com/atom/ns#" term="culture" /><category scheme="http://www.blogger.com/atom/ns#" term="tea" /><category scheme="http://www.blogger.com/atom/ns#" term="turing" /><category scheme="http://www.blogger.com/atom/ns#" term="von neumann" /><category scheme="http://www.blogger.com/atom/ns#" term="rackspace" /><category scheme="http://www.blogger.com/atom/ns#" term="einstein" /><title>Tea Time at Rackspace SF</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-7CErHoGdA60/UXb5kkQzw5I/AAAAAAAAAE0/KFhmC2Zq3D4/s1600/traditional-chinese-tea-ceremony.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-7CErHoGdA60/UXb5kkQzw5I/AAAAAAAAAE0/KFhmC2Zq3D4/s1600/traditional-chinese-tea-ceremony.png" height="177" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
One of the Rackspace teams here in the SF office doesn't to standups; it does "tea time" instead. A delightful change, to be sure. One of my coworkers published a &lt;a href="http://www.rackspace.com/blog/tea-time-because-we-wont-stand-for-a-standup/"&gt;Rackspace blog post&lt;/a&gt; about this today.&lt;br /&gt;
&lt;br /&gt;
More than a gratutious reblog, I wanted to highlight this bit of lovely coincidence I came across while reading &lt;a href="http://www.amazon.com/Turings-Cathedral-Origins-Digital-Universe/dp/0375422773"&gt;Turing's Cathedral&lt;/a&gt; last night: &lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
"Afternoon tea— a ritual introduced at Fine Hall by Oswald Veblen, who, according to Herman Goldstine, “tried awfully hard to be an Englishman”— was served on real china daily at exactly three o’clock. According to Oppenheimer, “tea is where we explain to each other what we do not understand.”&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Dyson, George (2012-03-06). Turing's Cathedral: The Origins of the Digital Universe (p. 90). Knopf Doubleday Publishing Group. Kindle Edition.&amp;nbsp; &lt;/i&gt;&lt;/blockquote&gt;
The part of the book where this quote occurred was discussing &lt;a href="http://www.ias.edu/articles/fine-hall"&gt;Fine Hall&lt;/a&gt; 
which was built for Von Neumann's computer team at the Princeton 
Institute for Advanced Studies.&lt;br /&gt;
&lt;br /&gt;
And, yes, tea time is a great time for our team mates to explain to each other what they don't understand.&lt;br /&gt;
&lt;br /&gt;
In case you missed it above, here's the link again:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;a href="http://www.rackspace.com/blog/tea-time-because-we-wont-stand-for-a-standup/"&gt;http://www.rackspace.com/blog/tea-time-because-we-wont-stand-for-a-standup/&lt;/a&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=LUqfPe-1VXg:zeB0gaqwGvs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=LUqfPe-1VXg:zeB0gaqwGvs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=LUqfPe-1VXg:zeB0gaqwGvs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=LUqfPe-1VXg:zeB0gaqwGvs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=LUqfPe-1VXg:zeB0gaqwGvs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=LUqfPe-1VXg:zeB0gaqwGvs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=LUqfPe-1VXg:zeB0gaqwGvs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=LUqfPe-1VXg:zeB0gaqwGvs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/LUqfPe-1VXg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/5693343238430975953/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2013/04/tea-time-at-rackspace-sf.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/5693343238430975953?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/5693343238430975953?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/LUqfPe-1VXg/tea-time-at-rackspace-sf.html" title="Tea Time at Rackspace SF" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-7CErHoGdA60/UXb5kkQzw5I/AAAAAAAAAE0/KFhmC2Zq3D4/s72-c/traditional-chinese-tea-ceremony.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2013/04/tea-time-at-rackspace-sf.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YGQXs-eip7ImA9WhBVEkQ.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-421072588329505406</id><published>2013-04-18T08:32:00.000-07:00</published><updated>2013-04-18T08:32:00.552-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-18T08:32:00.552-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="http" /><category scheme="http://www.blogger.com/atom/ns#" term="async" /><category scheme="http://www.blogger.com/atom/ns#" term="howtos" /><category scheme="http://www.blogger.com/atom/ns#" term="erlang" /><category scheme="http://www.blogger.com/atom/ns#" term="lfe" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><title>Cruising HTTP with LFE</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-fonndtAAXJI/UUAGF-K1LpI/AAAAAAAAADk/YZs-7OwO608/s1600/LispFlavoredErlang-medium.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-fonndtAAXJI/UUAGF-K1LpI/AAAAAAAAADk/YZs-7OwO608/s200/LispFlavoredErlang-medium.png" width="168" /&gt;&lt;/a&gt;&lt;/div&gt;
In the &lt;a href="http://technicae.cogitat.io/2013/04/getting-started-with-lfe-on-ubuntu.html"&gt;last post&lt;/a&gt;, you learned how to get LFE running on Ubuntu. This one will give you some insight into how LFE can be used in something approaching real-world problems. In the next post, we're going to jump back into &lt;a href="http://technicae.cogitat.io/search/label/%CE%BB-calculus"&gt;the lambda calculus&lt;/a&gt;, and we'll see some more LFE shortly after that.&lt;br /&gt;
&lt;br /&gt;
Because &lt;a href="http://lfe.github.io/"&gt;Lisp Flavored Erlang&lt;/a&gt; is 100% compatible with Erlang Core, it has access to all the Erlang libraries, OTP, and many third-party modules, etc.&amp;nbsp; Naturally, this includes the Erlang HTTP client, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;httpc&lt;/span&gt;. Today we're going to be taking a look at how to use &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;httpc&lt;/span&gt; from LFE. Do note, however that this post is only going to provide a taste, just enough to give you a sense of the flavor, as it were. &lt;br /&gt;
&lt;br /&gt;
If you would like more details, be sure to not only give the &lt;a href="http://erlang.org/doc/man/httpc.html"&gt;official docs&lt;/a&gt; a thorough reading, but to take a look at the &lt;a href="http://erlang.org/doc/apps/inets/http_client.html"&gt;HTTP Client section&lt;/a&gt; of the &lt;a href="http://erlang.org/doc/apps/inets/"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;inets&lt;/span&gt; Reference Manual&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Note that for the returned values below, I elide large data structures. If you run them in the LFE REPL yourself, you can view them in all of the line-consuming glory.
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Synchronous &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;GET&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Let's get started with a simple example. The first thing we need to do is start the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;inets&lt;/span&gt; application. With that done, we'll then be able to make client requests:&lt;br /&gt;
&lt;script src="https://gist.github.com/5381504.js?file=http-sync-1.lfe.lisp"&gt;&lt;/script&gt;

Now we can perform an HTTP &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;GET&lt;/span&gt;:
&lt;script src="https://gist.github.com/5381504.js?file=http-sync-2.lfe.lisp"&gt;&lt;/script&gt;

This just makes a straight-forward HTTP request (defaults to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;GET&lt;/span&gt;) and returns a bunch of associated data:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;HTTP version&lt;/li&gt;
&lt;li&gt;status code&lt;/li&gt;
&lt;li&gt;reason phrase&lt;/li&gt;
&lt;li&gt;headers&lt;/li&gt;
&lt;li&gt;body&lt;/li&gt;
&lt;/ul&gt;
All of that data is dumped into our &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;result&lt;/span&gt; variable. Here's the same &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;GET&lt;/span&gt; but with pattern matching set up so that we can easily access all that data:&lt;br /&gt;
&lt;script src="https://gist.github.com/5381504.js?file=http-sync-3.lfe.lisp"&gt;&lt;/script&gt;

For those not familiar with Erlang patterns, we've just told LFE the following:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;the return value of the function we're going to call is going to be a tuple composed of an atom (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;'ok&lt;/span&gt;) and another tuple&lt;/li&gt;
&lt;li&gt;the nested tuple is going to be composed of a tuple, some headers, and a body&lt;/li&gt;
&lt;li&gt;the &lt;i&gt;next&lt;/i&gt; nested tuple is going to be composed of the HTTP version, status code, and status code phrase&lt;/li&gt;
&lt;/ul&gt;
If you'd like to learn more about using patterns in LFE, be sure to view the &lt;a href="http://lfe.github.io/user-guide/diving/5.html"&gt;patterns page&lt;/a&gt; of the LFE User Guide. &lt;br /&gt;
&lt;br /&gt;
Once the request returns, we can check out the variables we set in the pattern:&lt;br /&gt;
&lt;script src="https://gist.github.com/5381504.js?file=http-sync-4.lfe.lisp"&gt;&lt;/script&gt; 
&lt;br /&gt;
That's great if everything goes as expected and we get a response from the server. What happens if we don't?&lt;br /&gt;
&lt;br /&gt;
Well, errors don't have the same nested data structure that the non-error results have, so we're going to have to make some changes to our pattern if we want to extract parts of the error reason. Pattern matching for just the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;'error&lt;/span&gt; atom and the error reason, we can get a sense of what that data structure looks like:&lt;br /&gt;
&lt;script src="https://gist.github.com/5381504.js?file=http-sync-5.lfe.lisp"&gt;&lt;/script&gt; 
&lt;br /&gt;
Looking at just the data stored in the reason variable, we see:&lt;br /&gt;
&lt;script src="https://gist.github.com/5381504.js?file=http-sync-6.lfe.lisp"&gt;&lt;/script&gt;

If you check out the &lt;a href="http://erlang.org/doc/man/httpc.html#request-1"&gt;docs for &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;httpc&lt;/span&gt; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;request&lt;/span&gt;&lt;/a&gt; and look under "Types", you will see that the error returned can be one of three things:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;a tuple of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;connect_failed&lt;/span&gt; and additional data&lt;/li&gt;
&lt;li&gt;a tuple of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send_failed&lt;/span&gt; and additional data&lt;/li&gt;
&lt;li&gt;or just unspecified additional data&lt;/li&gt;
&lt;/ul&gt;
In our example our additional data is a tuple of the address we were trying to connect to and the specific error type that for our failed connection.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Async &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;GET&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Now that we've taken a quick look at the synchronous example, let's make a foray into async. We'll still be using &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;httpc&lt;/span&gt;'s &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;request&lt;/span&gt; function, but we'll need to use one of the longer forms were extra options need to be passed, since that's how you tell the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;request&lt;/span&gt; function to perform the request asynchronously and not synchronously.&lt;br /&gt;
&lt;br /&gt;
For clarity of introducing the additional options, we're going to define some variables first:
&lt;script src="https://gist.github.com/5381591.js?file=http-async-1.lfe.lisp"&gt;&lt;/script&gt;
You can read more about the options in the &lt;a href="http://erlang.org/doc/man/httpc.html#request-1"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;httpc&lt;/span&gt; docs&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
With the variables defined, let's make our async call:
&lt;script src="https://gist.github.com/5381591.js?file=http-async-2.lfe.lisp"&gt;&lt;/script&gt;

The sender receives the results, and since we sent from the LFE REPL, that's the process that will receive the data. Let's keep our pattern simple at first -- just the request id and the result data:&lt;br /&gt;
&lt;script src="https://gist.github.com/5381591.js?file=http-async-3.lfe.lisp"&gt;&lt;/script&gt;

Needless to say, parsing the returned data is a waste of Erlang's pattern matching, so let's go back and do that again, this time with a nice pattern to capture the results. We'll need to do another request, though, so that something gets sent to the shell:&lt;br /&gt;
&lt;script src="https://gist.github.com/5381591.js?file=http-async-4.lfe.lisp"&gt;&lt;/script&gt;

Now we can set up a pattern that will allow us to extract and print just the bits that we're looking for. The thing to keep in mind here is that the scope for the variables is within the receive call, so we'll need to display the values within that scope:&lt;br /&gt;
&lt;script src="https://gist.github.com/5381591.js?file=http-async-5.lfe.lisp"&gt;&lt;/script&gt;

This should demonstrate the slight differences in usage and result patterns between the sync and async modes.&lt;br /&gt;
&lt;br /&gt;
Well, that about sums it up for an intro to the HTTP client in LFE! But one last thing, for the sake of completeness. Once we're done, we can shut down inets:&lt;br /&gt;
&lt;script src="https://gist.github.com/5381591.js?file=http-async-6.lfe.lisp"&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=ATHnopFXsfg:vw_9KarUxFk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=ATHnopFXsfg:vw_9KarUxFk:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=ATHnopFXsfg:vw_9KarUxFk:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=ATHnopFXsfg:vw_9KarUxFk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=ATHnopFXsfg:vw_9KarUxFk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=ATHnopFXsfg:vw_9KarUxFk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=ATHnopFXsfg:vw_9KarUxFk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=ATHnopFXsfg:vw_9KarUxFk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/ATHnopFXsfg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/421072588329505406/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2013/04/cruising-http-with-lfe.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/421072588329505406?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/421072588329505406?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/ATHnopFXsfg/cruising-http-with-lfe.html" title="Cruising HTTP with LFE" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-fonndtAAXJI/UUAGF-K1LpI/AAAAAAAAADk/YZs-7OwO608/s72-c/LispFlavoredErlang-medium.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2013/04/cruising-http-with-lfe.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0EFQX8zfCp7ImA9WhBWGUQ.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-9134345096761195058</id><published>2013-04-14T16:30:00.001-07:00</published><updated>2013-04-14T19:06:50.184-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-14T19:06:50.184-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="kerl" /><category scheme="http://www.blogger.com/atom/ns#" term="repl" /><category scheme="http://www.blogger.com/atom/ns#" term="modules" /><category scheme="http://www.blogger.com/atom/ns#" term="joxa" /><category scheme="http://www.blogger.com/atom/ns#" term="howtos" /><category scheme="http://www.blogger.com/atom/ns#" term="erlang" /><category scheme="http://www.blogger.com/atom/ns#" term="lfe" /><category scheme="http://www.blogger.com/atom/ns#" term="rebar" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="elixir" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Getting Started with LFE on Ubuntu</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-Zqe5Lmg49Sc/UWs6VpQITjI/AAAAAAAAAEk/qO7_SEd0mek/s1600/LFE-on-Ubuntu.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-Zqe5Lmg49Sc/UWs6VpQITjI/AAAAAAAAAEk/qO7_SEd0mek/s320/LFE-on-Ubuntu.png" height="239" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
For those that don't know, there is a fully &lt;a href="http://erlangcentral.org/"&gt;Erlang&lt;/a&gt; Core-compatible &lt;a href="http://en.wikipedia.org/wiki/Lisp-1_vs._Lisp-2#The_function_namespace"&gt;Lisp-2&lt;/a&gt; that runs on the Erlang VM and produces &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.beam&lt;/span&gt; files that can be used in any Erlang application. This manna from heaven is &lt;a href="https://github.com/rvirding/lfe/"&gt;LFE&lt;/a&gt;, or Lisp Flavored Erlang. It was started about 5 years ago by &lt;a href="http://rvirding.blogspot.com/"&gt;Robert Virding&lt;/a&gt;, one of the co-creators of the Erlang programming language, and has inspired other similar efforts: &lt;a href="http://elixir-lang.org/"&gt;Elixir&lt;/a&gt; (a Ruby-alike) and &lt;a href="http://joxa.org/"&gt;Joxa&lt;/a&gt; (a Lisp-1). (Incidentally, Robert has also created &lt;a href="https://github.com/rvirding/erlog"&gt;Prolog&lt;/a&gt; and &lt;a href="https://github.com/rvirding/luerl.git"&gt;Lua&lt;/a&gt; implementations that run on top of the Erlang VM!)&lt;br /&gt;
&lt;br /&gt;
The new &lt;a href="http://lfe.github.io/"&gt;LFE docs site&lt;/a&gt; (a continuous work in progress) has some good introductory materials for the curious reader:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;a href="http://lfe.github.io/quick-start/1.html"&gt;Quick Start&lt;/a&gt; guide &lt;/li&gt;
&lt;li&gt;An as yet incomplete &lt;a href="http://lfe.github.io/user-guide/intro/1.html"&gt;User Guide&lt;/a&gt; (most of the introductory chapters are finished)&lt;/li&gt;
&lt;li&gt;A tutorial on Erlang's &lt;a href="http://lfe.github.io/tutorials/processes/1.html"&gt;Lightweight Processes in LFE&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
This blog post aims to bring some of those hidden materials into the consciousness of Ubuntu users. If you are averse to Erlang syntax, LFE opens up a whole new world to you :-)&lt;br /&gt;
&lt;br /&gt;
The examples below assume Ubuntu 12.10. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Getting Erlang&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Erlang R15B01 comes with Ubuntu 12.10. If that's all you need, then this will suite you just fine:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo apt-get install erlang&lt;/span&gt;&lt;/blockquote&gt;
If you are wanting to test against multiple versions of Erlang, you should check out the &lt;a href="https://github.com/spawngrid/kerl"&gt;kerl&lt;/a&gt; project, which lets you install a wide variety of Erlang versions (including the latest releases) side-by-side.&lt;br /&gt;
&lt;br /&gt;
You'll also need git, if you don't yet have it installed:&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo apt-get install git&lt;/span&gt;&lt;/blockquote&gt;
Currently, &lt;a href="https://github.com/rebar/rebar"&gt;rebar&lt;/a&gt; is required to build all the LFE files. If you're going to be building LFE projects, you'll want this anyway ;-) Rebar will be in Ubuntu 13.04, but it's not in 12.10, so you'll need to get it:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ wget https://github.com/rebar/rebar/wiki/rebar&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ chmod 755 rebar&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo mv rebar /usr/local/bin&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Getting and Building LFE&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Here's what you need to do to build LFE:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ mkdir -p ~/lab/erlang &amp;amp;&amp;amp; cd ~/lab/erlang&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ git clone https://github.com/rvirding/lfe.git&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ cd lfe&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ make compile&lt;/span&gt;&lt;/blockquote&gt;
If you looked at your &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;./ebin&lt;/span&gt; directory when you cloned the repo, you would have seen that there were no &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.beam&lt;/span&gt; files in it. After compiling, it is full of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.beam&lt;/span&gt;s ;-)&lt;br /&gt;
&lt;br /&gt;
Sidebar: A common pattern in Erlang applications is the use of a &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;deps&lt;/span&gt; directory under one's project dir where dependencies can be installed without conflicting with any system-wide installs, providing versioning independence, etc. Managing these with rebar has been very effective for projects, where simply calling &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;rebar compile&lt;/span&gt; puts everything your app needs in &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;./deps&lt;/span&gt;. Projects that depend upon LFE are doing this, but we'll cover that in a future blog post.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Using LFE&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
With everything compiled, we can jump right in! Let's fire up the REPL, and do some arithmetic as a sanity check:&lt;br /&gt;
&lt;script src="https://gist.github.com/5384522.js?file=lfe-repl-1.lfe.lisp"&gt;&lt;/script&gt;

&lt;br /&gt;
How about a message to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;stdout&lt;/span&gt;?&lt;br /&gt;
&lt;script src="https://gist.github.com/5384522.js?file=lfe-repl-2.lfe.lisp"&gt;&lt;/script&gt;

&lt;br /&gt;
Any form starting with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;:&lt;/span&gt; is interpreted as a call to a module. The full form is &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;(: &amp;lt;module name&amp;gt; &amp;lt;function name&amp;gt; &amp;lt;arguments&amp;gt;)&lt;/span&gt;. As such, you can see that we're calling the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;format&lt;/span&gt; function in the (built-in) &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;io&lt;/span&gt; module.&lt;br /&gt;
&lt;br /&gt;
Also, it's good to know that there are certain things that you can't do in the REPL, e.g., defining modules, macros, functions, and records. Erlang expects that these sorts of activities take place in modules. However, we can explore a little more before we write our first module. Let's use the REPL's &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;set&lt;/span&gt; form and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;lambda&lt;/span&gt; to define a function anyway (albeit, in a somewhat awkward fashion):&lt;br /&gt;
&lt;script src="https://gist.github.com/5384522.js?file=lfe-repl-3.lfe.lisp"&gt;&lt;/script&gt;

&lt;br /&gt;
That wasn't too bad ;-) We're seeing the external module call, again -- this time to the math library. Now let's use a module of our own devising...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Creating Modules&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In another terminal (but same working directory), let's create a module in a file called my-module.lfe, with the following content:&lt;br /&gt;
&lt;script src="https://gist.github.com/5384608.js?file=lfe-module-1.lfe.lisp"&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;br /&gt;
Note that the module name in the code needs to match the file name (minus the extension) that you used for the module.&lt;br /&gt;
&lt;br /&gt;
Back in the REPL terminal window, let's compile this module and run the defined function:&lt;br /&gt;
&lt;script src="https://gist.github.com/5384608.js?file=lfe-module-2.lfe.lisp"&gt;&lt;/script&gt;

&lt;br /&gt;
Let's add another function to the module that demonstrates the benefits of Erlang's multiple-arity support:&lt;br /&gt;
&lt;script src="https://gist.github.com/5384608.js?file=lfe-module-3.lfe.lisp"&gt;&lt;/script&gt;

&lt;br /&gt;
Re-compiling and running the functions, we are greeted with success:&lt;br /&gt;
&lt;script src="https://gist.github.com/5384608.js?file=lfe-module-4.lfe.lisp"&gt;&lt;/script&gt;

&lt;br /&gt;
Lastly, let's convert the power function we defined in the previous section using our REPL-workaround to a "real" function, defined in our new module:&lt;br /&gt;
&lt;script src="https://gist.github.com/5384608.js?file=lfe-module-5.lfe.lisp"&gt;&lt;/script&gt;

&lt;br /&gt;
And then let's try it out:&lt;br /&gt;
&lt;script src="https://gist.github.com/5384608.js?file=lfe-module-6.lfe.lisp"&gt;&lt;/script&gt;

&lt;br /&gt;
Perfect.&lt;br /&gt;
&lt;br /&gt;
(Of course, it's rather absurd to redefine &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pow&lt;/span&gt; to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;exp&lt;/span&gt;, when there is basically nothing to gain by it ;-) It's just a quick demo...)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-fonndtAAXJI/UUAGF-K1LpI/AAAAAAAAADk/YZs-7OwO608/s1600/LispFlavoredErlang-medium.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-fonndtAAXJI/UUAGF-K1LpI/AAAAAAAAADk/YZs-7OwO608/s200/LispFlavoredErlang-medium.png" height="200" width="168" /&gt;&lt;/a&gt;&lt;/div&gt;
There's lots more to learn; this has been just a small sip from a hot mug o' LFE.&lt;br /&gt;
&lt;br /&gt;
However, it's definitely enough to get you started and, should you be interested in following along in future LFE blog posts, you'll have everything you need to get the most out of those.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=ggwtEbTVTOU:u1YYyF5iqXw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=ggwtEbTVTOU:u1YYyF5iqXw:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=ggwtEbTVTOU:u1YYyF5iqXw:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=ggwtEbTVTOU:u1YYyF5iqXw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=ggwtEbTVTOU:u1YYyF5iqXw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=ggwtEbTVTOU:u1YYyF5iqXw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=ggwtEbTVTOU:u1YYyF5iqXw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=ggwtEbTVTOU:u1YYyF5iqXw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/ggwtEbTVTOU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/9134345096761195058/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2013/04/getting-started-with-lfe-on-ubuntu.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/9134345096761195058?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/9134345096761195058?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/ggwtEbTVTOU/getting-started-with-lfe-on-ubuntu.html" title="Getting Started with LFE on Ubuntu" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-Zqe5Lmg49Sc/UWs6VpQITjI/AAAAAAAAAEk/qO7_SEd0mek/s72-c/LFE-on-Ubuntu.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2013/04/getting-started-with-lfe-on-ubuntu.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AAR30_fyp7ImA9WhBWFkQ.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-1320441927711091098</id><published>2013-04-10T21:39:00.001-07:00</published><updated>2013-04-11T08:55:46.347-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-11T08:55:46.347-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="λ-calculus" /><category scheme="http://www.blogger.com/atom/ns#" term="notation" /><category scheme="http://www.blogger.com/atom/ns#" term="lambda calculus" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="math" /><title>The Lambda Calculus: A Quick Primer</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-6VOclHLsn8U/UWMiLE5aa0I/AAAAAAAAAEY/SrJ6d2vVi9s/s1600/Lambda.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-6VOclHLsn8U/UWMiLE5aa0I/AAAAAAAAAEY/SrJ6d2vVi9s/s200/Lambda.png" height="200" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;b&gt;The λ-Calculus Series&lt;/b&gt;&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://technicae.cogitat.io/2013/04/the-lambda-calculus-brief-history.html"&gt;A Brief History&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A Quick Primer for λ-Calculus&lt;/li&gt;
&lt;li&gt;Reduction Explained&lt;/li&gt;
&lt;li&gt;Church Numerals&lt;/li&gt;
&lt;li&gt;Arithmetic&lt;/li&gt;
&lt;li&gt;Logic&lt;/li&gt;
&lt;li&gt;Pairs and Lists&lt;/li&gt;
&lt;li&gt;Combinators&lt;/li&gt;
&lt;/ol&gt;
To the untrained eye, the notation used in λ-calculus can be a bit confusing. And by "untrained", I mean your average programmer. This is a travesty: reading the notation of λ-calculus should be as easy to do as recognizing that the following phrase demonstrates variable assignation:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x = 123&lt;/span&gt;&lt;/blockquote&gt;
So how do we arrive at a state of familiarity and clarity from a starting state of confusion? Let's dive in with some examples, and take it step at a time :-) Once we've got our heads wrapped around Alonzo Church's notation, we'll be able to easily read it -- and thus convert it into code! (We will have lots of practice in the coming posts to do just that.)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;A Quick Primer for λ-Calculus&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Here's one of the simplest definitions in λ-calculus that you're going to see: the identity function:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;λx.x&lt;/span&gt;&lt;/blockquote&gt;
This reads as "Here is a function that takes &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x&lt;/span&gt; as an argument and returns &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x&lt;/span&gt;." Let's do some more:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;λxy.x&lt;/span&gt;&lt;/blockquote&gt;
"Here is a function that takes &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;y&lt;/span&gt; as arguments and returns only &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x&lt;/span&gt;."&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;λx.&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;λy.&lt;/span&gt;xy&lt;/span&gt;&lt;/blockquote&gt;
"An outer function takes &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x&lt;/span&gt; as an argument and an inner function takes &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;y&lt;/span&gt; as an argument, returning the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x&lt;/span&gt; and the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;y&lt;/span&gt;." Note that this is exactly equivalent to the following (by convention):&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;λxy.xy&lt;/span&gt;&lt;/blockquote&gt;
Let's up the ante with a function application:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;λf.&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;λ&lt;/span&gt;x.f x&lt;/span&gt;&lt;/blockquote&gt;
"Here is a function that takes a function &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;f&lt;/span&gt; as its argument; the inner function takes &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x&lt;/span&gt; as its argument; return the result of the function &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;f&lt;/span&gt; when given the argument &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x&lt;/span&gt;." For example, if we pass a function &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;f&lt;/span&gt; which returns its input multiplied by 2, and we supplied a value for &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x&lt;/span&gt; as 6, then we would see an output of 12. &lt;br /&gt;
&lt;br /&gt;
Let's take that a little further:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;λ&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;f.&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;λ&lt;/span&gt;x.f (f (f x))&lt;/span&gt;&lt;/blockquote&gt;
"Here is a function that takes a function &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;f&lt;/span&gt; as its argument; the inner 
function takes &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x&lt;/span&gt; as its argument. Apply the function f to the argument &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x&lt;/span&gt;; take that result and apply &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;f&lt;/span&gt; to it. Then do it a third time, returning that result." If we had the same function as the example above and passed the same value, our result this time would be 48 (i.e., 6 * 2 * 2 * 2).&lt;br /&gt;
&lt;br /&gt;
That's most of what you need to read λ-calculus expressions. Next we'll take a peek into the murky waters of&amp;nbsp; λ-calculus reduction and find that it's quite drinkable, that we were just being fooled by the shadows.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=38a_z-AZrDc:wTzu_FUjWDc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=38a_z-AZrDc:wTzu_FUjWDc:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=38a_z-AZrDc:wTzu_FUjWDc:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=38a_z-AZrDc:wTzu_FUjWDc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=38a_z-AZrDc:wTzu_FUjWDc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=38a_z-AZrDc:wTzu_FUjWDc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=38a_z-AZrDc:wTzu_FUjWDc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=38a_z-AZrDc:wTzu_FUjWDc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/38a_z-AZrDc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/1320441927711091098/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2013/04/the-lambda-calculus-quick-primer.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/1320441927711091098?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/1320441927711091098?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/38a_z-AZrDc/the-lambda-calculus-quick-primer.html" title="The Lambda Calculus: A Quick Primer" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-6VOclHLsn8U/UWMiLE5aa0I/AAAAAAAAAEY/SrJ6d2vVi9s/s72-c/Lambda.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2013/04/the-lambda-calculus-quick-primer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEAGRHsycCp7ImA9WhBWFUk.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-7234681690694906707</id><published>2013-04-09T14:24:00.000-07:00</published><updated>2013-04-09T14:25:25.598-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-09T14:25:25.598-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="interviews" /><category scheme="http://www.blogger.com/atom/ns#" term="erlang" /><category scheme="http://www.blogger.com/atom/ns#" term="community" /><category scheme="http://www.blogger.com/atom/ns#" term="scoble" /><category scheme="http://www.blogger.com/atom/ns#" term="conferences" /><title>Interview with Erlang Co-Creators</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-iR9SXsfKR20/UT_3CEIkNKI/AAAAAAAAADU/6ZqJHwDtiIM/s1600/erlang-logo-darkback.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-iR9SXsfKR20/UT_3CEIkNKI/AAAAAAAAADU/6ZqJHwDtiIM/s1600/erlang-logo-darkback.png" height="167" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
A few weeks back -- the week of the PyCon sprints, in fact -- was the &lt;a href="http://www.erlang-factory.com/conference/SFBay2013"&gt;San Francisco Erlang conference&lt;/a&gt;. This was a small conference (I haven't been to one so small since PyCon was at GW in the early 2000s), and absolutely charming as a result. There were some really nifty talks and a lot of fantastic hallway and ballroom conversations... not to mention Robert Virding's very sweet &lt;a href="https://twitter.com/oubiwann/status/316006519646855168/photo/1"&gt;Raspberry Pi Erlang-powered wall-sensing Lego robot&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
My first Erlang Factory, the event lasted for two fun-filled days and culminated with a &lt;a href="https://twitter.com/oubiwann/status/316005811690287104/photo/1"&gt;stroll in the evening sun of San Francisco&lt;/a&gt; down to the Rackspace office where we held a &lt;a href="http://www.meetup.com/Erlang-Factory-SF-Bay-Area/events/109049612/"&gt;Meetup mini-conference&lt;/a&gt; (beer, food, and three more talks). Conversations lasted until well after 10pm with the &lt;a href="https://twitter.com/oubiwann/status/315330456671367168/photo/1"&gt;remaining die-hards&lt;/a&gt; making a trek through the nighttime streets SOMA and the Financial District back to their respective abodes.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-UTNPsMlxcvY/UQBSsj_BQWI/AAAAAAAAADA/SZjwtfYECMw/s1600/RackspaceLogoMedium.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-UTNPsMlxcvY/UQBSsj_BQWI/AAAAAAAAADA/SZjwtfYECMw/s1600/RackspaceLogoMedium.png" height="200" width="191" /&gt;&lt;/a&gt;&lt;/div&gt;
Before the close of the conference, however, we managed to sneak a ride (4 of us in a Mustang) to Scoble's studio and conduct an interview with &lt;a href="http://joearms.github.io/"&gt;Joe Armstrong&lt;/a&gt; and &lt;a href="http://www.erlang-factory.com/conference/SFBay2012/speakers/RobertVirding"&gt;Robert Virding&lt;/a&gt;. We covered some of the basics in order to provide a gentle overview for folks who may not have been exposed to Erlang yet and are curious about what it has to offer our growing multi-core world. This wend up on the &lt;a href="http://www.rackspace.com/blog/rackspace-takes-a-look-at-the-erlang-language/"&gt;Rackspace blog&lt;/a&gt; as well as the &lt;a href="http://www.building43.com/videos/2013/03/26/rackspace-takes-a-look-at-the-erlang-language/"&gt;Building 43&lt;/a&gt; site. We've got a couple of teams using Erlang in Rackspace; if you're interested, be sure to email &lt;a href="mailto:steven.pestorich@RACKSPACE.COM"&gt;Steve Pestorich&lt;/a&gt; and ask him what's available!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=W00WVpAvuxI:z_5UtlrkeH0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=W00WVpAvuxI:z_5UtlrkeH0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=W00WVpAvuxI:z_5UtlrkeH0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=W00WVpAvuxI:z_5UtlrkeH0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=W00WVpAvuxI:z_5UtlrkeH0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=W00WVpAvuxI:z_5UtlrkeH0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=W00WVpAvuxI:z_5UtlrkeH0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=W00WVpAvuxI:z_5UtlrkeH0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/W00WVpAvuxI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/7234681690694906707/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2013/04/interview-with-erlang-co-creators.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/7234681690694906707?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/7234681690694906707?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/W00WVpAvuxI/interview-with-erlang-co-creators.html" title="Interview with Erlang Co-Creators" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-iR9SXsfKR20/UT_3CEIkNKI/AAAAAAAAADU/6ZqJHwDtiIM/s72-c/erlang-logo-darkback.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2013/04/interview-with-erlang-co-creators.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0INRnozcSp7ImA9WhBWFkQ.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-8427610361209978790</id><published>2013-04-08T23:22:00.000-07:00</published><updated>2013-04-11T08:53:17.489-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-11T08:53:17.489-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="λ-calculus" /><category scheme="http://www.blogger.com/atom/ns#" term="turing machine" /><category scheme="http://www.blogger.com/atom/ns#" term="haskell" /><category scheme="http://www.blogger.com/atom/ns#" term="lambda calculus" /><category scheme="http://www.blogger.com/atom/ns#" term="erlang" /><category scheme="http://www.blogger.com/atom/ns#" term="ml" /><category scheme="http://www.blogger.com/atom/ns#" term="lfe" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="history" /><category scheme="http://www.blogger.com/atom/ns#" term="math" /><title>The Lambda Calculus: A Brief History</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-6VOclHLsn8U/UWMiLE5aa0I/AAAAAAAAAEU/WQTM0-l_MxA/s1600/Lambda.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-6VOclHLsn8U/UWMiLE5aa0I/AAAAAAAAAEU/WQTM0-l_MxA/s1600/Lambda.png" height="200" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
Over this past weekend I took a lovely journey into the heart of the lambda calculus, and it was quite amazing. My explorations were made within the context of &lt;a href="https://github.com/rvirding/lfe/"&gt;LFE&lt;/a&gt;. Needless to say, this was a romp of pure delight. In fact, it was &lt;i&gt;so&lt;/i&gt; much fun and helped to clarify for me so many nooks and crannies of something that I had simply not explored very thoroughly in the past, that I &lt;i&gt;had&lt;/i&gt; to share :-)&lt;br /&gt;
&lt;br /&gt;
The work done over the past few days is on its way to becoming part of the &lt;a href="http://lfe.github.io/"&gt;documentation for LFE&lt;/a&gt;. However, this is also an excellent opportunity to share some clarity with a wider audience. As such, I will be writing a series of blog posts on λ-calculus from a very hands-on (almost practical!) perspective. There will be some overlap with the LFE documentation, but the medium is different and as such, the delivery will vary (sometimes considerably).&lt;br /&gt;
&lt;br /&gt;
This series of posts will cover the following topics:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;A Brief History&lt;/li&gt;
&lt;li&gt;&lt;a href="http://technicae.cogitat.io/2013/04/the-lambda-calculus-quick-primer.html"&gt;A Quick Primer for λ-Calculus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Reduction Explained&lt;/li&gt;
&lt;li&gt;Church Numerals&lt;/li&gt;
&lt;li&gt;Arithmetic&lt;/li&gt;
&lt;li&gt;Logic&lt;/li&gt;
&lt;li&gt;Pairs and Lists&lt;/li&gt;
&lt;li&gt;Combinators&lt;/li&gt;
&lt;/ol&gt;
The point of these posts is not to expound upon that which has already been written about endlessly. Rather, the hope is to give a very clear demonstration of what the lambda calculus &lt;i&gt;really&lt;/i&gt; is, and to do so with clear examples and concise prose. When the gentle reader is able see the lambda calculus in action, with lines of code that clearly show what is occurring, the mystery will disappear and an intuition for the subject matter will quite naturally begin to arise. This post is the first in the series; I hope you enjoy them as much as I did rediscovering λ-calculus :-)&lt;br /&gt;
&lt;br /&gt;
Let us start at the beginning... &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;A Brief History&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The roots of functional programming languages such as Lisp, ML, Erlang, Haskell and others, can be traced to the concept of recursion in general and λ-calculus in particular. In previous posts, I touched upon &lt;a href="http://technicae.cogitat.io/2012/12/the-secret-history-of-lambda.html"&gt;how we ended up with the lambda&lt;/a&gt; as a symbol for the anonymous function as well as &lt;a href="http://technicae.cogitat.io/2013/04/maths-and-programming-whence-recursion.html"&gt;how recursion came to be a going concern&lt;/a&gt; in modern mathematics and then computer science.&lt;br /&gt;
&lt;br /&gt;
In both of those posts we saw &lt;a href="http://en.wikipedia.org/wiki/Alonzo_Church"&gt;Alonzo Church&lt;/a&gt; play a major role, but we didn't really spend time on what is quite probably considered his greatest contribution to computer science, if not mathematics itself: λ-calculus. Keep in mind that the &lt;a href="http://en.wikipedia.org/wiki/Peano_axioms"&gt;Peano axioms&lt;/a&gt; made use of recursion, that &lt;a href="http://en.wikipedia.org/wiki/Giuseppe_Peano"&gt;Giuseppe Peano&lt;/a&gt; played a key role in &lt;a href="http://en.wikipedia.org/wiki/Bertrand_Russell"&gt;Bertrand Russell&lt;/a&gt;’s development of the &lt;a href="http://en.wikipedia.org/wiki/Principia_Mathematica"&gt;Principia&lt;/a&gt;, that Alonzo Church sought to make improvements on the Principia, and λ-calculus eventually arose from these efforts.&lt;br /&gt;
&lt;br /&gt;
Invented in 1928, Alonzo didn't publish λ-calculus until 1932. When an inconsistency was discovered, he revised it in 1933 and republished. Furthermore, in this second paper, Church introduced a means of representing positive integers using lambda notation, now known as Church numerals. With Church and Turing both publishing papers on computability in 1936 (based respectively upon λ-calculus and the concept of &lt;a href="http://en.wikipedia.org/wiki/Turing_machine"&gt;Turing machines&lt;/a&gt;), they proposed solutions to the &lt;a href="http://en.wikipedia.org/wiki/Entscheidungsproblem"&gt;Entscheidungsproblem&lt;/a&gt;. Though &lt;a href="http://en.wikipedia.org/wiki/Kurt_G%C3%B6del"&gt;Gödel&lt;/a&gt; preferred Turing's approach, &lt;a href="http://en.wikipedia.org/wiki/J._Barkley_Rosser"&gt;Rosser&lt;/a&gt; suggested that they were equivalent definitions in 1939. A few years later, &lt;a href="http://en.wikipedia.org/wiki/Stephen_Cole_Kleene"&gt;Kleene&lt;/a&gt; proposed the &lt;a href="http://en.wikipedia.org/wiki/Church%27s_thesis_%28constructive_mathematics%29"&gt;Church Thesis&lt;/a&gt; (1943) and then later formally demonstrated the equivalence between his teacher's and Turing's approaches giving the combination the name of the &lt;a href="http://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis"&gt;Church-Turing Thesis&lt;/a&gt; (1952, in his &lt;u&gt;Introduction to Metamathematics&lt;/u&gt;). Within eight years, &lt;a href="http://en.wikipedia.org/wiki/John_McCarthy_%28computer_scientist%29"&gt;John McCarthy&lt;/a&gt; published his now-famous paper describing the work that he had started in 1958: "Recursive Functions of Symbolic Expressions and Their Computation by Machine". In this paper, McCarthy outlined his new programming language Lisp, citing Church's 77-page book&amp;nbsp; (1941, &lt;u&gt;Calculi of Lambda Conversion&lt;/u&gt;), sending the world off in a whole new direction.&lt;br /&gt;
&lt;br /&gt;
Since that time, there has been on-going research into λ-calculus. Indisputably, λ-calculus has had a tremendous impact on research into computability as well as the practical applications of programming languages. As programmers and software engineers, we feel its impact -- directly and indirectly -- on a regular, almost daily basis.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=vo1VocolvTw:sLZR-E3PrOM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=vo1VocolvTw:sLZR-E3PrOM:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=vo1VocolvTw:sLZR-E3PrOM:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=vo1VocolvTw:sLZR-E3PrOM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=vo1VocolvTw:sLZR-E3PrOM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=vo1VocolvTw:sLZR-E3PrOM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=vo1VocolvTw:sLZR-E3PrOM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=vo1VocolvTw:sLZR-E3PrOM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/vo1VocolvTw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/8427610361209978790/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2013/04/the-lambda-calculus-brief-history.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/8427610361209978790?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/8427610361209978790?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/vo1VocolvTw/the-lambda-calculus-brief-history.html" title="The Lambda Calculus: A Brief History" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-6VOclHLsn8U/UWMiLE5aa0I/AAAAAAAAAEU/WQTM0-l_MxA/s72-c/Lambda.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2013/04/the-lambda-calculus-brief-history.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04NQn0zfCp7ImA9WhBWEEk.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-7215023495721058298</id><published>2013-04-03T10:03:00.000-07:00</published><updated>2013-04-03T19:19:53.384-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-03T19:19:53.384-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="openstack" /><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="autoscaling" /><category scheme="http://www.blogger.com/atom/ns#" term="community" /><category scheme="http://www.blogger.com/atom/ns#" term="orchestration" /><category scheme="http://www.blogger.com/atom/ns#" term="heat" /><category scheme="http://www.blogger.com/atom/ns#" term="configuration management" /><title>Autoscale and Orchestration: the Heat of OpenStack</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-2hnHY6RH64w/UVxf7PCDPvI/AAAAAAAAAEE/baimMc7CxHM/s1600/openstack-logo52.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-2hnHY6RH64w/UVxf7PCDPvI/AAAAAAAAAEE/baimMc7CxHM/s200/openstack-logo52.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
Several months before I joined Rackspace last year, there were efforts under way to provide an Autoscaling solution for Rackspace customers. Features that we needed in OpenStack and Heat hadn't been released yet, and there were no OpenStack experts on the Autoscaling team. As such, the engineers began developing a product that met Rackspace customer needs, integrated with the&lt;br /&gt;
existing monitoring and load-balancing infrastructure, and made calls to OpenStack Nova APIs as part of the scaling up and down process.&lt;br /&gt;
&lt;br /&gt;
At PyCon this year, Monty Taylor, Robert Collins, Clint Byrum, Devananda van der Veen, and I caught up and chatted about what their views were of the current status of autoscaling support in OpenStack Heat. It seems that the two pieces we need the most -- LBaas and support for external monitoring systems (perhaps via webhooks) -- are nascent and not ready for prime-time yet. Regardless, Monty and his team encouraged us to dive into Heat, contribute patches, and in general, release our work for consumption by other Stackers.&lt;br /&gt;
&lt;br /&gt;
Deeply encouraged by these interactions, we took this information to Rackspace management and, to quote Monty Python, &lt;a href="http://www.youtube.com/watch?v=enSYlCEz5VI"&gt;there was much rejoicing&lt;/a&gt;. Obviously OpenStack is huge for Rackspace. Even more, there is a lot of excitement about Heat, the existing autoscaling features in OpenStack, and getting our engineers involved and contributing to these efforts.&lt;br /&gt;
&lt;br /&gt;
In the course of these conversations, we discovered that Heat was getting lots of attention internally. It turns out that another internal Rackspace project had been doing something pretty cool: they were experimenting with the development of a portable syntax for application description and deployment orchestration. Their work had started to converge on some of the functionality provided by Heat, and they had a similar experience as the Autoscaling team. The timing was right to contribute what they have learned and align all of their continued efforts with adding value to Heat.&lt;br /&gt;
&lt;br /&gt;
Along these lines, we are building &lt;a href="http://lists.openstack.org/pipermail/openstack-dev/2013-April/007126.html"&gt;two new teams&lt;/a&gt; that will focus on Heat development: one &lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-UTNPsMlxcvY/UQBSsj_BQWI/AAAAAAAAADA/SZjwtfYECMw/s1600/RackspaceLogoMedium.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://3.bp.blogspot.com/-UTNPsMlxcvY/UQBSsj_BQWI/AAAAAAAAADA/SZjwtfYECMw/s200/RackspaceLogoMedium.png" width="191" /&gt;&lt;/a&gt;&lt;/div&gt;
contributing to features related to autoscaling (not necessarily limited to Heat) and the other contributing to the ongoing conversations regarding the separation of concerns between orchestration and configuration management. Everyone -- from engineers to management -- is very excited about this new direction in which our teams are moving. Not only will it bring new developers to OpenStack, but it is aligning our teams with Rackspace's OpenStack roots and the company's vision for supporting the growing cloud community.&lt;br /&gt;
&lt;br /&gt;
Simply put: we're pretty damned pumped and looking forward to more good times with OpenStack :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=qL_4LL37XWY:0nPUp8LrWR0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=qL_4LL37XWY:0nPUp8LrWR0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=qL_4LL37XWY:0nPUp8LrWR0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=qL_4LL37XWY:0nPUp8LrWR0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=qL_4LL37XWY:0nPUp8LrWR0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=qL_4LL37XWY:0nPUp8LrWR0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=qL_4LL37XWY:0nPUp8LrWR0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=qL_4LL37XWY:0nPUp8LrWR0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/qL_4LL37XWY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/7215023495721058298/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2013/04/autoscale-and-orchestration-heat-of.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/7215023495721058298?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/7215023495721058298?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/qL_4LL37XWY/autoscale-and-orchestration-heat-of.html" title="Autoscale and Orchestration: the Heat of OpenStack" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-2hnHY6RH64w/UVxf7PCDPvI/AAAAAAAAAEE/baimMc7CxHM/s72-c/openstack-logo52.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2013/04/autoscale-and-orchestration-heat-of.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UFQHg6cSp7ImA9WhBXGUk.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-5989945146803525157</id><published>2013-04-02T17:33:00.000-07:00</published><updated>2013-04-02T17:33:31.619-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-02T17:33:31.619-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="recursion" /><category scheme="http://www.blogger.com/atom/ns#" term="lambda calculus" /><category scheme="http://www.blogger.com/atom/ns#" term="research" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="category theory" /><category scheme="http://www.blogger.com/atom/ns#" term="history" /><category scheme="http://www.blogger.com/atom/ns#" term="math" /><category scheme="http://www.blogger.com/atom/ns#" term="functions" /><category scheme="http://www.blogger.com/atom/ns#" term="computing" /><title>Maths and Programming: Whence Recursion?</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-c1OHL64rUD0/UHtJyO5kp0I/AAAAAAAAAFw/3oGNoK636e0/s1600/Lambda.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-c1OHL64rUD0/UHtJyO5kp0I/AAAAAAAAAFw/3oGNoK636e0/s200/Lambda.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
As a manager in the software engineering industry, one of the things that I see on a regular basis is a general lack of knowledge from less experienced developers (not always "younger"!) with regard to the foundations of computing and the several related fields of mathematics. There is often a great deal of focus on what the hottest new thing is, or how the industry can be changed, or how we can innovate on the decades of profound research that has been done. All noble goals.&lt;br /&gt;
&lt;br /&gt;
Notably, another trend I've recognized is that in a large group of devs, there are often a committed few who &lt;i&gt;really&lt;/i&gt; know their field and its history. That is always so amazing to me and I have a great deal of admiration for the commitment and passion they have for their art. Let's have more of that :-)&lt;br /&gt;
&lt;br /&gt;
As for myself, these days I have many fewer hours a week which I can dedicate to programming compared to what I had 10 years ago. This is not surprising, given my career path. However, what it &lt;i&gt;has&lt;/i&gt; meant is that I have to be much more focused when I do get those precious few hours a night (and sometimes just a few per week!). I've managed this in an ad hoc manner by taking quick notes about fields of study that pique my curiosity. Over time, these get filtered and a few pop to the top that I really want to give more time.&lt;br /&gt;
&lt;br /&gt;
One of the driving forces of this filtering process is my never-ending curiosity: "&lt;i&gt;Why&lt;/i&gt; is it that way?" "How did this come to be?" "What is the &lt;i&gt;history&lt;/i&gt; behind that convention?" I tend to keep these musings to myself, exploring them at my leisure, finding some answers, and then moving on to the next question (usually this takes several weeks!).&lt;br /&gt;
&lt;br /&gt;
However, given the observations of the recent years, I thought it might be constructive to ponder aloud, as it were. To explore in a more public forum, to set an example that the vulnerability of curiosity and "not knowing" is quite okay, that even those of us with lots of time in the industry are constantly learning, constantly asking.&lt;br /&gt;
&lt;br /&gt;
My latest curiosity has been around recursion: who first came up with it? How did it make it's way from abstract maths to programming languages? How did it enter the consciousness of so many software engineers (especially those who are at ease in functional programming)? It turns out that an answer to this is actually quite closely related to a previous post I wrote on &lt;a href="http://technicae.cogitat.io/2012/12/the-secret-history-of-lambda.html"&gt;the secret history of lambda&lt;/a&gt;. A short version goes something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Giuseppe_Peano"&gt;Giuseppe Peano&lt;/a&gt; wanted to establish a firm foundation for logic and maths in general. As part of this, he ended up creating &lt;a href="http://en.wikipedia.org/wiki/Peano_axioms"&gt;consistent axioms&lt;/a&gt; around the hard-to-define natural numbers, counting, and arithmetic operations (which utilized recursion).&amp;nbsp; While visiting a conference in Europe, &lt;a href="http://en.wikipedia.org/wiki/Bertrand_russell"&gt;Bertrand Russell&lt;/a&gt; was deeply impressed by the dialectic talent of Peano and his unfailing clarity; he queried Peano as to his secret for success (Peano told him) and them asked for all of his published works. Russell proceeded to studied these quite deeply and eventually co-wrote the &lt;a href="http://en.wikipedia.org/wiki/Principia_mathematica"&gt;Principia Mathematica&lt;/a&gt;, which &lt;a href="http://en.wikipedia.org/wiki/Alonzo_Church"&gt;Alonzo Church&lt;/a&gt; (along with his grad students) sought to improve upon later. Alonzo Church ended up developing the &lt;a href="http://en.wikipedia.org/wiki/Lambda_calculus"&gt;lambda calculus&lt;/a&gt; based on his work around the Principia and his student, &lt;a href="http://en.wikipedia.org/wiki/John_McCarthy_%28computer_scientist%29"&gt;John McCarthy&lt;/a&gt;, later created the first functional programming language, &lt;a href="http://en.wikipedia.org/wiki/Lisp_%28programming_language%29"&gt;Lisp&lt;/a&gt;, utilizing concepts from the lambda calculus (recursion and function composition).&lt;br /&gt;
&lt;br /&gt;
In the course of reading between 40-50 mathematics papers (including various histories) over the last week, I have learned far more than I had originally intended. So much so, in fact, that I'm currently working on a very fun recursion tutorial that not only covers the usual practical stuff, but steps the reader through programming implementations of the Peano axioms, arithmetic definitions, the Ackermann function, and parts of the lambda calculus.&lt;br /&gt;
&lt;br /&gt;
I've got a few more blog post ideas cooking that dive into functions, their history and evolution. We'll see how those pan out. Even more exciting, though, was having found interesting papers discussing the evolution of functions and the birth of &lt;a href="http://en.wikipedia.org/wiki/Category_theory"&gt;category theory&lt;/a&gt; from algebraic topology. This, needless to say, spawned a whole new trail of research, papers, and books... and I've got some great ideas for future blog posts/tutorials around this topic as well. (I've encountered category theory before, but watching it appear unsearched and unbidden in the midst of the other reading was quite delightful).&lt;br /&gt;
&lt;br /&gt;
In closing, I enjoy reading not only the original papers (and correspondence between great thinkers of a previous era), but also the meanderings and rediscoveries of my peers. I've run across blog posts like this in the past, and they were quite enchanting. I hope that we continue to foster that in our industry, and that we see more examples of it in the future.&lt;br /&gt;
&lt;br /&gt;
Keep on questing ;-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=fs7k_bfXrs0:RAHB4RRDBLY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=fs7k_bfXrs0:RAHB4RRDBLY:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=fs7k_bfXrs0:RAHB4RRDBLY:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=fs7k_bfXrs0:RAHB4RRDBLY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=fs7k_bfXrs0:RAHB4RRDBLY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=fs7k_bfXrs0:RAHB4RRDBLY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=fs7k_bfXrs0:RAHB4RRDBLY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=fs7k_bfXrs0:RAHB4RRDBLY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/fs7k_bfXrs0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/5989945146803525157/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2013/04/maths-and-programming-whence-recursion.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/5989945146803525157?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/5989945146803525157?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/fs7k_bfXrs0/maths-and-programming-whence-recursion.html" title="Maths and Programming: Whence Recursion?" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-c1OHL64rUD0/UHtJyO5kp0I/AAAAAAAAAFw/3oGNoK636e0/s72-c/Lambda.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2013/04/maths-and-programming-whence-recursion.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IHRn05fCp7ImA9WhBQEUU.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-4020090730405770225</id><published>2013-03-13T06:07:00.000-07:00</published><updated>2013-03-13T07:38:57.324-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-13T07:38:57.324-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="meetup" /><category scheme="http://www.blogger.com/atom/ns#" term="erlang" /><category scheme="http://www.blogger.com/atom/ns#" term="san francisco" /><category scheme="http://www.blogger.com/atom/ns#" term="sf" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="events" /><category scheme="http://www.blogger.com/atom/ns#" term="rackspace" /><category scheme="http://www.blogger.com/atom/ns#" term="languages" /><title>Erlang Meetup at Rackspace, San Francisco</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-iR9SXsfKR20/UT_3CEIkNKI/AAAAAAAAADQ/7uiieRBkAxk/s1600/erlang-logo-darkback.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="167" src="http://1.bp.blogspot.com/-iR9SXsfKR20/UT_3CEIkNKI/AAAAAAAAADQ/7uiieRBkAxk/s200/erlang-logo-darkback.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
I'm very pleased to announce that &lt;a href="http://www.rackspace.com/"&gt;Rackspace&lt;/a&gt;'s San Francisco office will be hosting an Erlang Meetup immediately after the closing session of last day of &lt;a href="http://www.erlang-factory.com/conference/SFBay2013"&gt;SF Erlang Factory&lt;/a&gt; on 22 March.&lt;br /&gt;
&lt;br /&gt;
We are honored to announce that both &lt;a href="http://www.erlang-factory.com/conference/SFBay2012/speakers/RobertVirding"&gt;Robert Virding&lt;/a&gt; and &lt;a href="http://www.oreillynet.com/pub/au/3373"&gt;Francesco Cesarini&lt;/a&gt; will be present for the event. The night will open up at 6:30pm with Mediterranean food, refreshments (and I hear there will be a keg). Around 7:15pm we will gather for a presentation by the very talented folks at &lt;a href="http://boundary.com/"&gt;Boundary&lt;/a&gt; which will start at 7:30pm.&lt;br /&gt;
&lt;br /&gt;
The Boundary presentation will be followed by one from Robert Virding. We'll finish the night with a door prize give-away of two copies of Francesco and Simon's book &lt;a href="http://shop.oreilly.com/product/9780596518189.do"&gt;Erlang Programming: A Concurrent Approach to Software Development&lt;/a&gt;. Perhaps the winners might be able to talk Francesco into signing their copies? ;-)&lt;br /&gt;
&lt;br /&gt;
Last but not least, some of Rackspace's own Erlangers will be on hand for conversations about how we're using Erlang/OTP to deliver Fanatical Support in in our Data Center and Cloud Ops groups.&lt;br /&gt;
&lt;br /&gt;
We're going to start with a cap of 60 people for the event, but if there's high demand, we have room to adjust this. &lt;strike&gt;Due to some communications hiccups, we're going to do the planning for this event the old-fashioned way: send an email to &lt;a href="mailto:duncan.mcgreggor@rackspace.com"&gt;duncan.mcgreggor@rackspace.com&lt;/a&gt;, and let me know that you'd like to attend. Your name will be added to the list in the order I receive emails. The list of attendees and the waiting list are published &lt;a href="https://docs.google.com/spreadsheet/pub?key=0AoC0RV1sEkGmdEJWUlJYMmg0THpkUW5uOHFFaVR2OFE&amp;amp;single=true&amp;amp;gid=0&amp;amp;output=html"&gt;here&lt;/a&gt; and will be refreshed with each new addition&lt;/strike&gt;.&lt;br /&gt;
&lt;br /&gt;
Update! The event is now published on &lt;a href="http://www.meetup.com/Erlang-Factory-SF-Bay-Area/events/109049612/"&gt;meetup.com&lt;/a&gt; -- Thanks for all your help, Andra!&lt;br /&gt;
&lt;br /&gt;
As special thanks go out to Robert Virding, &lt;a href="http://philtoland.com/"&gt;Phil Toland&lt;/a&gt;, and &lt;a href="http://blog.troutwine.us/"&gt;Brian Troutwine&lt;/a&gt; -- conversations with them were the inspiration for putting this event together. Thanks guys! (Note that I've put that background info into &lt;a href="http://technicae.cogitat.io/2013/03/lisp-flavored-erlang.html"&gt;its own blog post&lt;/a&gt;, so as not to confuse the event announcement ... to much ;-) ).&lt;br /&gt;
&lt;br /&gt;
See you at Erlang Factory SF and then on Friday at the Rackspace office!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=J0cHWjCT2kA:iJA6yTCk6sg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=J0cHWjCT2kA:iJA6yTCk6sg:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=J0cHWjCT2kA:iJA6yTCk6sg:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=J0cHWjCT2kA:iJA6yTCk6sg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=J0cHWjCT2kA:iJA6yTCk6sg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=J0cHWjCT2kA:iJA6yTCk6sg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=J0cHWjCT2kA:iJA6yTCk6sg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=J0cHWjCT2kA:iJA6yTCk6sg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/J0cHWjCT2kA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/4020090730405770225/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2013/03/erlang-meetup-at-rackspace-san-francisco.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/4020090730405770225?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/4020090730405770225?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/J0cHWjCT2kA/erlang-meetup-at-rackspace-san-francisco.html" title="Erlang Meetup at Rackspace, San Francisco" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-iR9SXsfKR20/UT_3CEIkNKI/AAAAAAAAADQ/7uiieRBkAxk/s72-c/erlang-logo-darkback.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2013/03/erlang-meetup-at-rackspace-san-francisco.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MGQH4-fSp7ImA9WhBQEUg.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-5976133893839135205</id><published>2013-03-12T23:17:00.000-07:00</published><updated>2013-03-12T23:17:01.055-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-12T23:17:01.055-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="twisted" /><category scheme="http://www.blogger.com/atom/ns#" term="erlang" /><category scheme="http://www.blogger.com/atom/ns#" term="documentation" /><category scheme="http://www.blogger.com/atom/ns#" term="community" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="lfe" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="rackspace" /><title>Lisp Flavored Erlang</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-fonndtAAXJI/UUAGF-K1LpI/AAAAAAAAADg/rcLT5-XGjnU/s1600/LispFlavoredErlang-medium.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/-fonndtAAXJI/UUAGF-K1LpI/AAAAAAAAADg/rcLT5-XGjnU/s200/LispFlavoredErlang-medium.png" width="168" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
I've flirted with Lisp since the 90s, really started getting into it around 2008 when I started playing with genetic programming, and more recently investigated Common Lisp, Scheme (&lt;a href="http://gambitscheme.org/"&gt;Gambit&lt;/a&gt; and &lt;a href="http://www.call-cc.org/"&gt;Chicken&lt;/a&gt;), and Clojure with the intent of discovering the best way to write distributed programs in Lisp. (I even seriously explored implementing chunks of &lt;a href="http://twistedmatrix.com/"&gt;Twisted&lt;/a&gt; in Common Lisp. If only I had more time...)&lt;br /&gt;
&lt;br /&gt;
Needless to say, I kept coming back to Erlang as it is a natural choice for the sort of concurrent programming I was interested in doing. On several occasions, I'd run across &lt;a href="https://github.com/rvirding/lfe"&gt;Robert Virding's Lisp-2&lt;/a&gt; that he had written on top of the Erlang VM. At first blush, this appeared quite promising. Yet faced with the perceived burden of learning Erlang, I consistently set it aside for a future date.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-size: x-large;"&gt;"Excuse me, could I have some Erlang, please? Yes, just a cup. Oh, and can I get that Lisp-flavored? Thanks so much." &lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
After bouncing between Clojure and CL, after running into difficulties with Termite on Chicken Scheme, and finally, after being quite impressed with the efforts made by the &lt;a href="http://elixir-lang.org/"&gt;Elixir&lt;/a&gt; folks (who I believe took inspiration from LFE!), I decided to give LFE a chance. Within minutes of that decision, I came to two conclusions:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;LFE is &lt;i&gt;brilliant&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;LFE needs docs like Elixir... and tutorials... and &lt;i&gt;exposure&lt;/i&gt;! Why haven't I been using LFE all along?!&lt;/li&gt;
&lt;/ol&gt;
At which point, I started hacking on some docs to see if I could stick with it. When, after a few days, I proved to myself that I could, I contacted Robert and let him know not only how much I adored his masterpiece, but that I really wanted to write tons and tons of docs for it so that &lt;i&gt;anyone&lt;/i&gt; could pick it up and start using it right away. I wanted to write docs for an audience like me, that didn't know Erlang, who weren't Lisp gurus.&lt;br /&gt;
&lt;br /&gt;
This seemed like a doable goal, since I had about 5 minutes' worth of Erlang experience at the time I was having these conversations with Robert. I was learning Erlang at a rapid pace simply by virtue of the Lisp hook that LFE provided.&lt;br /&gt;
&lt;br /&gt;
Our interactions led to the publicizing of the &lt;a href="http://lfe.github.com/"&gt;new docs site for Lisp Flavored Erlang&lt;/a&gt; on the &lt;a href="http://groups.google.com/group/lisp-flavoured-erlang"&gt;LFE google groups list&lt;/a&gt;. We also created a Twitter account (we both have full access to it, but I tend to maintain it) whose sole purpose is to bring LFE to more people, keep the news around LFE fresh, etc.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-size: x-large;"&gt;"I could have sworn you just said 'Lisp'..."&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
A side note about Lisp: S-expressions are concise and elegant. Code and data using the same form is quite powerful. I do believe that the technology industry has the capacity to realize that old biases against Lisp are just that: old and outdated. The many dialects of Lisp are anything but. Clojure and (I believe) LFE are perfect examples of this. Whole new generations of programmers are delighting in the expressive power of a language whose roots can be traced back to &lt;a href="http://www-formal.stanford.edu/jmc/history/lisp/node2.html"&gt;actual manipulations of memory registers&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
To resume the narrative: in the course of various efforts focused on documenting LFE, asking questions on the mail list, and having various other discussions, Robert pointed out that some of my coworkers at &lt;a href="http://www.rackspace.com/"&gt;Rackspace&lt;/a&gt; had been &lt;a href="http://www.rackspace.com/blog/how-rackspace-is-using-erlang/"&gt;working on Erlang projects&lt;/a&gt;. I subsequently reached out to Phil Toland. Then, within minutes of this (and entirely coincidentally), Kai Janson emailed a group of us about &lt;a href="http://www.erlang-factory.com/conference/SFBay2013"&gt;Erlang Factory SF&lt;/a&gt; and his desire to provide Erlang workshops for engineers at Rackspace.&lt;br /&gt;
&lt;br /&gt;
This led to further conversations with Robert, then with Francesco, with several Rackers signing up for Erlang Factory this year, and finally, with me volunteering to put a Meetup together afterwards, hosted at Rackspace's SF office (more on that in a few hours).&lt;br /&gt;
&lt;br /&gt;
For the curious, I do continue to work in Python and Twisted; I am excited about the new &lt;a href="http://www.python.org/dev/peps/pep-3156/"&gt;async support&lt;/a&gt; that Guido is spearheading for Python 3 and which has electrified so many hard-core Python hackers. Similarly, I continue to hack on Common Lisp projects. However, I am quite delighted that I have found a way to interface with Erlang which matches how I think, matches my aesthics. And finally, I look forward to many fruitful years of LFE in my life :-)&lt;br /&gt;
&lt;br /&gt;
Thanks Joe! Thanks Mike! Thanks Robert!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=meup0ugHZAg:9CSocOP0ZXI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=meup0ugHZAg:9CSocOP0ZXI:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=meup0ugHZAg:9CSocOP0ZXI:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=meup0ugHZAg:9CSocOP0ZXI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=meup0ugHZAg:9CSocOP0ZXI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=meup0ugHZAg:9CSocOP0ZXI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=meup0ugHZAg:9CSocOP0ZXI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=meup0ugHZAg:9CSocOP0ZXI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/meup0ugHZAg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/5976133893839135205/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2013/03/lisp-flavored-erlang.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/5976133893839135205?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/5976133893839135205?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/meup0ugHZAg/lisp-flavored-erlang.html" title="Lisp Flavored Erlang" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-fonndtAAXJI/UUAGF-K1LpI/AAAAAAAAADg/rcLT5-XGjnU/s72-c/LispFlavoredErlang-medium.png" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://technicae.cogitat.io/2013/03/lisp-flavored-erlang.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcGQXszfyp7ImA9WhNaEEk.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-1187546927486437739</id><published>2013-01-24T08:47:00.000-08:00</published><updated>2013-01-24T08:47:00.587-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-24T08:47:00.587-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="openstack" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="culture" /><category scheme="http://www.blogger.com/atom/ns#" term="cloud" /><category scheme="http://www.blogger.com/atom/ns#" term="technology" /><category scheme="http://www.blogger.com/atom/ns#" term="node" /><category scheme="http://www.blogger.com/atom/ns#" term="twisted" /><category scheme="http://www.blogger.com/atom/ns#" term="work" /><category scheme="http://www.blogger.com/atom/ns#" term="jobs" /><category scheme="http://www.blogger.com/atom/ns#" term="lua" /><category scheme="http://www.blogger.com/atom/ns#" term="rackspace" /><title>Unbeatable Culture at Rackspace</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-UTNPsMlxcvY/UQBSsj_BQWI/AAAAAAAAADA/SZjwtfYECMw/s1600/RackspaceLogoMedium.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://3.bp.blogspot.com/-UTNPsMlxcvY/UQBSsj_BQWI/AAAAAAAAADA/SZjwtfYECMw/s200/RackspaceLogoMedium.png" width="191" /&gt;&lt;/a&gt;&lt;/div&gt;
Culture is hugely important to me in any company I want to be a part of. Having telecommuted for many years, working in an office environment is a big step. I need to be lured, enticed, and teased. Something needs to overcome the massive convenience of remote work. It's a &lt;i&gt;big&lt;/i&gt; lifestyle change.&lt;br /&gt;
&lt;br /&gt;
A company's culture has been one of the crucial factors in evaluating such a big shift in my daily work. The culture is what makes it worth while -- and fun! -- to endure a commute, work in a shared environment, deal with myriad distractions, etc.&lt;br /&gt;
&lt;br /&gt;
Having spent time visiting and hanging out in many of the top-tier start-up (and established) company offices in the Bay Area, I was very impressed with what Rackspace had to offer: staff, designers, sales, and engineers who were highly gifted, loved their jobs, were fanatically dedicated to their company, and didn't take themselves too seriously. After a long and romantic courtship, I finally took the plunge. Knowing that &lt;a href="http://www.myspace.com/officialjohngorka/music/songs/full-of-life-28448242"&gt;life is full of disappointment&lt;/a&gt;, I was fully aware that this was a risk.&lt;br /&gt;
&lt;br /&gt;
As such, I was pleasantly surprised to find that after a month at Rackspace, the cultural experience was a genuine one. However, I was blown away when I attended &lt;a href="http://rackertalent.com/rackspace-university/the-rookie-o-experience/"&gt;Rookie O&lt;/a&gt; at the beginning of January and experienced the depth of what Rackspace has done for the past 15 years, what they offer on the whole as a company, and how they keep everything real and fun. It was such an eye-opener for me that I had to &lt;a href="http://www.rackspace.com/blog/a-new-hires-perspective-on-rookie-o-and-why-technical-talent-should-want-in/"&gt;blog about it&lt;/a&gt;. Here's a teaser for you:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;em&gt;"This is what I and so many of my peers have been searching for in a 
technical company: a place with heart, room to grow and a vast frontier 
in front of us. The key thing, though, is the heart. That’s the support 
for everything else, and it’s something that often ends up riding in the
 back of the bus on a trip to nowhere. Rackspace has the heart driving
 the bus. This is not a conscious technical criteria for so many of us 
when seeking employment, but it is the reason that we grow so 
dissatisfied at other companies and why Rackspace has been such a 
surprise for me."&lt;/em&gt; &lt;/blockquote&gt;
Incidentally, while drafting that post, two other interesting things happened:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Fortune magazine &lt;a href="http://www.businesswire.com/news/home/20130116006219/en"&gt;named Rackspace&lt;/a&gt; one of the best 100 companies to work for in 2012, and&lt;/li&gt;
&lt;li&gt;Bloomberg released &lt;a href="http://www.businessweek.com/articles/2013-01-16/welcome-to-rackspace-a-frenetic-orientation"&gt;an article about Rookie O&lt;/a&gt; (the same class I was in, oddly; also, note that it's targeted at the "cool," cynical audience ;-) ) &lt;/li&gt;
&lt;/ol&gt;
In 2011 we made Fortune's Top 100 list as well, coming in at #74. This year, we jumped 40 places on that list to #34 :-) How cool is that?!&lt;br /&gt;
&lt;br /&gt;
Rackspace is always hiring, and our San Francisco office is growing as well. We do everything from Twisted and Python to iOS, Node.js, Lua and Java. We're in the cloud, on the desktops, and jumping into mobile devices. If any of this excites you, check out &lt;a href="http://rfer.us/RAX9A.2oh"&gt;the openings&lt;/a&gt;!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=x4rQYfJxa3k:_HYc6PecnCU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=x4rQYfJxa3k:_HYc6PecnCU:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=x4rQYfJxa3k:_HYc6PecnCU:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=x4rQYfJxa3k:_HYc6PecnCU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=x4rQYfJxa3k:_HYc6PecnCU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=x4rQYfJxa3k:_HYc6PecnCU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=x4rQYfJxa3k:_HYc6PecnCU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=x4rQYfJxa3k:_HYc6PecnCU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/x4rQYfJxa3k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/1187546927486437739/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2013/01/unbeatable-culture-at-rackspace.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/1187546927486437739?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/1187546927486437739?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/x4rQYfJxa3k/unbeatable-culture-at-rackspace.html" title="Unbeatable Culture at Rackspace" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-UTNPsMlxcvY/UQBSsj_BQWI/AAAAAAAAADA/SZjwtfYECMw/s72-c/RackspaceLogoMedium.png" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://technicae.cogitat.io/2013/01/unbeatable-culture-at-rackspace.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMASXk_fSp7ImA9WhNVF0w.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-334398815964735468</id><published>2012-12-28T09:34:00.000-08:00</published><updated>2012-12-28T09:57:28.745-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-28T09:57:28.745-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="lambda" /><category scheme="http://www.blogger.com/atom/ns#" term="lambda calculus" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="functional-programming" /><category scheme="http://www.blogger.com/atom/ns#" term="math" /><category scheme="http://www.blogger.com/atom/ns#" term="languages" /><title>The Secret History of Lambda</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-c1OHL64rUD0/UHtJyO5kp0I/AAAAAAAAAFw/3oGNoK636e0/s1600/Lambda.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-c1OHL64rUD0/UHtJyO5kp0I/AAAAAAAAAFw/3oGNoK636e0/s200/Lambda.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
Being a bit of an origins nut (I always want to know &lt;i&gt;how&lt;/i&gt; something came to be or &lt;i&gt;why&lt;/i&gt; it is a certain way), one of the things that always bothered me with regard to Lisp was that no one seemed to talking about the origin of lambda in the lambda calculus. I suppose if I wasn't lazy, I'd have gone to a library and spent some time looking it up. But since I was lazy, I used Wikipedia. Sadly, I never got what I wanted: no history of lambda.&amp;nbsp;[1]&amp;nbsp;Well,&amp;nbsp;certainly&amp;nbsp;some information about the history of the lambda calculus, but not the actual character or term in that context.&lt;br /&gt;
&lt;br /&gt;
Why lambda? Why not gamma or delta? Or &lt;a href="http://en.wikipedia.org/wiki/Siddha%E1%B9%83_alphabet#Conjuncts"&gt;Siddham ṇḍha&lt;/a&gt;?&lt;br /&gt;
&lt;br /&gt;
To my great relief, this question was finally answered when I was reading one of the best Lisp books I've ever read: &lt;a href="http://norvig.com/"&gt;Peter Norvig&lt;/a&gt;'s&amp;nbsp;&lt;a href="http://www.amazon.com/dp/B003VWBY1I/"&gt;Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp&lt;/a&gt;. I'll save my discussion of that book for later; right now I'm going to focus on the paragraph at location 821 of my Kindle edition of the book. [2]&lt;br /&gt;
&lt;br /&gt;
The story goes something like this:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Between 1910 and 1913, &lt;a href="http://en.wikipedia.org/wiki/Alfred_North_Whitehead"&gt;Alfred Whitehead&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Bertrand_Russell"&gt;Bertrand Russell&lt;/a&gt; published three volumes of their &lt;a href="http://en.wikipedia.org/wiki/Principia_Mathematica"&gt;Principia Mathematica&lt;/a&gt;, a work whose purpose was to derive all of mathematics from basic principles in logic. In these tomes, they cover two types of functions: the familiar descriptive functions (defined using relations), and then propositional functions. [3]&lt;/li&gt;
&lt;li&gt;Within the context of propositional functions, the authors make a typographical distinction between free variables and bound variables or functions that have an actual name: bound variables use circumflex notation, e.g. x̂(x+x). [4]&lt;/li&gt;
&lt;li&gt;Around 1928, Church (and then later, with his grad students Stephen Kleene and J. B. Rosser) started attempting to improve upon Russell and Whitehead regarding a foundation for logic. [5]&lt;/li&gt;
&lt;li&gt;Reportedly, Church stated that the use of&amp;nbsp;x̂ in the Principia was for class abstractions, and he needed to distinguish that from function abstractions, so he used &lt;span style="font-size: xx-small;"&gt;⋀&lt;/span&gt;x [6] or ^x [7] for the latter.&lt;/li&gt;
&lt;li&gt;However, these proved to be awkward for different reasons, and an uppercase lambda was used: Λx. [8].&lt;/li&gt;
&lt;li&gt;More awkwardness followed, as this was too easily confused with other symbols (perhaps uppercase delta? logical &lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;and&lt;/span&gt;?). Therefore, he substituted the lowercase λ. [9]&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist)"&gt;John McCarthy&lt;/a&gt; was a student of Alonzo Church and, as such, had inherited Church's notation for functions. When McCarthy invented &lt;a href="http://en.wikipedia.org/wiki/Lisp_(programming_language)"&gt;Lisp&lt;/a&gt; in the late 1950s, he used the lambda notation for creating functions, though unlike Church, he spelled it out. [10]&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
It seems that our beloved &lt;span style="font-family: Courier New, Courier, monospace;"&gt;lambda&lt;/span&gt; [11], then, is an accident in typography more than anything else.&lt;/div&gt;
&lt;br /&gt;
Somehow, this endears lambda to me even more ;-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;span style="font-size: x-small;"&gt;[1] As you can see from the rest of the footnotes, I've done some research since then and have found other references to this history of the lambda notation.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;[2]&amp;nbsp;Norvig, Peter (1991-10-15). Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp (Kindle Locations 821-829). Elsevier Science - A. Kindle Edition. The paragraph in question is quoted here:&lt;/span&gt;&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-size: x-small;"&gt;The name lambda comes from the mathematician Alonzo Church’s notation for functions (Church 1941). Lisp usually prefers expressive names over terse Greek letters, but lambda is an exception. Abetter name would be make - function. Lambda derives from the notation in Russell and Whitehead’s Principia Mathematica, which used a caret over bound variables: x( x + x). Church wanted a one-dimensional string, so he moved the caret in front: ^ x( x + x). The caret looked funny with nothing below it, so Church switched to the closest thing, an uppercase lambda, Λx( x + x). The Λ was easily confused with other symbols, so eventually the lowercase lambda was substituted: λx( x + x). John McCarthy was a student of Church’s at Princeton, so when McCarthy invented Lisp in 1958, he adopted the lambda notation. There were no Greek letters on the keypunches of that era, so McCarthy used (lambda (x) (+ xx)), and it has survived to this day.&lt;/span&gt;&lt;/blockquote&gt;
&lt;span style="font-size: x-small;"&gt;[3]&amp;nbsp;&lt;a href="http://plato.stanford.edu/entries/pm-notation/#4"&gt;http://plato.stanford.edu/entries/pm-notation/#4&lt;/a&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;[4] Norvig, 1991, Location 821.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;[5]&amp;nbsp;&lt;/span&gt;&lt;a href="http://maths.swan.ac.uk/staff/jrh/papers/JRHHislamWeb.pdf" style="font-size: small;"&gt;History of Lambda-calculus and Combinatory Logic&lt;/a&gt;&lt;span style="font-size: x-small;"&gt;, page 7.&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;[6] Ibid.&lt;/span&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;[7] Norvig, 1991, Location 821.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-size: x-small;"&gt;[8] Ibid.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;[9]&amp;nbsp;Looking at Church's works online, he uses lambda notation in his 1932 paper&amp;nbsp;&lt;i&gt;A Set of Postulates for the Foundation of Logic&lt;/i&gt;. His&amp;nbsp;preceding&amp;nbsp;papers upon which the seminal 1932 is based&amp;nbsp;&lt;i&gt;On the Law of Excluded Middle&lt;/i&gt;&amp;nbsp;(1928) and&amp;nbsp;&lt;i&gt;Alternatives to Zermelo's Assumption&lt;/i&gt;&amp;nbsp;(1927), make no reference to lambda notation. As such,&amp;nbsp;&lt;i&gt;A Set of Postulates for the Foundation of Logic&lt;/i&gt;&amp;nbsp;seems to be his first paper that references lambda.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;[10] Norvig indicates that this is simply due to the limitations of the keypunches in the 1950s that did not have keys for Greek letters.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-size: x-small;"&gt;[11] Alex Martelli is not a fan of lambda in the context of Python, and though a good friend of Peter Norvig, I've heard Alex refer to lambda as an abomination :-) So, perhaps not beloved for &lt;/span&gt;&lt;i style="font-size: small;"&gt;everyone&lt;/i&gt;&lt;span style="font-size: x-small;"&gt;. In fact, Peter Norvig himself wrote (see above) that a better name would have been &lt;/span&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"&gt;make-function&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=LKwxMvrdNxw:J_mR-XCo7ek:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=LKwxMvrdNxw:J_mR-XCo7ek:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=LKwxMvrdNxw:J_mR-XCo7ek:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=LKwxMvrdNxw:J_mR-XCo7ek:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=LKwxMvrdNxw:J_mR-XCo7ek:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=LKwxMvrdNxw:J_mR-XCo7ek:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=LKwxMvrdNxw:J_mR-XCo7ek:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=LKwxMvrdNxw:J_mR-XCo7ek:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/LKwxMvrdNxw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/334398815964735468/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/12/the-secret-history-of-lambda.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/334398815964735468?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/334398815964735468?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/LKwxMvrdNxw/the-secret-history-of-lambda.html" title="The Secret History of Lambda" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-c1OHL64rUD0/UHtJyO5kp0I/AAAAAAAAAFw/3oGNoK636e0/s72-c/Lambda.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/12/the-secret-history-of-lambda.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUAASHwzfSp7ImA9WhNWGEg.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-5048633716939690341</id><published>2012-12-18T10:02:00.003-08:00</published><updated>2012-12-18T10:02:29.285-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-18T10:02:29.285-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="maintainers" /><category scheme="http://www.blogger.com/atom/ns#" term="advocates" /><category scheme="http://www.blogger.com/atom/ns#" term="support" /><category scheme="http://www.blogger.com/atom/ns#" term="twisted" /><category scheme="http://www.blogger.com/atom/ns#" term="community" /><category scheme="http://www.blogger.com/atom/ns#" term="jobs" /><category scheme="http://www.blogger.com/atom/ns#" term="devs" /><title>Seeking a Twisted Maintainer</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-Nt_tY2YcsMs/UNCsqmC1U5I/AAAAAAAAACU/kmS7u_R5Hl8/s1600/2000px-Twisted_Logo_(software).png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/-Nt_tY2YcsMs/UNCsqmC1U5I/AAAAAAAAACU/kmS7u_R5Hl8/s200/2000px-Twisted_Logo_(software).png" width="188" /&gt;&lt;/a&gt;&lt;/div&gt;
Last week &lt;a href="http://labs.twistedmatrix.com/2012/12/seeking-motivated-maintainer-for-twisted.html"&gt;we posted&lt;/a&gt; on the Twisted Matrix blog about the maintainer position for the Twisted project being open. We are accepting applicants for a motivated and experienced release manager and core contributor. Our core maintainers are getting busier and busier with specialized Twisted work, and don't have the time that they used to be able to dedicate to maintaining Twisted.&lt;br /&gt;
&lt;br /&gt;
The post on the Twisted Matrix blog gives a quick overview of the position; if you're interested, please check out the &lt;a href="http://twistedmatrix.com/trac/wiki/Fellowship2013"&gt;fellowship proposal&lt;/a&gt;&amp;nbsp;for more details and email the address on that page (at the bottom).&lt;br /&gt;
&lt;br /&gt;
Also, feel free to ping glyph, exarkun, or myself (oubiwann) on #twisted-dev on IRC to chat about it more.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=NCuR2EyQTlw:-OzfRExfono:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=NCuR2EyQTlw:-OzfRExfono:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=NCuR2EyQTlw:-OzfRExfono:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=NCuR2EyQTlw:-OzfRExfono:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=NCuR2EyQTlw:-OzfRExfono:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=NCuR2EyQTlw:-OzfRExfono:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=NCuR2EyQTlw:-OzfRExfono:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=NCuR2EyQTlw:-OzfRExfono:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/NCuR2EyQTlw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/5048633716939690341/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/12/seeking-twisted-maintainer.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/5048633716939690341?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/5048633716939690341?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/NCuR2EyQTlw/seeking-twisted-maintainer.html" title="Seeking a Twisted Maintainer" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-Nt_tY2YcsMs/UNCsqmC1U5I/AAAAAAAAACU/kmS7u_R5Hl8/s72-c/2000px-Twisted_Logo_(software).png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/12/seeking-twisted-maintainer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8NSHo5fyp7ImA9WhNWE0o.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-3907323719699022590</id><published>2012-12-12T17:05:00.000-08:00</published><updated>2012-12-12T20:44:59.427-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-12T20:44:59.427-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tornado" /><category scheme="http://www.blogger.com/atom/ns#" term="async" /><category scheme="http://www.blogger.com/atom/ns#" term="python 3" /><category scheme="http://www.blogger.com/atom/ns#" term="twisted" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="design" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="rackspace" /><category scheme="http://www.blogger.com/atom/ns#" term="languages" /><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><category scheme="http://www.blogger.com/atom/ns#" term="apis" /><title>Async in Python 3</title><content type="html">&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-xO-6jId0QVg/UMkqqDrhMqI/AAAAAAAAAB8/F8pjiP7E_bc/s1600/Logo_Python.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/-xO-6jId0QVg/UMkqqDrhMqI/AAAAAAAAAB8/F8pjiP7E_bc/s200/Logo_Python.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;b&gt;Update&lt;/b&gt;: Guido has been working on &lt;a href="http://www.python.org/dev/peps/pep-3156/"&gt;PEP 3156&lt;/a&gt;; check on it regularly for the latest! (In the last two hours I've seen it updated with three &lt;b&gt;big&lt;/b&gt; content changes.)&lt;br /&gt;
&lt;br /&gt;
The buzz has died down a bit now, but the mellowing of the roaring flames has resulted in some nice embers in which an async for Python 3 is being forged. This is an exciting time for those of us who 1) love Python and 2) can't get us enough async.&lt;br /&gt;
&lt;br /&gt;
I wanted to take the time to record some of the goodness here before I forgot or got too busy working on something else. So here goes:&lt;br /&gt;
&lt;br /&gt;
The latest bout of Python async fever started in September of 2012 in &lt;a href="http://mail.python.org/pipermail/python-ideas/2012-September/016185.html"&gt;this message&lt;/a&gt; when&amp;nbsp;Christian M. Amsüss emailed the Python-ideas mail list about the state of async in Python and the hopes that a roadmap could be decided upon for Python 3. Note that this is the latest (re)incarnation of conversations that have been going on for some time and for which there is even a &lt;a href="http://www.python.org/dev/peps/pep-3153/"&gt;PEP&lt;/a&gt;&amp;nbsp;(with &lt;a href="https://github.com/lvh/async-pep"&gt;related work&lt;/a&gt;&amp;nbsp;on github).&lt;br /&gt;
&lt;br /&gt;
After a few tens of messages were exchanged, Guido &lt;a href="http://mail.python.org/pipermail/python-ideas/2012-October/016424.html"&gt;shared his thoughts&lt;/a&gt;, starting with:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;i&gt;This is an incredibly important discussion.&lt;/i&gt;&lt;/blockquote&gt;
This seemed to really heat things up, eventually with core Twisted and Tornado folks chiming in. I learned a tremendous amount from the discussions that took place. There's probably a book deal in all that for a motivated archivist/interviewer...&lt;br /&gt;
&lt;br /&gt;
After this went on for chunks of September and October, &lt;a href="http://mail.python.org/pipermail/python-ideas/2012-October/016849.html"&gt;Guido stated&lt;/a&gt; that he'd like to break the discussion up into various sub-topics:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;reactors&lt;/li&gt;
&lt;li&gt;protocol implementations&lt;/li&gt;
&lt;li&gt;Twisted (esp. Deferred)&lt;/li&gt;
&lt;li&gt;Tornado&lt;/li&gt;
&lt;li&gt;yield from vs. Futures&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
This was done in order to prevent the original thread from going over 100 messages and to better organize the discussion... but wow, things completely exploded after that (in good ways. mostly). It was async open season, and the ringing of shots in the air seemed continuous. If you scroll&amp;nbsp;to about the half-way point of the &lt;a href="http://mail.python.org/pipermail/python-ideas/2012-October/thread.html"&gt;October &amp;nbsp;archive page&lt;/a&gt;, you will see the first of these new threads (&lt;a href="http://mail.python.org/pipermail/python-ideas/2012-October/016851.html"&gt;[Python-ideas] The async API of the future: Reactors&lt;/a&gt;). These messages essentially dominate the rest of the October archives. It's probably not unexpected that this continued into &lt;a href="http://mail.python.org/pipermail/python-ideas/2012-November/thread.html"&gt;November&lt;/a&gt;.&amp;nbsp;A &lt;a href="http://mail.python.org/pipermail/python-dev/2012-November/122881.html"&gt;related thread&lt;/a&gt; was started on Python-dev and it seemed&amp;nbsp;to revive an old thread &lt;a href="http://mail.python.org/pipermail/python-dev/2012-December/123011.html"&gt;this month&lt;/a&gt; (on the same list).&lt;br /&gt;
&lt;br /&gt;
All of this got mentioned &lt;a href="http://www.reddit.com/r/Python/comments/11eqtd/from_guido_on_mailpythonorg_the_async_api_of_the/"&gt;on Reddit&lt;/a&gt;, too. It inspired at least two blog posts of which I am aware: &amp;nbsp;&lt;a href="http://stevedower.id.au/blog/async-api-for-python/"&gt;one post&lt;/a&gt;&amp;nbsp;by Steve Dower, and &lt;a href="http://washort.twistedmatrix.com/2012/10/coroutines-reduce-readability.html"&gt;another by&lt;/a&gt;&amp;nbsp;Allen Short. Even better, though, Guido started &lt;a href="http://code.google.com/p/tulip/source/browse/README"&gt;an exploratory project&lt;/a&gt; called Tulip to test out some of these ideas in actual running code.&amp;nbsp;As he mentions in the README, &lt;a href="http://www.cosc.canterbury.ac.nz/greg.ewing/python/generators/yf_current/Examples/Scheduler/scheduler.txt"&gt;a tutorial&lt;/a&gt; by Greg Ewing was influential in the initial implementation of Tulip and&amp;nbsp;initial design notes were made in the message &lt;a href="http://mail.python.org/pipermail/python-ideas/2012-October/017501.html"&gt;[Python-ideas] Async API: some code to review&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Shortly after that, some of the Twisted devs local to Guido met with him at his former office in San Francisco. This went amazingly well and revolved mostly around the pros and cons of separating the protocol and transport functionality. Guido started experimenting with that in Tulip on December 6th. Yesterday, a followup meeting took place at the Rackspace office, this time &lt;a href="http://code.google.com/p/tulip/source/browse/NOTES"&gt;with notes&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
There's a long way to go still, but I find myself&amp;nbsp;compulsively&amp;nbsp;checking&amp;nbsp;the commit log for Tulip now :-) It's exciting to imagine a future where Twisted and Tornado could easily interoperate with async support in Python 3 with a minimum of fuss. In fact, Glyph has already sketched out two classes which might be all that's needed for 2-way interoperation between Twisted and Python 3.&lt;br /&gt;
&lt;br /&gt;
Here's to the future!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=WcLGi_tZ6i8:628X-Q3pke8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=WcLGi_tZ6i8:628X-Q3pke8:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=WcLGi_tZ6i8:628X-Q3pke8:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=WcLGi_tZ6i8:628X-Q3pke8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=WcLGi_tZ6i8:628X-Q3pke8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=WcLGi_tZ6i8:628X-Q3pke8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=WcLGi_tZ6i8:628X-Q3pke8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=WcLGi_tZ6i8:628X-Q3pke8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/WcLGi_tZ6i8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/3907323719699022590/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/12/async-in-python-3.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/3907323719699022590?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/3907323719699022590?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/WcLGi_tZ6i8/async-in-python-3.html" title="Async in Python 3" /><author><name>Duncan McGreggor</name><uri>http://www.blogger.com/profile/05824242007299312223</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/-Ci20oHKVEhU/UKMBZtDNJGI/AAAAAAAAABE/_p5KqlBMD9M/s220/DuncanSimpsons_cropped-medium-2-flat.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-xO-6jId0QVg/UMkqqDrhMqI/AAAAAAAAAB8/F8pjiP7E_bc/s72-c/Logo_Python.png" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/12/async-in-python-3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMHQ3s5eyp7ImA9WhBQEk4.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-8627823263389307658</id><published>2012-10-30T11:22:00.000-07:00</published><updated>2013-03-13T20:40:32.523-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-13T20:40:32.523-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="threadpools" /><category scheme="http://www.blogger.com/atom/ns#" term="async" /><category scheme="http://www.blogger.com/atom/ns#" term="actors" /><category scheme="http://www.blogger.com/atom/ns#" term="agents" /><category scheme="http://www.blogger.com/atom/ns#" term="validators" /><category scheme="http://www.blogger.com/atom/ns#" term="threads" /><category scheme="http://www.blogger.com/atom/ns#" term="clojure" /><category scheme="http://www.blogger.com/atom/ns#" term="reblog" /><category scheme="http://www.blogger.com/atom/ns#" term="errors" /><title>Async in Clojure: Playing with Agents, Part II</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-wGUH0hB0Yls/UI62EO3wsBI/AAAAAAAAALw/HiyFdql7fIY/s1600/clojure-logo-large.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-wGUH0hB0Yls/UI62EO3wsBI/AAAAAAAAALw/HiyFdql7fIY/s200/clojure-logo-large.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
In &lt;a href="http://blog.mindpool.io/2012/10/async-in-clojure-playing-with-agents.html"&gt;the last post&lt;/a&gt;, we took a look at basic usage of &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;'s &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;agent&lt;/span&gt;&lt;/span&gt; function. In this post, we'll dive a little bit deeper&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Validation&lt;/b&gt;
&lt;br /&gt;
We glossed over the options that you can define when creating an agent; one of them is the &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;validator&lt;/span&gt;&lt;/span&gt; which one can use to check before the agent is updated with the passed value.&lt;br /&gt;
&lt;br /&gt;
If we want to make sure that our &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;read-agent&lt;/span&gt;&lt;/span&gt; always gets a string value, this is all we have to do:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3977479.js?file=01-validation.clj"&gt;&lt;/script&gt;

&lt;br /&gt;
Similarly, any function that takes a single value as a parameter can be used here. As you can see, we had to change our default value for the agent from &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;nil&lt;/span&gt;&lt;/span&gt; to &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;""&lt;/span&gt;&lt;/span&gt; since there is now a string validator. If we hadn't, any time we tried to use that agent, we'd get &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;java.lang.IllegalStateException&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;When Things Go Wrong&lt;/b&gt;&lt;br /&gt;
Another option you can set when defining an agent is the error handler. This will be used in the event of an error, including if a value fails to be validated by your validator function. Here's an example:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3977479.js?file=02-error-handler.clj"&gt;&lt;/script&gt;

&lt;br /&gt;
With both of these options, you don't have to set them when the agent is defined; you can do it later with a function call, if you so desire (or if needs demand it):&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3977479.js?file=03-set-options.clj"&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;b&gt;Watch This!&lt;/b&gt;&lt;br /&gt;
So, we've got an error handler but no event handler? Yup. However, you &lt;i&gt;can&lt;/i&gt; actually get callback-like behavior using &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;watch&lt;/span&gt;&lt;/span&gt;es. Check this out:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3977479.js?file=04-callbacks.clj"&gt;&lt;/script&gt;

&lt;br /&gt;
Now, any time our agent's state changes, the function passed to the watch will fire. As described in &lt;a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/add-watch"&gt;the docs&lt;/a&gt;, the parameters are: the agent, a key of your devising (must be unique per agent), and the handler that you want to have fired upon state change. The handler takes as parameters: the key you defined, the agent, the agent's old value, and the agent's new value.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;All Together Now&lt;/b&gt;&lt;br /&gt;
With all our example code in place, we can now exercise the whole thing at once. Here's the whole thing:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3977479.js?file=05-agent.clj"&gt;&lt;/script&gt;

&lt;br /&gt;
To simply demonstrate the async nature and the callbacks in action, let's run the following:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3977479.js?file=06-repl.txt"&gt;&lt;/script&gt;

&lt;br /&gt;
Eventually, our callback will render output very much like the following:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3977479.js?file=07-repl.txt"&gt;&lt;/script&gt;

&lt;br /&gt;
Do note, however, that if we called a series of &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send-off&lt;/span&gt;&lt;/span&gt;s with different times (using the same agent and watch), we wouldn't see the ones with shorter times come back first. We'd see the callback output in the same order we called &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send-off&lt;/span&gt;&lt;/span&gt;. This is because the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;watch&lt;/span&gt;&lt;/span&gt; function is called synchronously on the agent's thread before any pending &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send-off&lt;/span&gt;&lt;/span&gt;s (or &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send&lt;/span&gt;&lt;/span&gt;s) are called. In future posts, I'll cover ways around this (constructing agents on the fly as well as exploring alternative solutions with external libraries).&lt;br /&gt;
&lt;br /&gt;
Regardless, with these primitives, there are all sorts of things one can do. For instance...&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Dessert&lt;/b&gt;&lt;br /&gt;
To close, check out this neat little bit of code that sends 1,000,000 messages in a ring. This code creates a chain of agents, and then actions are relayed through it (taken from the &lt;a href="http://clojure.org/agents"&gt;agents doc page&lt;/a&gt;): &lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3977479.js?file=08-relay-ring.clj"&gt;&lt;/script&gt;

&lt;br /&gt;
Kicking this puppy off, our million messages finish in about 1 second :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3977479.js?file=09-repl.txt"&gt;&lt;/script&gt;

&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=-rOfcnLV7Gw:9NSCnqvzGZ0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=-rOfcnLV7Gw:9NSCnqvzGZ0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=-rOfcnLV7Gw:9NSCnqvzGZ0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=-rOfcnLV7Gw:9NSCnqvzGZ0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=-rOfcnLV7Gw:9NSCnqvzGZ0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=-rOfcnLV7Gw:9NSCnqvzGZ0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=-rOfcnLV7Gw:9NSCnqvzGZ0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=-rOfcnLV7Gw:9NSCnqvzGZ0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/-rOfcnLV7Gw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/8627823263389307658/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/10/async-in-clojure-playing-with-agents_30.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/8627823263389307658?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/8627823263389307658?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/-rOfcnLV7Gw/async-in-clojure-playing-with-agents_30.html" title="Async in Clojure: Playing with Agents, Part II" /><author><name>Duncan McGreggor</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-nrh0l1Wyg7E/TwH5bXx6isI/AAAAAAAAAGw/CdDWpfpYaGg/s220/duncan_in_redwood_crop_retouch_2.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-wGUH0hB0Yls/UI62EO3wsBI/AAAAAAAAALw/HiyFdql7fIY/s72-c/clojure-logo-large.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/10/async-in-clojure-playing-with-agents_30.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMGQHc9fyp7ImA9WhBQEk4.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-4204071584134176631</id><published>2012-10-29T10:00:00.001-07:00</published><updated>2013-03-13T20:40:21.967-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-13T20:40:21.967-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="threadpools" /><category scheme="http://www.blogger.com/atom/ns#" term="async" /><category scheme="http://www.blogger.com/atom/ns#" term="actors" /><category scheme="http://www.blogger.com/atom/ns#" term="agents" /><category scheme="http://www.blogger.com/atom/ns#" term="twisted" /><category scheme="http://www.blogger.com/atom/ns#" term="libevent" /><category scheme="http://www.blogger.com/atom/ns#" term="libev" /><category scheme="http://www.blogger.com/atom/ns#" term="threads" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="clojure" /><category scheme="http://www.blogger.com/atom/ns#" term="reblog" /><title>Async in Clojure: Playing with Agents, Part I</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://farm9.staticflickr.com/8194/8132215505_bed518b214.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://farm9.staticflickr.com/8194/8132215505_bed518b214.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt; has a very interesting async primitive: the &lt;a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/agent"&gt;agent&lt;/a&gt;. There is some good &lt;a href="http://clojure.org/agents"&gt;documentation on agents&lt;/a&gt;, but for those that come from a background such as mine (&lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; at &lt;a href="http://twistedmatrix.com/"&gt;Twisted&lt;/a&gt;), I thought it might be nice to present one way of using agents to mimic the familiar async + callback reactive-style programming. &lt;br /&gt;
&lt;br /&gt;
Do note, however, that Clojure agents run in one of two threadpools (one intended for CPU-intensive tasks, and the other for I/O-intensive tasks). As such, this is quite different than the event-loop approach that Twisted uses (or async frameworks that utilize libraries such as &lt;a href="http://libevent.org/"&gt;libevent&lt;/a&gt; or &lt;a href="http://software.schmorp.de/pkg/libev.html"&gt;libev&lt;/a&gt;). Twisted has the &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;deferToThread&lt;/span&gt;&lt;/span&gt; functionality, which is ... well, not exactly close, really. Regardless, let's get started.&lt;br /&gt;
&lt;br /&gt;
In the following examples, we're going to pretend we have huge files we'll be reading off a local disk.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What to Call&lt;/b&gt;&lt;br /&gt;
Clojure's &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;agent&lt;/span&gt;&lt;/span&gt; function is very, very simple: you pass it a value (it's initial state) and some options, if needed. That's it.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3967254.js?file=01-agent.clj"&gt;&lt;/script&gt;

&lt;br /&gt;
To update its state, you use either the &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send&lt;/span&gt;&lt;/span&gt; or &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send-off&lt;/span&gt;&lt;/span&gt; functions. If you've got CPU-bound tasks whose state you want to manage with agents, then you should use the &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send&lt;/span&gt;&lt;/span&gt; function. If your tasks will be I/O-bound, then you should use&lt;span style="font-size: small;"&gt; &lt;span style="font-size: small;"&gt;the &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send-off&lt;/span&gt;&lt;/span&gt; function for updating a&lt;span style="font-size: small;"&gt;gent state.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (The threadpool dedicated for use by &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send&lt;/span&gt;&lt;/span&gt; has a fixed size, based on the number of processors on your system. The threadpool for &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send-off&lt;/span&gt;&lt;/span&gt; is exapandable with thread caching and keep-alives.) Since our examples are focused on disk I/O, we'll be using &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send-off&lt;/span&gt;&lt;/span&gt;. (they have the same signature, though, so the following usage information applies to both).&lt;br /&gt;
&lt;br /&gt;
When you &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;send-off&lt;/span&gt;&lt;/span&gt; something to an agent, you pass if a few things:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;an agent&lt;/li&gt;
&lt;li&gt;the action or update function&lt;/li&gt;
&lt;li&gt;any number of additional parameters you want the action function to consume&lt;/li&gt;
&lt;/ul&gt;
Here's what that looks like:
&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3967254.js?file=02-send-off.clj"&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;b&gt;What to Write&lt;/b&gt; &lt;br /&gt;
So, we know what an agent looks like when bound and we know how we're going to send an update to the agent, but how might we construct the update itself? Perhaps like this:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3967254.js?file=03-action.clj"&gt;&lt;/script&gt;

&lt;br /&gt;
As you can see, the first value that an action function takes is the "old" value of the agent -- the value that the agent has prior to the action that will take place. Once this function returns, the agent's value will be set to the return value of the action function. (What's more, if we needed to access the agent itself inside the action function for any reason, we could do so using the &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;*agent*&lt;/span&gt;&lt;/span&gt; variable -- accessible within the scope of the action function).&lt;br /&gt;
&lt;br /&gt;
Before we go on, let's take a look at this in action from the REPL:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3967254.js?file=05-repl.txt"&gt;&lt;/script&gt;

&lt;br /&gt;
The first thing we do is switch from the default namespace to one dedicated to our examples (this makes managing scope in the REPL much cleaner). Then we load a file that has the agent and action function defined. Then we tell it to run our fake "big read" function, asking it to run for about 10 seconds. As you can see, send-off returns the agent immediately. We then get the current value of the agent by dereferencing it. Finally our big read finishes, and we see it print how long it took. We then look at the agent directly, and then dereference it again -- both showing us what we'd expect: that the value of the agent has been updated to the return value of our big read function. Finally, we shutdown the agent threads and exit the REPL.&lt;br /&gt;
&lt;br /&gt;
(The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;start-clojure&lt;/span&gt;&lt;/span&gt; script is wrapped with &lt;a href="http://utopia.knoware.nl/~hlub/rlwrap/#rlwrap"&gt;rlwrap&lt;/a&gt; so that I have access to a command line history, persistent over different sessions. The script boils down to this: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;rlwrap java -cp /usr/local/clojure-1.4.0/clojure-1.4.0.jar clojure.main&lt;/span&gt;&lt;/span&gt;.)&lt;br /&gt;
&lt;br /&gt;
We've seen the agent in action now, but there's a bit more we can do. We'll take a look at that in the next post.&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=7JMKjke_F1k:rRjw5Vd_S0Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=7JMKjke_F1k:rRjw5Vd_S0Q:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=7JMKjke_F1k:rRjw5Vd_S0Q:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=7JMKjke_F1k:rRjw5Vd_S0Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=7JMKjke_F1k:rRjw5Vd_S0Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=7JMKjke_F1k:rRjw5Vd_S0Q:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=7JMKjke_F1k:rRjw5Vd_S0Q:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=7JMKjke_F1k:rRjw5Vd_S0Q:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/7JMKjke_F1k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/4204071584134176631/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/10/async-in-clojure-playing-with-agents.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/4204071584134176631?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/4204071584134176631?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/7JMKjke_F1k/async-in-clojure-playing-with-agents.html" title="Async in Clojure: Playing with Agents, Part I" /><author><name>Duncan McGreggor</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-nrh0l1Wyg7E/TwH5bXx6isI/AAAAAAAAAGw/CdDWpfpYaGg/s220/duncan_in_redwood_crop_retouch_2.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/10/async-in-clojure-playing-with-agents.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIDQH07eSp7ImA9WhBQEk4.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-6731652472434740839</id><published>2012-10-19T10:14:00.000-07:00</published><updated>2013-03-13T20:42:51.301-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-13T20:42:51.301-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sbcl" /><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="async" /><category scheme="http://www.blogger.com/atom/ns#" term="signals" /><category scheme="http://www.blogger.com/atom/ns#" term="libevent" /><category scheme="http://www.blogger.com/atom/ns#" term="cffi" /><category scheme="http://www.blogger.com/atom/ns#" term="reblog" /><category scheme="http://www.blogger.com/atom/ns#" term="mac" /><category scheme="http://www.blogger.com/atom/ns#" term="io" /><category scheme="http://www.blogger.com/atom/ns#" term="cl-async" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>libevent for Lisp: A Signal Example </title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-c1OHL64rUD0/UHtJyO5kp0I/AAAAAAAAAFw/3oGNoK636e0/s1600/Lambda.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-c1OHL64rUD0/UHtJyO5kp0I/AAAAAAAAAFw/3oGNoK636e0/s200/Lambda.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
At MindPool, there are several async I/O options we've been exploring for Lisp:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;CMUCL/SBCL's &lt;a href="http://common-lisp.net/project/cmucl/doc/cmu-user/serve-event.html"&gt;SERVE-EVENT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://common-lisp.net/project/iolib/"&gt;IOlib&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jadahl/cl-event"&gt;cl-event&lt;/a&gt; (&lt;a href="http://libevent.org/"&gt;libevent&lt;/a&gt; for Lisp, using &lt;a href="http://www.cliki.net/cffi"&gt;cffi&lt;/a&gt;; three years old)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/orthecreedence/cl-async"&gt;cl-async&lt;/a&gt; (also using cffi libevent wrapper, actively developed) &lt;/li&gt;
&lt;/ul&gt;
As luck would have it, I started with cl-event, and it was a fun little adventure (given the fact that it hasn't been maintained). I corresponded with the very nice original author a bit, asking if there were any updates in other locations, but sadly there weren't.&lt;br /&gt;
&lt;br /&gt;
I was ready to dive in and get things current, when one last Google search turned up &lt;a href="https://github.com/orthecreedence/cl-async"&gt;cl-async&lt;/a&gt;. This little bugger was hard to find, as at that point it had not been listed on &lt;a href="http://www.cliki.net/"&gt;CLiki&lt;/a&gt;. (But it is now :-)). &lt;a href="http://www.linkedin.com/in/andrewmlyon"&gt;Andrew Lyon&lt;/a&gt; has done a tremendous amount of work on cl-async, with a very complete set of bindings for libevent. This is just what I had been looking for, so I jumped in immediately.&lt;br /&gt;
&lt;br /&gt;
As one might imagine from the topic of this post, there's a lot to be explored, uncovered, and developed further around async programming in Lisp. I'll start off slowly with a small example, and add more over the course of time.&lt;br /&gt;
&lt;br /&gt;
I also hope to cover IOlib and SBCL's SERVE-EVENT in some future posts. Time will tell... For now, let's get started with cl-async in SBCL :-)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Dependencies&lt;/b&gt;&lt;br /&gt;
In a &lt;a href="http://blog.mindpool.io/2012/10/getting-started-with-steel-bank-common.html"&gt;previous post&lt;/a&gt;, I discussed getting an environment set up with SBCL, I the rest of this post assumes that has been read and done :-) &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Getting cl-async and Setting Up an SBCL Environment for Hacking&lt;/b&gt;&lt;br /&gt;
Now let's download cl-async and install the Libevent bindings :-)&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3909700.js?file=01-install.txt"&gt;&lt;/script&gt;

&lt;br /&gt;
With the Lisp Libevent bindings installed, we're now ready to create a Lisp image to assist us when exploring cl-async. A Lisp image saves the current state of the REPL, with all the loaded libaries, etc., allowing for rapid start-ups and script executions. Just the thing, when you're iterating on something :-)
&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3909700.js?file=02-setup-environment.txt"&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;b&gt;Example: Adding a Signal Handler&lt;/b&gt;&lt;br /&gt;
Let's dive into some signal handling now! Here is some code I put together as part of an effort to beef up the examples in cl-async:
&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3909700.js?file=03-handle-signal.lisp"&gt;&lt;/script&gt;

&lt;br /&gt;
Note that the &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;as:&lt;/span&gt;&lt;/span&gt; is a nickname for the package namespace &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;cl-async:&lt;/span&gt;&lt;/span&gt;. 
&lt;br /&gt;
&lt;br /&gt;
As one might expect, there is a function to start the event loop. However, what is a little different is that one doesn't initialize the event loop directly, but with a callback. As such, one cannot set up handlers, etc., except within the scope of this callback.&lt;br /&gt;
&lt;br /&gt;
We've got the &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;setup-handler&lt;/span&gt;&lt;/span&gt; function for that, which adds a callback for a &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;SIGINT&lt;/span&gt;&lt;/span&gt; event. Let's try it out :-) &lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3909700.js?file=04-run-the-script.txt"&gt;&lt;/script&gt;

Once your script has finished loading the core, you should see output like the above, with no return to the shell prompt.
&lt;br /&gt;
&lt;br /&gt;
When we send a &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;SIGINT&lt;/span&gt;&lt;/span&gt; with &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;^C&lt;/span&gt;&lt;/span&gt;, we can watch our callback get fired:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3909700.js?file=05-output.txt"&gt;&lt;/script&gt;

&lt;br /&gt;
Next up, we'll take a look at other types of handlers in cl-async.&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=1dXSU5oTb3o:_BPt37EQLB0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=1dXSU5oTb3o:_BPt37EQLB0:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=1dXSU5oTb3o:_BPt37EQLB0:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=1dXSU5oTb3o:_BPt37EQLB0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=1dXSU5oTb3o:_BPt37EQLB0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=1dXSU5oTb3o:_BPt37EQLB0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=1dXSU5oTb3o:_BPt37EQLB0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=1dXSU5oTb3o:_BPt37EQLB0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/1dXSU5oTb3o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/6731652472434740839/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/10/libevent-for-lisp-signal-example.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/6731652472434740839?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/6731652472434740839?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/1dXSU5oTb3o/libevent-for-lisp-signal-example.html" title="libevent for Lisp: A Signal Example " /><author><name>Duncan McGreggor</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-nrh0l1Wyg7E/TwH5bXx6isI/AAAAAAAAAGw/CdDWpfpYaGg/s220/duncan_in_redwood_crop_retouch_2.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-c1OHL64rUD0/UHtJyO5kp0I/AAAAAAAAAFw/3oGNoK636e0/s72-c/Lambda.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/10/libevent-for-lisp-signal-example.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEERn47eCp7ImA9WhBQEk4.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-2334767543439035515</id><published>2012-10-18T11:24:00.000-07:00</published><updated>2013-03-13T20:43:27.000-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-13T20:43:27.000-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lisp" /><category scheme="http://www.blogger.com/atom/ns#" term="sbcl" /><category scheme="http://www.blogger.com/atom/ns#" term="installation" /><category scheme="http://www.blogger.com/atom/ns#" term="readline" /><category scheme="http://www.blogger.com/atom/ns#" term="reblog" /><category scheme="http://www.blogger.com/atom/ns#" term="rlwrap" /><category scheme="http://www.blogger.com/atom/ns#" term="brew" /><category scheme="http://www.blogger.com/atom/ns#" term="howtos" /><category scheme="http://www.blogger.com/atom/ns#" term="apt-get" /><category scheme="http://www.blogger.com/atom/ns#" term="installs" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="mac" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Getting Started with Steel Bank Common Lisp</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-c1OHL64rUD0/UHtJyO5kp0I/AAAAAAAAAFw/3oGNoK636e0/s1600/Lambda.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-c1OHL64rUD0/UHtJyO5kp0I/AAAAAAAAAFw/3oGNoK636e0/s200/Lambda.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
As some of you know, I've been a closet Lisp fan for several years. When I first joined &lt;a href="http://www.canonical.com/"&gt;Canonical&lt;/a&gt; in 2008, I was hacking on Lisp in Python, so that I could do &lt;a href="http://en.wikipedia.org/wiki/Genetic_programming"&gt;genetic programming&lt;/a&gt; in Python. In fact, my first and only lightening talk at a Canonical sprint was on genetic algorithms and programming :-)&amp;nbsp; (This was the same set of lightening talks that &lt;a href="https://launchpad.net/~vds"&gt;Vincenzo Di Somma&lt;/a&gt; gave a wonderful presentation on his photography; completely unrelated: this is one of my favorite &lt;a href="https://twimg0-a.akamaihd.net/profile_images/431392761/IoEunSaduh.jpg"&gt;pics of Vincenzo&lt;/a&gt; :-) ).&lt;br /&gt;
&lt;br /&gt;
A few years later, I talked to &lt;a href="https://twitter.com/jimbaker"&gt;Jim Baker&lt;/a&gt; about Python's AST, and how one might be able to do genetic programming by manipulating it directly, instead of running a Lisp in Python.&lt;br /&gt;
&lt;br /&gt;
Throughout all this time, I've been touching in with various community projects, hacking on various Lispy Things, reading, etc., but generally doing so quite quietly. Over the past few months, however, I've really gotten into it, and Lisp has become a real force in my life, rapidly playing just as dominant a role as Python.&lt;br /&gt;
&lt;br /&gt;
Similarly, &lt;a href="http://mindpool.io/"&gt;MindPool&lt;/a&gt; has become active in several Lisp projects; as such, there are a great many things to share now. However, before I begin all that, I'd like to take an opportunity to get folks up and running with an example Lisp environment.&lt;br /&gt;
&lt;br /&gt;
Future posts will explore various areas of Common Lisp, Scheme dialects, I/O loops, etc., but this one will provide a basis for all future posts that relate to Common Lisp and specifically the &lt;a href="http://www.sbcl.org/"&gt;Steel Bank implementation&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Installing SBCL&lt;/b&gt;&lt;br /&gt;
If you don't have SBCL (Steel Bank Common Lisp; &lt;a href="http://en.wikipedia.org/wiki/Steel_Bank_Common_Lisp"&gt;a pun on it's source parent&lt;/a&gt;, CMUCL), you need to install it:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;For Ubuntu (12.04 LTS has 1.0.55): &lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo apt-get install sbcl&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Or &lt;span style="font-size: small;"&gt;you can go to &lt;/span&gt;the &lt;/span&gt;&lt;a href="http://www.sbcl.org/platform-table.html"&gt;download page&lt;/a&gt; for everyone else.&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;apt-get&lt;/span&gt; for Lisp&lt;/b&gt; &lt;br /&gt;
Next, you'll need to install &lt;a href="http://www.quicklisp.org/"&gt;Quicklisp&lt;/a&gt; (as you might have surmised, it's like Debian &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;apt-get&lt;/span&gt;&lt;/span&gt; for Common Lisp). The instructions on &lt;a href="http://www.quicklisp.org/beta/"&gt;this page&lt;/a&gt; will get you up and running with Quicklisp.&lt;br /&gt;
&lt;br /&gt;
I like having quicklisp available when I run SBCL, so I did the following after installing Quicklisp (and you might want to as well) from the &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sbcl&lt;/span&gt;&lt;/span&gt; prompt:&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;* (ql:add-to-init-file)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Readline Support&lt;/b&gt; &lt;br /&gt;
The default installation of SBCL doesn't have readline support for the REPL, so using your arrow keys won't give you the expected result (your command history). To remedy that, you can use a readline wrapper. First, install &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;rlwrap&lt;/span&gt;&lt;/span&gt;:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu: &lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ sudo apt-get install rlwrap&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Mac OS X: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;$ brew install rlwrap&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
Then, create &lt;span style="font-size: small;"&gt;the&lt;/span&gt; &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;chmod&lt;/span&gt;&lt;/span&gt;ed 755 script &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;~/bin&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;/start-sbcl&lt;/span&gt;&lt;/span&gt; with the following content (make sure that &lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;~/bin&lt;/span&gt;&lt;/span&gt; is in your path):&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;rlwrap sbcl&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
At which point you can run the following and have access to a command history in SBCL:&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;$ start-sbcl&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-size: x-small;"&gt;*&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Why Steel Bank?&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/CMU_Common_Lisp"&gt;CMUCL&lt;/a&gt; gained an excellent reputation for being a highly performant, optimized implementation of Lisp. Based on CMUCL and continuing this tradition of excellent performance, SBCL's reputation preceded it. Over a range of different types of programs, SBCL not only compares favorably to other Lisp dialects, it &lt;a href="http://shootout.alioth.debian.org/u64q/which-programs-are-fastest.php?gcc=on&amp;amp;gpp=on&amp;amp;java=on&amp;amp;sbcl=on&amp;amp;go=on&amp;amp;ghc=on&amp;amp;ocaml=on&amp;amp;clojure=on&amp;amp;hipe=on&amp;amp;erlang=on&amp;amp;python3=on&amp;amp;yarv=on&amp;amp;perl=on&amp;amp;calc=chart"&gt;seriously kicks ass all over&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
SBCL comes in at 8th place in that benchmark ranking, beating out Go in 9th place. In all the languages that made it into the Top 10, I've only ever touched C, C++, Java, Scala, Lisp, and Go. In my list, SBCL made the Top 5 :-) Regardless, of all of them, Lisp has the syntax a find most pleasurable. Given my background in Python, this is not surprising ;-)&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;What's next?&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
Funny that you should ask... given my background with &lt;a href="http://twistedmatrix.com/"&gt;Twisted&lt;/a&gt;, I'll give you one guess ;-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=-4EvBXSlGAE:xDuboeKzL7Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=-4EvBXSlGAE:xDuboeKzL7Q:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=-4EvBXSlGAE:xDuboeKzL7Q:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=-4EvBXSlGAE:xDuboeKzL7Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=-4EvBXSlGAE:xDuboeKzL7Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=-4EvBXSlGAE:xDuboeKzL7Q:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=-4EvBXSlGAE:xDuboeKzL7Q:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=-4EvBXSlGAE:xDuboeKzL7Q:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/-4EvBXSlGAE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/2334767543439035515/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/10/getting-started-with-steel-bank-common.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/2334767543439035515?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/2334767543439035515?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/-4EvBXSlGAE/getting-started-with-steel-bank-common.html" title="Getting Started with Steel Bank Common Lisp" /><author><name>Duncan McGreggor</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-nrh0l1Wyg7E/TwH5bXx6isI/AAAAAAAAAGw/CdDWpfpYaGg/s220/duncan_in_redwood_crop_retouch_2.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-c1OHL64rUD0/UHtJyO5kp0I/AAAAAAAAAFw/3oGNoK636e0/s72-c/Lambda.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/10/getting-started-with-steel-bank-common.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEDRnw8fCp7ImA9WhBQEk4.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-1370493477066019323</id><published>2012-10-15T17:34:00.001-07:00</published><updated>2013-03-13T20:44:37.274-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-13T20:44:37.274-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="frameworks" /><category scheme="http://www.blogger.com/atom/ns#" term="bottle" /><category scheme="http://www.blogger.com/atom/ns#" term="docutils" /><category scheme="http://www.blogger.com/atom/ns#" term="reblog" /><category scheme="http://www.blogger.com/atom/ns#" term="web" /><category scheme="http://www.blogger.com/atom/ns#" term="async" /><category scheme="http://www.blogger.com/atom/ns#" term="howtos" /><category scheme="http://www.blogger.com/atom/ns#" term="templating" /><category scheme="http://www.blogger.com/atom/ns#" term="twisted" /><category scheme="http://www.blogger.com/atom/ns#" term="flask" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="html" /><category scheme="http://www.blogger.com/atom/ns#" term="rst" /><category scheme="http://www.blogger.com/atom/ns#" term="klein" /><title>Rendering ReST with Klein and Twisted Templates</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://en.wikipedia.org/wiki/File:Twisted_Logo_%28software%29.svg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Twisted_Logo_(software).svg/200px-Twisted_Logo_(software).svg.png" /&gt;&lt;/a&gt;&lt;/div&gt;
In a previous life, I spent about 25 hours a day worrying about &lt;a href="http://en.wikipedia.org/wiki/Content_management_system"&gt;content management systems&lt;/a&gt; written in Python. As a result of the battle scars built up during those days, I have developed a pretty strong aversion for a heavy &lt;span id="goog_371946543"&gt;&lt;/span&gt;CMS&lt;span id="goog_371946544"&gt;&lt;/span&gt; when a simple approach will do. &lt;i&gt;Especially&lt;/i&gt; if the users are technologically proficient.&lt;br /&gt;
&lt;br /&gt;
At &lt;a href="http://mindpool.io/"&gt;MindPool&lt;/a&gt;, we're building out our infrastructure right now using &lt;a href="http://twistedmatrix.com/trac/"&gt;Twisted&lt;/a&gt; so that we can take advantage of the super amazing numbers of protocols that Twisted supports to provide some pretty unique combined services for our customers (among the many other types of services we are providing). For our website, we're using the &lt;a href="http://bottlepy.org/"&gt;Bottle&lt;/a&gt;/&lt;a href="http://flask.pocoo.org/"&gt;Flask&lt;/a&gt;-inspired &lt;a href="https://github.com/twisted/klein"&gt;Klein&lt;/a&gt; as our micro web framework, and this uses the most excellent &lt;a href="http://twistedmatrix.com/documents/current/web/howto/twisted-templates.html"&gt;Twisted templating&lt;/a&gt;. (We are, of course, also using &lt;a href="http://twitter.github.com/bootstrap/"&gt;Twitter Bootstrap&lt;/a&gt;.)&lt;br /&gt;
&lt;br /&gt;
Here's the rub, though: we want to manage our content in the git repo for our site with &lt;a href="http://docutils.sourceforge.net/rst.html"&gt;ReStructured Text&lt;/a&gt; files, and there's no way to tell the template rendering machinery (the &lt;a href="https://github.com/twisted/twisted/blob/master/twisted/web/_flatten.py#L97"&gt;flattener code&lt;/a&gt;) to allow raw HTML into the mix. As such, my first attempt at ReST support was rendering HTML tags all over the user-facing content.&lt;br /&gt;
&lt;br /&gt;
This ended up being a blessing in disguise, though, as I was fairly unhappy with the third-party dependencies that had popped up as a result of getting this to work. After a couple false starts, I was hot on the trail of a good solution: convert the &lt;a href="http://docutils.sourceforge.net/"&gt;docutils&lt;/a&gt;-generated HTML (from the ReST source files) to &lt;a href="https://github.com/twisted/twisted/blob/master/twisted/web/_stan.py"&gt;Twisted Stan tags&lt;/a&gt;, and push &lt;i&gt;those&lt;/i&gt; into the renderers.&lt;br /&gt;
&lt;br /&gt;
This ended up working like a champ. Here's what I did:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Created a couple of utility functions for easily getting HTML from ReST and Stan from ReST.&lt;/li&gt;
&lt;script src="https://gist.github.com/3846991.js?file=utils.py"&gt;&lt;/script&gt;
&lt;li&gt;Wrote a custom &lt;a href="http://twistedmatrix.com/documents/current/api/twisted.web.iweb.IRenderable.html"&gt;IRenderable&lt;/a&gt; for ReST content (not strictly necessary, but organizationally useful, given what else will be added in the future).&lt;/li&gt;
&lt;script src="https://gist.github.com/3846991.js?file=renderer.py"&gt;&lt;/script&gt;
&lt;li&gt;Updated the base class for "content" page templates to dispatch, depending upon content type.&lt;/li&gt;
&lt;script src="https://gist.github.com/3846991.js?file=basepages.py"&gt;&lt;/script&gt;
&lt;/ol&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://farm9.staticflickr.com/8315/8061537867_a86c1d96f5_b.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="97" src="http://farm9.staticflickr.com/8315/8061537867_a86c1d96f5_b.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
Afterwards I was rewarded with some nicely rendered content on the staging MindPool site :-) (once the content text has been completed, we'll be pushing it live).&lt;br /&gt;
&lt;br /&gt;
Kudos to &lt;a href="https://twitter.com/dreid"&gt;David Reid&lt;/a&gt; for Klein and (as usual) to the &lt;a href="http://twistedmatrix.com/trac/wiki/TwistedCommunity"&gt;Twisted community&lt;/a&gt; for one hell of a framework that is the engine of &lt;i&gt;my&lt;/i&gt; internet. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=zoXwejI03es:PJAnum6XFIs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=zoXwejI03es:PJAnum6XFIs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=zoXwejI03es:PJAnum6XFIs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=zoXwejI03es:PJAnum6XFIs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=zoXwejI03es:PJAnum6XFIs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=zoXwejI03es:PJAnum6XFIs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=zoXwejI03es:PJAnum6XFIs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=zoXwejI03es:PJAnum6XFIs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/zoXwejI03es" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/1370493477066019323/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/10/rendering-rest-with-klein-and-twisted.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/1370493477066019323?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/1370493477066019323?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/zoXwejI03es/rendering-rest-with-klein-and-twisted.html" title="Rendering ReST with Klein and Twisted Templates" /><author><name>Duncan McGreggor</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-nrh0l1Wyg7E/TwH5bXx6isI/AAAAAAAAAGw/CdDWpfpYaGg/s220/duncan_in_redwood_crop_retouch_2.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/10/rendering-rest-with-klein-and-twisted.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEBQnk-fSp7ImA9WhBQEk4.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-5089448061330896036</id><published>2012-10-13T14:00:00.000-07:00</published><updated>2013-03-13T20:44:13.755-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-13T20:44:13.755-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gimp" /><category scheme="http://www.blogger.com/atom/ns#" term="open-source" /><category scheme="http://www.blogger.com/atom/ns#" term="photoshop" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="graphics" /><category scheme="http://www.blogger.com/atom/ns#" term="reblog" /><category scheme="http://www.blogger.com/atom/ns#" term="logos" /><title>GIMP 2.8 and the Taming of Two Decades' Graphics Habits</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://farm9.staticflickr.com/8322/8058043163_0eb47f3ac2_z.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="208" src="http://farm9.staticflickr.com/8322/8058043163_0eb47f3ac2_z.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
At long last, I find myself in a 100% comfort zone with &lt;a href="http://www.gimp.org/"&gt;the GIMP&lt;/a&gt;. As a user, it's been a long road to get here ... I can't even imagine what the development teams have experienced over the past 16 years. Regardless, I am infinitely grateful for their efforts over that time, their hard work to bring the world a completely free, open source application for incredibly sophisticated image manipulation, drawing, and even painting.&lt;br /&gt;
&lt;br /&gt;
I'll provide some more details on my experiences with GIMP 2.8, but first... a romp through the past!&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://farm9.staticflickr.com/8451/8058043075_85b176200f_z.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="133" src="http://farm9.staticflickr.com/8451/8058043075_85b176200f_z.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
I've been using graphics programs since my first exposure to the &lt;a href="http://en.wikipedia.org/wiki/Macintosh_Plus"&gt;Macintosh Plus&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Macintosh_SE"&gt;SE&lt;/a&gt; machines in the late 1980s, where the head of the science department at Bangor High School often found himself without access to his machine (yeah, thanks to me...). As much as a science geek as I was, it was actually the graphics programs to which I was addicted. In particular, I was obsessed with using &lt;a href="http://en.wikipedia.org/wiki/MacPaint"&gt;MacPaint&lt;/a&gt; to draw  -- pixel by pixel -- a dithered bitmap of a photograph leaning next to the monitor.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://farm9.staticflickr.com/8311/8058041996_277d0e7087_z.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="131" src="http://farm9.staticflickr.com/8311/8058041996_277d0e7087_z.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
About 6 or 7 years later, I was at it again doing graphics work on a non-profit's Mac (running &lt;a href="http://en.wikipedia.org/wiki/System_7"&gt;System 7&lt;/a&gt;) with &lt;a href="http://en.wikipedia.org/wiki/Adobe_Photoshop_version_history#Macintosh"&gt;Photoshop 3.0&lt;/a&gt; -- my first exposure to this software. It was absolutely mind-blowingly awesome what Photoshop enabled one to do with digital images. I was consumed. If I was awake, I was at the computer, creating something whacky from scratch or morphing something old into a new form. Though the work that I had done was focused on graphics for HTML and getting into the nascent field of "web design," some of my efforts ended up getting published as illustrations for a book.&lt;br /&gt;
&lt;br /&gt;
I continued doing graphics as part of my work (in some form or another) from then on, usually borrowing a friend's machine in order to use Photoshop (which I could not afford). Despairing of not having my own copy of the software,&amp;nbsp; I would often try out other drawing, painting, and image manipulations applications. Without fail, none would ever measure up to the power and even more, the usability, of Photoshop.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://farm9.staticflickr.com/8179/8058043123_98bf5e5a93.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://farm9.staticflickr.com/8179/8058043123_98bf5e5a93.jpg" width="295" /&gt;&lt;/a&gt;&lt;/div&gt;
It wasn't too much after this that I got involved with Linux and open source software. As for many from that time, my life has not been the same since. But those early years were painful. My first distro (Slackware), I had to manually hack the ethernet drivers in C just to get connected to the network using my particular hardware. Regardless, Linux was all I could think about; it was all I wanted to use.&lt;br /&gt;
&lt;br /&gt;
Desperately hungering for a Photoshop-like experience on Linux, I searched HotBot on a regular basis, and finally discovered GIMP. Based on a quick glance at the now-historic splash screens, it looks like my first use of the GIMP started after the 1.0 release, though I didn't start using it more regularly until 1.2 (which had my favorite GIMP splash screen to date). &lt;br /&gt;
&lt;br /&gt;
Despite my hopes and the best efforts of an amazing development team, the GIMP infuriated me. What took one step in Photoshop usually took about 5 steps in the GIMP. The user interface was anti-intuitive, and seemed to be built by folks with an intimate knowledge of the underlying API and reflected this far too well.&lt;br /&gt;
&lt;br /&gt;
With each major release of the GIMP, I would find myself downloading and installing it, but only actually using it a handful of times. Ultimately, I'd run crying back to Photoshop, borrowing a friend's computer or persuading someone to give me an unused copy. The very nature of graphic arts is visual and intuitive... I felt that the GIMP was blocking that natural flow. As a result, I couldn't get anything done in it (and what little I did looked bad).&lt;br /&gt;
&lt;br /&gt;
Year later, while working at &lt;a href="http://www.canonical.com/"&gt;Canonical&lt;/a&gt;, I had several opportunities to create graphics for various fun projects, gags, or practical jokes. Given the nature of the company's mission, I made sure to do that work using the GIMP. Though the pain of the old days had faded considerably, and GIMP had, by 2008, reached a much higher degree of usability, I still found myself enduring awkward workflow moments on a regular basis and this continued throughout the 4 years of version 2.6's release. However, during that time, an impressive selection of GIMP plugins were created, some of which I came to adore so completely that I would switch from Photoshop &lt;i&gt;to&lt;/i&gt; GIMP, just so I could use them on a project. This was a new -- and amazingly welcome -- change for me.&lt;br /&gt;
&lt;br /&gt;
Then, earlier this year, the last few pieces fell into place. &lt;br /&gt;
&lt;br /&gt;
With the release of GIMP 2.8 in May, I have not looked for nor pined over any other sophisticated graphics programs. At long last, the GIMP completely satisfies. The biggest single point of pain for me in 2.6 (given that I was running on Mac OS X most of the time) was the lack of single-window&amp;nbsp; support. For every UI interaction, I had to click twice -- once to focus on the window, and once to actually perform the given action. It was crazy-making. 2.8 finally released the goodness of single-window mode for GIMP users around the globe. Futhermore, since I have been a layer-using maniac since Photoshop 3.0 and my graphics files tend to reach into the 200 and 300 MB range due to the numbers of layers (and resolution, of course), I have a desperate need to organize the chaos of all those layers. Prior to 2.8, my layer pallet on large projects was almost completely unnavigable. With 2.8, sanity and cleanliness abounds.&lt;br /&gt;
&lt;br /&gt;
And there's more :-) Check out this short list:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;single-window mode&lt;/li&gt;
&lt;li&gt;multi-column dock windows&lt;/li&gt;
&lt;li&gt;increased screen real-estate&lt;/li&gt;
&lt;li&gt;layer groups&lt;/li&gt;
&lt;li&gt;Cairo is used for all rendering&lt;/li&gt;
&lt;li&gt;on-canvas text editing&lt;/li&gt;
&lt;/ul&gt;
For more details, you'll want to visit &lt;a href="http://www.gimp.org/release-notes/gimp-2.8.html"&gt;this page&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
Oddly, this walk down memory lane and ultimate endorsement of the GIMP relates to MindPool.&amp;nbsp; I used the GIMP to do all the complicated graphics work for our initial branding, logos, etc. &lt;a href="https://picasaweb.google.com/mindpoollabs/MindPoolGraphics"&gt;Looking at the results&lt;/a&gt;, I'm sure if seems fairly silly and even trivial... but there's a LOT that went into that simplicity :-)&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://farm9.staticflickr.com/8042/8058155835_4dc4d3734b.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://farm9.staticflickr.com/8042/8058155835_4dc4d3734b.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
For instance, the shot of the moon is actually taken from a photograph of the moon. It has been passed through multiple filters in order to get just the level of abstract color and shape I was looking for. Similarly for the water, but the settings were actually quite different to achieve the result I was seeking. I think the layer count peaked around 30 in one version of the file.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://farm9.staticflickr.com/8177/8058177918_a3c2e512f6_b.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="67" src="http://farm9.staticflickr.com/8177/8058177918_a3c2e512f6.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
Another example is the logo that we'll be using for the &lt;a href="http://mindpool.io/"&gt;company's main site&lt;/a&gt;. This also took advantage of some plugins (new and old), though mostly it relied upon paths, brush strokes, and mask layers (the latter for the water pool reflection watermarked into the image). The new features in 2.8 made all of that work very easy to do. No longer is the tool interfering with my workflow; rather, it is facilitating it. Working with graphics using open source tools is now an absolute pleasure for me.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://farm9.staticflickr.com/8173/8055158571_48006e655d_o.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="90" src="http://farm9.staticflickr.com/8173/8055158571_be8fccf395.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
For giggles, I'm including a screenshot of GIMP 2.8 in action, with my single-window mode view stretched across two 27" monitors (full version is &lt;a href="http://www.flickr.com/photos/oubiwann/8055158571/in/photostream"&gt;here&lt;/a&gt;). Graphical editing has never been so clean!&lt;br /&gt;
&lt;br /&gt;
Thanks, GIMP team :-) It's nice to finally be home.&lt;br /&gt;
&lt;br /&gt;
Fun link: For the historically inclined, you might enjoy &lt;a href="http://www.webdesignerdepot.com/2010/02/20-years-of-adobe-photoshop/"&gt;this quick read&lt;/a&gt; about the beginnings of Photoshop and the family that made it all happen :-)&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=QTFyLhl3cIc:3RUCrIakhEk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=QTFyLhl3cIc:3RUCrIakhEk:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=QTFyLhl3cIc:3RUCrIakhEk:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=QTFyLhl3cIc:3RUCrIakhEk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=QTFyLhl3cIc:3RUCrIakhEk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=QTFyLhl3cIc:3RUCrIakhEk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=QTFyLhl3cIc:3RUCrIakhEk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=QTFyLhl3cIc:3RUCrIakhEk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/QTFyLhl3cIc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/5089448061330896036/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/10/gimp-28-and-taming-of-two-decades.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/5089448061330896036?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/5089448061330896036?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/QTFyLhl3cIc/gimp-28-and-taming-of-two-decades.html" title="GIMP 2.8 and the Taming of Two Decades' Graphics Habits" /><author><name>Duncan McGreggor</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-nrh0l1Wyg7E/TwH5bXx6isI/AAAAAAAAAGw/CdDWpfpYaGg/s220/duncan_in_redwood_crop_retouch_2.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/10/gimp-28-and-taming-of-two-decades.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAHQ304fCp7ImA9WhVUEU0.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-134409467734847333</id><published>2012-05-14T23:00:00.000-07:00</published><updated>2012-05-15T12:05:32.334-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-15T12:05:32.334-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="openstack" /><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="devops" /><category scheme="http://www.blogger.com/atom/ns#" term="cern" /><category scheme="http://www.blogger.com/atom/ns#" term="half life" /><category scheme="http://www.blogger.com/atom/ns#" term="headcrabs" /><category scheme="http://www.blogger.com/atom/ns#" term="community" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="physics" /><category scheme="http://www.blogger.com/atom/ns#" term="dimensions" /><title>CERN, OpenStack Keep Resonance Cascades at Bay</title><content type="html">&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-soKhrWS6w6Y/T7FuvIlzm0I/AAAAAAAAAKg/AHpu8syxokc/s1600/Gordonfreeman.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/-soKhrWS6w6Y/T7FuvIlzm0I/AAAAAAAAAKg/AHpu8syxokc/s200/Gordonfreeman.jpg" width="156" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Tim Bell preparing to get his &lt;br /&gt;
OpenStack on&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;span style="font-family: inherit;"&gt;As &lt;a href="http://cogitat.io/2012/04/new-life-openstack-devops-community.html" target="_blank"&gt;previously mentioned&lt;/a&gt;, there's a growing momentum around ops-oriented&amp;nbsp;participation&amp;nbsp;in the &lt;a href="http://openstack.org/" target="_blank"&gt;OpenStack&lt;/a&gt; community. &lt;a href="http://dreamhost.github.com/" target="_blank"&gt;DreamHost&lt;/a&gt; is deeply invested in DevOps, seeing how that's where we're going to be living in a few months! As &lt;a href="http://www.linkedin.com/in/simonanderson" target="_blank"&gt;Simon Anderson&lt;/a&gt;, CEO of DreamHost, recently said:&lt;/span&gt;&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-size: large;"&gt;"When we're running a complex fabric of apps on over 5,000 servers across three data centers, we need a lean and nimble approach to software development and operational implementation. Without a DevOps approach, we wouldn't be able to push code into production as fast or as efficiently as we do, and our customers would not be happy! Today's 
developers demand up-to-the-hour security and performance updates to Internet infrastructure, so we aim to deliver just that with DevOps."&lt;/span&gt;&lt;/blockquote&gt;
&lt;span style="font-family: inherit;"&gt;Though expressed in the context of our work, the import of DevOps that Simon's comment generally highlights is going to be increasingly important for nearly anyone running cloud services.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;In particular, I've been following the work of the intrepid folks at CERN. As such, this post is not about DreamHost; rather, it's a mad tale of OpenStack, DevOps, and averting alien invasion.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;After countless long-distance phone conversations, a flight to Switzerland, and spending several days buying pints for a security guard in the know (referred to from now on as "Barney"), I've uncovered some profound truths -- Mulder-style -- and have confirmed that the impact of OpenStack at CERN is huge.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-family: inherit;"&gt;Superficial examinations turn up the usual: CERN's planning&amp;nbsp;&lt;/span&gt;&lt;a href="http://cern.ch/go/Php8" style="font-family: inherit;" target="_blank"&gt;slides&lt;/a&gt;&lt;span style="font-family: inherit;"&gt;, nice quotes, discussions of features and savings in time and money. For&amp;nbsp;&lt;/span&gt;instance&lt;span style="font-family: inherit;"&gt;, i&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;n a recent email conversation with Tim "Gordon Freeman" Bell at CERN, I learned that&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-family: inherit; font-size: large;"&gt;"The&amp;nbsp;&lt;span class="il"&gt;CERN&lt;/span&gt;&amp;nbsp;Agile Infrastructure project aims to develop&amp;nbsp;&lt;span class="il"&gt;CERN&lt;/span&gt;'s computing&amp;nbsp;resources and processes to support the expanding needs of LHC physicists and&amp;nbsp;the&amp;nbsp;&lt;span class="il"&gt;CERN&lt;/span&gt;&amp;nbsp;organisation."&lt;/span&gt;&lt;/blockquote&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-BkBjvrwzLJM/T7FyNTZdtpI/AAAAAAAAAKs/4a3R4_VXGiQ/s1600/Gordon%252BFreeman%252BSpotted%252BAt%252BCERN%252BOpenStack.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="240" src="http://4.bp.blogspot.com/-BkBjvrwzLJM/T7FyNTZdtpI/AAAAAAAAAKs/4a3R4_VXGiQ/s320/Gordon%252BFreeman%252BSpotted%252BAt%252BCERN%252BOpenStack.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
I think these guys have been hanging out with Simon! But once you slip behind the scenes, peek at some of the whiteboards in unattended rooms, or rifle through notes lying about, you see that things are not what they appear. I've included a shot of Mr. OpenStack-at-CERN himself; this was my first clue.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Publicly, he's been working with other teams at CERN to:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;modernise the data centre configuration tools and automating operations&amp;nbsp;procedures&lt;/li&gt;
&lt;li&gt;exploit wide scale use of virtualisation, improving flexibility and&amp;nbsp;efficiency&lt;/li&gt;
&lt;li&gt;enhance monitoring such that the usage of the infrastructure can be fully&amp;nbsp;understood and tuned to maximise the resources available&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div&gt;
But privately, it seems that he and his team have been doing much, much more. This was alluded to in a statement made by team member Jan van Eldik: "We expect the number of requests to insert non-standard specimens into the scanning beam of the Anti-Mass Spectrometer to&amp;nbsp;significantly&amp;nbsp;decrease, once automation is in place and everyone is using the standard infrastructure we are setting up."&lt;br /&gt;
&lt;br /&gt;
That isn't to say there haven't been incidents...&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Innocuously enough, the current toolchains are based around:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family: inherit;"&gt;OpenStack as a single Infrastructure-as-a-Service providing physics&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;experiment services, developer boxes, applications servers as well as the&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;large batch farm&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Puppet for configuration management&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Scientific Linux&amp;nbsp;&lt;/span&gt;&lt;span class="il" style="font-family: inherit;"&gt;CERN&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;as the dominant operating system with sizeable chunk&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;of Windows installs&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-1q07tTpJgzk/T7F1ewUmaZI/AAAAAAAAAK4/JnP2Qqv-zHM/s1600/crowbar.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://4.bp.blogspot.com/-1q07tTpJgzk/T7F1ewUmaZI/AAAAAAAAAK4/JnP2Qqv-zHM/s200/crowbar.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
But that second bullet caught my eye, and one of Barney's pub mates confirmed a rumor that we'd heard: the Puppet instances are actually trained&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Headcrab" target="_blank"&gt;headcrabs&lt;/a&gt;. The primary training tool? You guessed it, a crowbar. Barney said that the folks from Dell took inspiration from this and developed it further for&amp;nbsp;&lt;a href="http://content.dell.com/us/en/gen/d/cloud-computing/crowbar-software-framework" target="_blank"&gt;their OpenStack deployment framework&lt;/a&gt;&amp;nbsp;after an extended visit to CERN.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;Although Barney hadn't seen any evidence of resonance cascades, there have been minor cross-dimensional disturbances as a result of some "cowboy" activity and folks not following DevOps best practices. This has been kept quiet for obvious reasons, but&amp;nbsp;&lt;/span&gt;has led to a small pest problem in some of CERN's&amp;nbsp;&lt;a href="http://www.cernlove.org/blog/2009/10/underground-cern-its-half-life/" target="_blank"&gt;older tunnel complexes&lt;/a&gt;.&lt;span style="font-family: inherit;"&gt;&amp;nbsp;As rouge elements are discovered, CERN has been educating transgressors&amp;nbsp;&lt;/span&gt;aggressively.&lt;span style="font-family: inherit;"&gt;&amp;nbsp;(Sometimes they go as far as sending employees to &lt;a href="http://half-life.wikia.com/wiki/Xen" target="_blank"&gt;Xen&lt;/a&gt; training... or was it &lt;a href="http://en.wikipedia.org/wiki/Xen" target="_blank"&gt;Xen&lt;/a&gt; training?)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-4NND3kC6IVA/T7G-ZD14MJI/AAAAAAAAALQ/hIYN5o5HxRA/s1600/2008-04-02-hadron-gordon-freeman.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="213" src="http://1.bp.blogspot.com/-4NND3kC6IVA/T7G-ZD14MJI/AAAAAAAAALQ/hIYN5o5HxRA/s320/2008-04-02-hadron-gordon-freeman.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;One artist's conception of what success will&lt;br /&gt;
look like for OpenStack at CERN&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;span style="font-family: inherit;"&gt;Despite the minor&amp;nbsp;&lt;/span&gt;hiccoughs&lt;span style="font-family: inherit;"&gt;&amp;nbsp;along the way, CERN is aiming for success. (Given the lack of Combine&lt;/span&gt;&amp;nbsp;and forced relocation programs, they're already doing better than Black Mesa's&amp;nbsp;Anomalous&amp;nbsp;Materials team.)&amp;nbsp;&lt;span style="font-family: inherit;"&gt;Plans are in place for an initial&amp;nbsp;&lt;/span&gt;pre-production service,&amp;nbsp;&lt;span style="font-family: inherit;"&gt;OpenStack deployment this year. Following that, they will be moving towards 300,000&amp;nbsp;virtual machines on 15,000 hosts spread across two data centres by 2015.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: inherit;"&gt;The OpenStack community is supporting them in their efforts with fantastic new features, high-quality discussions on the mail lists, and real-time interaction on the IRC channels.&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;In an act of reciprocity and community spirit, operators at CERN have volunteered to contribute back to the OpenStack community with regard to operations best practices, reference&amp;nbsp;&lt;/span&gt;architecture&lt;span style="font-family: inherit;"&gt;&amp;nbsp;documentation, and support on the operators' mail list.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
To see how other&amp;nbsp;institutions&amp;nbsp;were taking this news, I spent several days waiting on hold. In particular, Aperture&amp;nbsp;Science could not be reached for comment. However, Ops team member&amp;nbsp;&lt;span class="gI"&gt;Belmiro Rodrigues Moreira&lt;/span&gt;&amp;nbsp;did say that there's an audio file being circulated at CERN of Cave Johnson threatening to "burn down OpenStack" ... with lemons. Given Aperture Science's failure record with time machine development, it's generally assumed to be a prank audio reconstruction. CloudStack developers are considered to be the prime suspects, seeing how much time they have on their hands while waiting for ant to finish compiling the latest Java contributions.&lt;br /&gt;
&lt;br /&gt;
When asked what advice he could give to shops deploying OpenStack, Tim said simply: "Remember, the cake is a lie. Don't get distracted and don't stop. Just keep hacking."&lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-8Dcl3t-U0z4/T7F-jc0KLKI/AAAAAAAAALE/QYPV7ce7TPc/s1600/20090111171621!Eli-alyx-vance.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="213" src="http://4.bp.blogspot.com/-8Dcl3t-U0z4/T7F-jc0KLKI/AAAAAAAAALE/QYPV7ce7TPc/s320/20090111171621!Eli-alyx-vance.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Alyx, explaining to her dad why she loves DreamHost&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
Couldn't have said it better myself.&lt;br /&gt;
&lt;br /&gt;
In closing, and interestingly enough, one of DreamHost's employees has an uncle who works at the Black Mesa Research Facility. Though his teleportation research team was too busy for an extended interview,&amp;nbsp;&lt;a href="http://half-life.wikia.com/wiki/Alyx_Vance" target="_blank"&gt;his daughter&lt;/a&gt;&amp;nbsp;did mention that she is a DreamHost customer and can't wait to use OpenStack&amp;nbsp;while interning at CERN next summer. After all, that's what she uses to auto-scale her WordPress blog (she's in our private beta program). &lt;br /&gt;
&lt;br /&gt;
It's a small world.&lt;br /&gt;
&lt;br /&gt;
And, thanks to Tim and the rest at CERN, a safer one, too.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=efNvWnZK9F8:Ql45u-lvrDs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=efNvWnZK9F8:Ql45u-lvrDs:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=efNvWnZK9F8:Ql45u-lvrDs:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=efNvWnZK9F8:Ql45u-lvrDs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=efNvWnZK9F8:Ql45u-lvrDs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=efNvWnZK9F8:Ql45u-lvrDs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=efNvWnZK9F8:Ql45u-lvrDs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=efNvWnZK9F8:Ql45u-lvrDs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/efNvWnZK9F8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/134409467734847333/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/05/cern-openstack-keep-resonance-cascades.html#comment-form" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/134409467734847333?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/134409467734847333?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/efNvWnZK9F8/cern-openstack-keep-resonance-cascades.html" title="CERN, OpenStack Keep Resonance Cascades at Bay" /><author><name>Duncan McGreggor</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-nrh0l1Wyg7E/TwH5bXx6isI/AAAAAAAAAGw/CdDWpfpYaGg/s220/duncan_in_redwood_crop_retouch_2.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-soKhrWS6w6Y/T7FuvIlzm0I/AAAAAAAAAKg/AHpu8syxokc/s72-c/Gordonfreeman.jpg" height="72" width="72" /><thr:total>6</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/05/cern-openstack-keep-resonance-cascades.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04AQHs5cCp7ImA9WhBWGUQ.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-2550867840265368435</id><published>2012-05-12T17:50:00.001-07:00</published><updated>2013-04-14T21:25:41.528-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-14T21:25:41.528-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="conch" /><category scheme="http://www.blogger.com/atom/ns#" term="twisted" /><category scheme="http://www.blogger.com/atom/ns#" term="howtos" /><category scheme="http://www.blogger.com/atom/ns#" term="hacks" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="ssh" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="fixes" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><category scheme="http://www.blogger.com/atom/ns#" term="servers" /><title>Twisted SSH: Rendering a Log-in Banner/MOTD in Conch</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-UFw-54CdHh8/T68u-c2ePsI/AAAAAAAAAKI/52Nm1aD3meM/s1600/2000px-Twisted_Logo_(software).png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/-UFw-54CdHh8/T68u-c2ePsI/AAAAAAAAAKI/52Nm1aD3meM/s200/2000px-Twisted_Logo_(software).png" width="188" /&gt;&lt;/a&gt;&lt;/div&gt;
A few weeks ago, I pinged my peeps on #twisted asking why the banner for a custom SSH server wasn't rendering properly. After some digging around and some inconsistent results (well, consistently bad results for me), we weren't able to resolve anything, and I had to set the problem aside.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;The Symptom&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
The first thing I had tried was subclassing &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;Manhole&lt;/span&gt; from &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;twisted.conch.manhole&lt;/span&gt;, overriding (and up-calling) &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;connectionMade&lt;/span&gt;, writing the banner to the terminal upon successful connection. This didn't work, so I then tried overriding &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;initializeScreen&lt;/span&gt;&amp;nbsp;by subclassing&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;twisted.conch.recvline.RecvLine&lt;/span&gt;. Also a no-go. And by "didn't work" here's what I mean:&lt;br /&gt;
&lt;br /&gt;
In both Linux (Ubuntu 12.04 LTS, gnome-terminal) and Mac (OS X 10.6.8, Terminal.app), after a successful login to the Twisted SSH server, the following sequence would occur:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;an interactive Python prompt was rendered, e.g., ":&amp;gt;&amp;gt;"&lt;/li&gt;
&lt;li&gt;the banner was getting written to the terminal, and&lt;/li&gt;
&lt;li&gt;the terminal screen refreshed with the prompt at the top&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
This all happened so quickly, that I usually never even saw #1 and #2. Just the second ":&amp;gt;&amp;gt;" prompt from #3. Only by scrolling up the terminal buffer would I see that the banner had actually been rendered. Even though I was doing my &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;terminal.write&lt;/span&gt; after &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;connectionMade&lt;/span&gt; and &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;initializeScreen&lt;/span&gt;, it didn't seem to matter.&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Discovery!&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Some time last week, I put together example Twisted plugins showing what the problem was, and the circumstances under which a banner simply didn't get rendered. The idea was that I would provide some bare-bones test cases that demonstrated where the problem was occurring, post them to IRC or the Twisted mail list, and we could finally get it resolved. 'Cause, ya know, I really want my banners ...&lt;br /&gt;
&lt;br /&gt;
While tweaking the second Twisted plugin example, I finally poked my head into the right method and discovered the issue. Here's what's happening:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;twisted.conch.recvline.RecvLine.connectionMade&lt;/span&gt; calls &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;t.c.recvline.RecvLine.initializeScreen&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;t.c.recvline.RecvLine.initializeScreen&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;does a &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;terminal.reset&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;, writes the prompt, and then switches to insert mode. But this is a red herring. Since something after &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;initializeScreen&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; is causing the problem, we really need to be asking "who's calling &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;connectionMade&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;?"&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;t.c.manhole_ssh.TerminalSession.openShell&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; is what kicks it off when it calls the &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;transportFactory&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; (which is really&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;TerminalSessionTransport&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;openShell&lt;/span&gt; takes one parameter, &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;proto&lt;/span&gt; -- this is very important :-)&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;openShell&lt;/span&gt; instantiates&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;TerminalSessionTransport&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;TerminalSessionTransport&lt;/span&gt;&amp;nbsp;does one more thing after calling the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;makeConnection&lt;/span&gt; method on an&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;insults.ServerProtocol&lt;/span&gt; instance (the one I had tried overriding without success), and as such, this is the prime suspect for what was preventing the banner from being properly displayed: it calls &amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;chainedProtocol.terminalProtocol.terminalSize&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;chainedProtocol&lt;/span&gt;&amp;nbsp;is an&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;insults.ServerProtocol&lt;/span&gt; instance, and its &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;terminalProtocol&lt;/span&gt; attribute is set when&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ServerProtocol.connectionMade&lt;/span&gt;&amp;nbsp;is called.&lt;/li&gt;
&lt;li&gt;A quick check reveals that&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;terminalProtocol&lt;/span&gt;&amp;nbsp;is none other than the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;proto&lt;/span&gt; parameter passed to &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;openShell&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
But what &lt;i&gt;is&lt;/i&gt; &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;proto&lt;/span&gt;? Some debugging (and the fact that of the three &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;terminalSize&lt;/span&gt; methods in all of twisted, only one is an actual implementation) reveals that &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;proto&lt;/span&gt; is a&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;RecvLine&lt;/span&gt; instance. Reading that method uncovers the culprit in our whodunnit: &amp;nbsp;the first thing the method does is call &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;terminal.eraseDisplay&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Bingo! (And this is what I was referring to above when I said "poked my head" ...)&lt;br /&gt;
&lt;br /&gt;
Since this was called after all of my attempts to display a banner using both &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;connectionMade&lt;/span&gt; and &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;initializeScreen&lt;/span&gt;, there's no way my efforts would have succeeded.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Here's What You Do&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
How do you get around this? Easy! Subclass :-)&lt;br /&gt;
&lt;br /&gt;
The class &amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;TerminalSessionTransport&lt;/span&gt;&amp;nbsp;in &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;t.c.manhole_ssh&lt;/span&gt;&amp;nbsp;is the bad boy that calls &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;terminalSize&lt;/span&gt; (which calls &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;eraseDisplay&lt;/span&gt;). It's the last thing that&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;TerminalSessionTransport&lt;/span&gt;&amp;nbsp;does in its &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;__init__&lt;/span&gt;, so if we subclass it, and render our banner at the end of our &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;__init__&lt;/span&gt;, we should be golden. And we are :-)&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-rkj5zKv34qo/T7Ej7FRUKAI/AAAAAAAAAKU/v9EGXJwQu4o/s1600/Screenshot+from+2012-05-14+11:21:43.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="230" src="http://3.bp.blogspot.com/-rkj5zKv34qo/T7Ej7FRUKAI/AAAAAAAAAKU/v9EGXJwQu4o/s400/Screenshot+from+2012-05-14+11:21:43.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
You can see an example of this &lt;a href="https://github.com/dreamhost/dreamssh/blob/master/dreamssh/shell/base.py#L74" target="_blank"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Not sure if this sort of thing is better off in projects that make use of Twisted, or if it would be worth while to add this feature to Twisted itself. Time (and blog comments) will tell.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Epilogue&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
As is evident from the screenshot above (and the link), this feature is part of the &lt;a href="https://github.com/dreamhost/dreamssh" target="_blank"&gt;DreamSSH&lt;/a&gt; project. There are a handful of other nifty features/shortcuts that I have implemented in DreamSSH&amp;nbsp;(plus some cool ones that are coming)&amp;nbsp;and I'm using them in projects that need a custom SSH server. I released the &lt;a href="http://pypi.python.org/pypi/DreamSSH" target="_blank"&gt;first version of DreamSSH&lt;/a&gt; last night, and there's a pretty clear README on the github project page.&lt;br /&gt;
&lt;br /&gt;
One of the niftier things I did last night in preparation for the release was to dig into Twisted plugins and override some behaviour there. In order to make sure that the conveniences I had provided for devs with the Makefile were available for anyone who had DreamSSH installed, I added subcommands... but if the service was already running, these would fail. How to work around that (and other Twisted plugin tidbits) are probably best saved for another post, though :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=DMkHnCaip0Y:YbwHbrW941c:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=DMkHnCaip0Y:YbwHbrW941c:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=DMkHnCaip0Y:YbwHbrW941c:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=DMkHnCaip0Y:YbwHbrW941c:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=DMkHnCaip0Y:YbwHbrW941c:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=DMkHnCaip0Y:YbwHbrW941c:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=DMkHnCaip0Y:YbwHbrW941c:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=DMkHnCaip0Y:YbwHbrW941c:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/DMkHnCaip0Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/2550867840265368435/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/05/twisted-ssh-rendering-log-in-bannermotd.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/2550867840265368435?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/2550867840265368435?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/DMkHnCaip0Y/twisted-ssh-rendering-log-in-bannermotd.html" title="Twisted SSH: Rendering a Log-in Banner/MOTD in Conch" /><author><name>Duncan McGreggor</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-nrh0l1Wyg7E/TwH5bXx6isI/AAAAAAAAAGw/CdDWpfpYaGg/s220/duncan_in_redwood_crop_retouch_2.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-UFw-54CdHh8/T68u-c2ePsI/AAAAAAAAAKI/52Nm1aD3meM/s72-c/2000px-Twisted_Logo_(software).png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/05/twisted-ssh-rendering-log-in-bannermotd.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUCQXg-fip7ImA9WhVWE0U.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-3416349286218518862</id><published>2012-04-25T12:47:00.000-07:00</published><updated>2012-04-25T12:47:40.656-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-25T12:47:40.656-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="openstack" /><category scheme="http://www.blogger.com/atom/ns#" term="devops" /><category scheme="http://www.blogger.com/atom/ns#" term="development" /><category scheme="http://www.blogger.com/atom/ns#" term="operations" /><category scheme="http://www.blogger.com/atom/ns#" term="community" /><category scheme="http://www.blogger.com/atom/ns#" term="conferences" /><title>New Life: The OpenStack DevOps Community</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-FsuR_NWrcuA/T30gslonIUI/AAAAAAAAAIA/OQhQv_zfTS8/s1600/openstack-logo512.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/-FsuR_NWrcuA/T30gslonIUI/AAAAAAAAAIA/OQhQv_zfTS8/s200/openstack-logo512.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
Last week's OpenStack Design Summit and Conference were pretty fantastic events. Lots of great technical discussions, some good initial planning on large tasks, incredible numbers of conversations -- all of high quality! Looking back, though, I'd have to say that the high point of the event for me was what turned into the &lt;a href="http://folsomdesignsummit2012.sched.org/event/e176414e81687b80e00b91a7fbcdf0a6" target="_blank"&gt;DevOps community brainstorm session&lt;/a&gt; (&lt;a href="http://etherpad.openstack.org/FolsomDevOpsTeam" target="_blank"&gt;etherpad link&lt;/a&gt;) at the Design Summit&amp;nbsp;(all etherpads are &lt;a href="http://wiki.openstack.org/FolsomSummitEtherpads" target="_blank"&gt;here&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
The session was approved with the title of "OpenStack and Operations: Getting Real" with a major goal of deciding whether we needed to create a new top-level project for DevOps. So it was really "New DevOps Team?" However, all that changed once we got started, and there was some amazing feedback and enthusiasm in that room. By the end of it, we were all pretty pumped up and ready to jump in with all our hands and feet!&lt;br /&gt;
&lt;br /&gt;
The highest-level summary for me was this: The DevOps folks in the OpenStack community really need a point to rally around. Someplace they can not only talk to each other, share stories, get advice, etc., but also where they can have their voices heard by the predominantly developer-oriented OpenStack community. Jay Pipes suggested that a new section be added to the weekly IRC team leader meetings, and as &lt;a href="https://launchpad.net/~nova-operations" target="_blank"&gt;Nova Ops subteam&lt;/a&gt; lead (&lt;a href="http://wiki.openstack.org/Teams" target="_blank"&gt;teams list&lt;/a&gt;), I volunteered to collect top issues from the DevOps (sub-)community and give these some air-time in the meetings.&lt;br /&gt;
&lt;br /&gt;
Some other highlights from the session:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://trystack.org/"&gt;trystack.org&lt;/a&gt; needs volunteer admins -- a great opportunity for improving the dev &amp;lt;-&amp;gt; ops interface&lt;/li&gt;
&lt;li&gt;&lt;a href="http://public.web.cern.ch/public/" target="_blank"&gt;CERN&lt;/a&gt; is deeply invested in DevOps, and wants to share data and possibly help with defining reference architectures&lt;/li&gt;
&lt;li&gt;The same goes for the &lt;a href="http://www.unimelb.edu.au/" target="_blank"&gt;University of Melbourne&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;There was a good corporate presences in the session too, rallying around a new and improved DevOps community: HP, Yahoo, AT&amp;amp;T, Canonical, Rackspace, DreamHost, and more (sorry if I forgot you!)&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
There is a tremendous amount of information that we collected, but in written form (etherpads) as well as conversations during last week's event. As this is collected, we'll be reaching out to folks via the &lt;a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-operators" target="_blank"&gt;operators mail list&lt;/a&gt;, &lt;a href="http://planet.openstack.org/" target="_blank"&gt;blog posts&lt;/a&gt;, &lt;a href="https://twitter.com/#!/search/%23openstack%20AND%20%23devops" target="_blank"&gt;tweets&lt;/a&gt;, and &lt;a href="https://plus.google.com/s/%23openstack%20AND%20%23devops" target="_blank"&gt;Google+&lt;/a&gt; messages. Be sure to do the same! If you've got concerns, bring them up on the mail list, we'll get some bugs filed and blueprints put together, and come up with plans for addressing these.&lt;br /&gt;
&lt;br /&gt;
Thanks again, everyone!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=2N3RpPKgZGg:Qck5HFCuryU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=2N3RpPKgZGg:Qck5HFCuryU:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=2N3RpPKgZGg:Qck5HFCuryU:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=2N3RpPKgZGg:Qck5HFCuryU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=2N3RpPKgZGg:Qck5HFCuryU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=2N3RpPKgZGg:Qck5HFCuryU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=2N3RpPKgZGg:Qck5HFCuryU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=2N3RpPKgZGg:Qck5HFCuryU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/2N3RpPKgZGg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/3416349286218518862/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/04/new-life-openstack-devops-community.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/3416349286218518862?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/3416349286218518862?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/2N3RpPKgZGg/new-life-openstack-devops-community.html" title="New Life: The OpenStack DevOps Community" /><author><name>Duncan McGreggor</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-nrh0l1Wyg7E/TwH5bXx6isI/AAAAAAAAAGw/CdDWpfpYaGg/s220/duncan_in_redwood_crop_retouch_2.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-FsuR_NWrcuA/T30gslonIUI/AAAAAAAAAIA/OQhQv_zfTS8/s72-c/openstack-logo512.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/04/new-life-openstack-devops-community.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04HR3c5eSp7ImA9WhVXEk0.&quot;"><id>tag:blogger.com,1999:blog-8825992.post-4741067567372356371</id><published>2012-04-06T16:11:00.001-07:00</published><updated>2012-04-11T21:45:36.921-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-11T21:45:36.921-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="technology" /><category scheme="http://www.blogger.com/atom/ns#" term="latin" /><category scheme="http://www.blogger.com/atom/ns#" term="hindi" /><category scheme="http://www.blogger.com/atom/ns#" term="domains" /><category scheme="http://www.blogger.com/atom/ns#" term="words" /><category scheme="http://www.blogger.com/atom/ns#" term="blogging" /><category scheme="http://www.blogger.com/atom/ns#" term="io" /><title>New Domain Name for the Blog</title><content type="html">&lt;div&gt;
&lt;div&gt;
JP's wonderful &lt;a href="http://as.ynchrono.us/"&gt;blog sub-domain&lt;/a&gt; (and clever &lt;a href="http://s.ynchrono.us/"&gt;joke sub-domain&lt;/a&gt;) got me to thinking about what to do for a blog name again. Especially in the event that I ever leave blogger. For a year I tried using tau.tologo.us, but I think that was far too obscure a play on words. I gave up for a few years after that, and just stuck with the original username.blogspot.com setup.&lt;br /&gt;
&lt;br /&gt;
After revisiting the possibilities again, looking at everything from rephrasing Maxwell's equations as sub-domains to using a play on Hindi words (I almost went with blog.bija.li, doing the electric thing as well as going for the esoteric seed syllable/mantra reference). Also too obscure.&lt;br /&gt;
&lt;br /&gt;
After too many hours on &lt;a href="http://translate.google.com/"&gt;Google Translate&lt;/a&gt; (trying something out, getting it translated, back-translating it; that often provides humorous -- if not enlightening -- results), I managed to stumble across one I really liked. Immediately, in fact: &lt;a href="http://cogitat.io/"&gt;cogitat.io&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
How is it that this hasn't been taken? I was dumb-founded. And delighted :-) Check out the possible translations of the Latin goodness:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;thought&lt;/li&gt;
&lt;li&gt;cogitation&lt;/li&gt;
&lt;li&gt;thinking&lt;/li&gt;
&lt;li&gt;considering&lt;/li&gt;
&lt;li&gt;deliberating&lt;/li&gt;
&lt;li&gt;reflection&lt;/li&gt;
&lt;li&gt;meditation&lt;/li&gt;
&lt;li&gt;reflexion&lt;/li&gt;
&lt;li&gt;thought&lt;/li&gt;
&lt;li&gt;design&lt;/li&gt;
&lt;li&gt;plan&lt;/li&gt;
&lt;li&gt;reasoning power &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Splitting words at the tld, we get the aptly wonderful &lt;i&gt;cogitat i/o&lt;/i&gt;: "&lt;span class="short_text" id="result_box" lang="en"&gt;&lt;span class="hps"&gt;he thinks I/O." As a programmer who specializes in side effects (don't most of us?), I'm surrounded by I/O. I view it as software's analog to the ever-important physics (and life) concept of "cause and effect." Needless to say, I do love the tld. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
With the domain all set up, I was off to Blogspot... only to find that Google doesn't let you use "naked" domains as your blog name.&lt;br /&gt;
&lt;br /&gt;
*sigh*&lt;br /&gt;
&lt;br /&gt;
So then it was back to the drawing board (Google Translate). Fortunately, after just a few minutes of playing around, &lt;i&gt;technicae&lt;/i&gt; popped up, and I thought this &lt;i&gt;might&lt;/i&gt; be it. &lt;i&gt;technicae cogitat io&lt;/i&gt; can almost be translated as "meditating on technology" or "the design of technology."&lt;br /&gt;
&lt;br /&gt;
But there's more: I saw that if &lt;i&gt;io&lt;/i&gt; was typed with a capital &lt;i&gt;I&lt;/i&gt;, it would render the translation as "John." Which has led to the ultimate, most profound, inner-most secret essence of this blog:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;i&gt;Technicae cogitat Io.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;Videre Io currunt.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;Currere, Io! Currere!&lt;/i&gt;&lt;/blockquote&gt;
Probably not something something Cicero would have recognized, nor even something parsable in Vulgar Latin. Most of you have probably already got it, though. Regardless, here it is in naked English:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span class="" id="result_box" lang="en"&gt;&lt;span class="hps"&gt;"John&lt;/span&gt; &lt;span class="hps"&gt;thinks about&lt;/span&gt; &lt;span class="hps"&gt;technology&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span class="" id="result_box" lang="en"&gt; &lt;span class="hps"&gt;See&lt;/span&gt; &lt;span class="hps"&gt;John&lt;/span&gt; &lt;span class="hps"&gt;run&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span class="" id="result_box" lang="en"&gt; &lt;span class="hps"&gt;Run&lt;/span&gt;, &lt;span class="hps"&gt;John&lt;/span&gt;! &lt;span class="hps"&gt;Run&lt;/span&gt;!&lt;/span&gt;"&lt;/blockquote&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=rdODprqxEM8:5lc8a7CXUmk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=rdODprqxEM8:5lc8a7CXUmk:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=rdODprqxEM8:5lc8a7CXUmk:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=rdODprqxEM8:5lc8a7CXUmk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=rdODprqxEM8:5lc8a7CXUmk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=rdODprqxEM8:5lc8a7CXUmk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?i=rdODprqxEM8:5lc8a7CXUmk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ElectricDuncan?a=rdODprqxEM8:5lc8a7CXUmk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ElectricDuncan?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElectricDuncan/~4/rdODprqxEM8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://technicae.cogitat.io/feeds/4741067567372356371/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://technicae.cogitat.io/2012/04/new-domain-name-for-blog.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/4741067567372356371?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8825992/posts/default/4741067567372356371?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ElectricDuncan/~3/rdODprqxEM8/new-domain-name-for-blog.html" title="New Domain Name for the Blog" /><author><name>Duncan McGreggor</name><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://3.bp.blogspot.com/-nrh0l1Wyg7E/TwH5bXx6isI/AAAAAAAAAGw/CdDWpfpYaGg/s220/duncan_in_redwood_crop_retouch_2.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://technicae.cogitat.io/2012/04/new-domain-name-for-blog.html</feedburner:origLink></entry></feed>
