<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Robert Chatley</title>
 <link href="http://chatley.com/atom.xml" rel="self"/>
 <link href="http://chatley.com"/>
 <updated>2011-10-28T13:16:24+01:00</updated>
 <id>http://chatley.com</id>
 <author>
   <name>Robert Chatley</name>
   <email>robert@chatley.com</email>
 </author>
 
 
 <entry>
   <title>Making Music with Clojure and Overtone</title>
   <link href="http://chatley.com/posts/10-28-2011/overtone"/>
   <updated>2011-10-28T00:00:00+01:00</updated>
   <id>http://chatley.com/posts/10-28-2011/overtone</id>
   <content type="html">&lt;p&gt;This week I attended the London Clojure Dojo for the first time. It was a special edition focussed on making music using &lt;a href='http://overtone.github.com/'&gt;Overtone&lt;/a&gt;. A couple of weeks ago I was presenting a Clojure tutorial at the &lt;a href='http://www.fpday.net/fpday2011/index.php'&gt;FPDay&lt;/a&gt; conference in Cambridge, and met &lt;a href='http://sam.aaron.name/'&gt;Sam Aaron&lt;/a&gt; there. Sam is one of the main proponents and developers of Overtone, and he came to London to give us an introduction - then it was up to us to see if we could make any interesting music, or at least noises.&lt;/p&gt;

&lt;p&gt;Overtone is a piece of software written in Clojure that provides a front-end to a synthesiser - we were using SuperCollider. By writing and evaluating bits of Clojure code, we can send commands to the synthesizer to create sounds. Sam explained how the components of SuperCollider work internally, with synths, busses and buffers, but when we came to try it, it seemed like people could be more creating using Overtone by working at a higher level of abstraction, talking about notes and chord progressions, rather than frequencies and waveforms. Music seems to fit quite naturally with levels of abstraction, from notes we build chords, or fill in bars, then build these into bars and phrases, and maybe use these to assemble a higher level form like a Viennese waltz or a twelve-bar blues.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/overtone/sam-landscape.jpg' alt='Group' /&gt;&lt;/p&gt;

&lt;p&gt;It was interesting to see that the group was made up of some people who knew a lot about programming, but not so much about music, others who were musicians, but didn&amp;#8217;t really know much about programming, and some who fell in between. Some people came from the perspective of having learned an instrument, others were more familiar with synthesis and creating sounds, and then perhaps using software like Cubase or GarageBand to sequence sounds into compositions.&lt;/p&gt;

&lt;p&gt;We split into groups and played around with trying to make some music, then at the end we came back together for a show (and listen) and tell. It was pretty impressive what people could come up with in just over an hour, with little prior knowledge of the system.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/overtone/nicholas.jpg' alt='@ntoll' /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='http://twitter.com/ntoll'&gt;Nicholas&lt;/a&gt;, who trained at the Royal College of Music but later studied computing and now works in a startup as a programmer, used Overtone to create a piece of music inspired by Steve Reich&amp;#8217;s &lt;a href='http://www.youtube.com/watch?v=AnC5DhNqZ6w'&gt;Piano Phase&lt;/a&gt;. He took a sequence of notes and generated a repeated cycle in the Clojure code. Then he played two voices of this sequence at the same time, one very gradually speeding up, creating phase shifts with the version playing at a constant tempo.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/overtone/marius.jpg' alt='Marius' /&gt;&lt;/p&gt;

&lt;p&gt;Marius and his group took some of the example code as a starting point, playing a dubstep track, but then hooked up an iPad app &lt;a href='http://hexler.net/software/touchosc'&gt;touchosc&lt;/a&gt; that allowed them to interact with the music in realtime by using sliders on the screen of the iPad. They used this to modulate the pitch of the music, and superimpose another tune over the top.&lt;/p&gt;

&lt;p&gt;For our own efforts, we contentrated on the lower level end of things, looking at how to create instruments and control the synthesiser by sending it messages. We created sequences of frequencies (pitches) and times to change frequency. In this way we could slide notes up or down over time. We realised that to do this better, and better emulate something like a piano glissando, we needed to make the steps in frequency proportional to the current frequency, as the frequency of a note doubles with every octave rather than increasing linearly, but we didn&amp;#8217;t have time to figure out the maths. Here&amp;#8217;s a snippet:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='clojure'&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;definst&lt;/span&gt; &lt;span class='nv'&gt;square-wave&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nv'&gt;freq&lt;/span&gt; &lt;span class='mi'&gt;440&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;square&lt;/span&gt; &lt;span class='nv'&gt;freq&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;

&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;def &lt;/span&gt;&lt;span class='nv'&gt;times&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;take &lt;/span&gt;&lt;span class='mi'&gt;220&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;iterate &lt;/span&gt;&lt;span class='o'&gt;#&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;+&lt;/span&gt; &lt;span class='mi'&gt;30&lt;/span&gt; &lt;span class='nv'&gt;%&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)))&lt;/span&gt;

&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;defn &lt;/span&gt;&lt;span class='nv'&gt;change-pitch&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nv'&gt;t&lt;/span&gt; &lt;span class='nv'&gt;f&lt;/span&gt; &lt;span class='nv'&gt;inst&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;at&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;+ &lt;/span&gt;&lt;span class='nv'&gt;t&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;now&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;ctl&lt;/span&gt; &lt;span class='nv'&gt;inst&lt;/span&gt; &lt;span class='nv'&gt;:freq&lt;/span&gt; &lt;span class='nv'&gt;f&lt;/span&gt;&lt;span class='p'&gt;)))&lt;/span&gt;

&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;defn &lt;/span&gt;&lt;span class='nv'&gt;falling-pitches&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nv'&gt;start&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;take &lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;/ &lt;/span&gt;&lt;span class='nv'&gt;start&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;iterate &lt;/span&gt;&lt;span class='nv'&gt;dec&lt;/span&gt; &lt;span class='nv'&gt;start&lt;/span&gt;&lt;span class='p'&gt;)))&lt;/span&gt;
&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;defn &lt;/span&gt;&lt;span class='nv'&gt;rising-pitches&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nv'&gt;start&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;take &lt;/span&gt;&lt;span class='nv'&gt;start&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;iterate &lt;/span&gt;&lt;span class='nv'&gt;inc&lt;/span&gt; &lt;span class='nv'&gt;start&lt;/span&gt;&lt;span class='p'&gt;)))&lt;/span&gt;

&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;defn &lt;/span&gt;&lt;span class='nv'&gt;slide&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nv'&gt;pitches&lt;/span&gt; &lt;span class='nv'&gt;inst&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;map &lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fn &lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nv'&gt;x&lt;/span&gt; &lt;span class='nv'&gt;y&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;change-pitch&lt;/span&gt; &lt;span class='nv'&gt;x&lt;/span&gt; &lt;span class='nv'&gt;y&lt;/span&gt; &lt;span class='nv'&gt;inst&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='nv'&gt;times&lt;/span&gt; &lt;span class='nv'&gt;pitches&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;

&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;square-wave&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;slide&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;falling-pitches&lt;/span&gt; &lt;span class='mi'&gt;440&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;square-wave&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;slide&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;rising-pitches&lt;/span&gt; &lt;span class='mi'&gt;220&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;square-wave&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;stop&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Overall a very interesting and enjoyable evening working on something fun with some clever people. I certainly hope to return to the dojo and to try out some more things with Overtone.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Top Down TDD in Clojure with Brian Marick</title>
   <link href="http://chatley.com/posts/09-21-2011/marick-clojure-tdd"/>
   <updated>2011-09-21T00:00:00+01:00</updated>
   <id>http://chatley.com/posts/09-21-2011/marick-clojure-tdd</id>
   <content type="html">&lt;p&gt;This week I attended a two-day course on top-down TDD in Clojure, led by &lt;a href='http://twitter.com/marick'&gt;Brian Marick&lt;/a&gt;. The course was organised through the London agile community group the &lt;a href='http://xpday-london.editme.com/eXtremeTuesdayClub'&gt;Extreme Tuesday Club (XTC)&lt;/a&gt; and generously supported by &lt;a href='http://www.zuehlke.com/en/'&gt;Zuhlke Engineering&lt;/a&gt; who provided the venue, allowing us the use one of their conference rooms, and access to enough tea and coffee to get us through two days of thinking and programming.&lt;/p&gt;

&lt;p&gt;The aim of the course was to learn about, and to try out, techniques for test-driven development in Clojure, especially using &lt;a href='https://github.com/marick/Midje'&gt;Midje&lt;/a&gt; - a tool that Brian wrote to enable programmers to use a form of mocking during development of Clojure programs. Using Midje allows programmers to explore a problem working in a breadth-first manner, without having to define all of the supporting functions at lower levels of implementation until later on.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/marick/brian.jpg' alt='Marick' /&gt;&lt;/p&gt;

&lt;p&gt;The course attracted a pretty experienced group of attendees, with some regular Clojure programmers, including a couple of people who help to organise the London Clojure Dojo, and some TDD experts including Steve Freeman and Nat Pryce, the authors of &lt;a href='http://www.growing-object-oriented-software.com/'&gt;GOOS&lt;/a&gt;. This led to some very interesting and detailed discussions, and also meant that the course quickly changed from being an instructor-led tutorial into more of an exploratory workshop, debating the pros and cons of various approaches to problems.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/marick/group.jpg' alt='Group' /&gt;&lt;/p&gt;

&lt;p&gt;A Midje test defines some facts about the world as we would like it to be, once we have finished our program. For example we could be writing a program to calculate the vegetarian breakfast menu for a hotel. We can state a fact that we want to be true, and some clauses to set up the situation under which this could be the case. For example, we can say that the vegetarian menu will be cereal, provided that the full menu is cereal or a full-english, a full-english contains meat, but cereal does not. Using Midje we could define that like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='clojure'&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;ns&lt;/span&gt; &lt;span class='nv'&gt;midje-example&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='nv'&gt;core&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;:use&lt;/span&gt; &lt;span class='nv'&gt;midje&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='nv'&gt;sweet&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;

&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;fact&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;veggie-breakfast&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;cereal&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; 
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;provided&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;breakfast-menu&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;cereal&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt; &lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;full-english&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;provided&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;contains-meat?&lt;/span&gt; &lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;full-english&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nv'&gt;true&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;provided&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;contains-meat?&lt;/span&gt; &lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;cereal&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nv'&gt;false&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We can use Midje&amp;#8217;s meta-constants (denoted by two dots before and after the name, e.g.. &lt;code&gt;..cereal..&lt;/code&gt;) to fill in the test, even though we have not yet decided the data structure that we will use to model food items or menus. We use the &lt;code&gt;provided&lt;/code&gt; clauses to define sufficient properties of the meta-constants to make the test work. This is the top-down nature of this style of TDD, we will move on to making these decisions later, but can get our higher level function working first.&lt;/p&gt;

&lt;p&gt;Clojure isn&amp;#8217;t happy if we use things that are not defined, so we create a skeleton definition of &lt;code&gt;veggie-breakfast&lt;/code&gt; which is our function under test, and use Midje to create skeletons for our other unfinished functions.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='clojure'&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;ns&lt;/span&gt; &lt;span class='nv'&gt;midje-example&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='nv'&gt;core&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;:use&lt;/span&gt; &lt;span class='nv'&gt;midje&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='nv'&gt;sweet&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;

&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;unfinished&lt;/span&gt; &lt;span class='nv'&gt;breakfast-menu&lt;/span&gt; &lt;span class='nv'&gt;contains-meat?&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;defn &lt;/span&gt;&lt;span class='nv'&gt;veggie-breakfast&lt;/span&gt; &lt;span class='p'&gt;[]&lt;/span&gt; &lt;span class='p'&gt;[])&lt;/span&gt;

&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;fact&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;veggie-breakfast&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;cereal&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; 
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;provided&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;breakfast-menu&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;cereal&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt; &lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;full-english&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;provided&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;contains-meat?&lt;/span&gt; &lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;full-english&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nv'&gt;true&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;provided&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;contains-meat?&lt;/span&gt; &lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;cereal&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nv'&gt;false&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then we can run Midje, and it tells us that our fact is not confirmed - which is not unexpected, as we haven&amp;#8217;t written our function yet. Now we complete the implementation, run it again, and show that things are working.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='clojure'&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;ns&lt;/span&gt; &lt;span class='nv'&gt;midje-example&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='nv'&gt;core&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;:use&lt;/span&gt; &lt;span class='nv'&gt;midje&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='nv'&gt;sweet&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;

&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;unfinished&lt;/span&gt; &lt;span class='nv'&gt;breakfast-menu&lt;/span&gt; &lt;span class='nv'&gt;contains-meat?&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;defn &lt;/span&gt;&lt;span class='nv'&gt;veggie-breakfast&lt;/span&gt; &lt;span class='p'&gt;[]&lt;/span&gt; 
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;filter &lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;complement &lt;/span&gt;&lt;span class='nv'&gt;contains-meat?&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;breakfast-menu&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;fact&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;veggie-breakfast&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;cereal&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; 
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;provided&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;breakfast-menu&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;cereal&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt; &lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;full-english&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;provided&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;contains-meat?&lt;/span&gt; &lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;full-english&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nv'&gt;true&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;provided&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nf'&gt;contains-meat?&lt;/span&gt; &lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='nv'&gt;cereal&lt;/span&gt;&lt;span class='o'&gt;..&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nv'&gt;false&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;At the moment, for the smoothest experience, you need to use the emacs integration that Brian has developed. There is a leiningen plugin, but it is quite slow to run, so running even a small test suite can take a good few seconds, which is slightly annoying. It would be nice to have some effective tooling to work with the La Clojure plugin for IntelliJ. I think that that would help with Midje adoption.&lt;/p&gt;

&lt;p&gt;We spent a good deal of time discussing static versus dynamic dependencies in Clojure programs, how to create seams to inject dependencies on underlying components, and whether doing so was required or idiomatic in Clojure. I don&amp;#8217;t think we reached any firm conclusions, but it was interesting to explore possibilities and constraints.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/marick/smiles.jpg' alt='Group' /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>On Learning JavaScript</title>
   <link href="http://chatley.com/posts/07-18-2011/on-learning-javascript"/>
   <updated>2011-07-18T00:00:00+01:00</updated>
   <id>http://chatley.com/posts/07-18-2011/on-learning-javascript</id>
   <content type="html">&lt;p&gt;In the last week, I have been learning JavaScript. Like many people, I had previously written little bits and pieces of JavaScript on web projects to try and make various bits of HTML pages dynamic, but I&amp;#8217;d never looked at it in depth as a proper programming language. I&amp;#8217;ve now come to quite like it.&lt;/p&gt;

&lt;p&gt;I think that one of the things that affects people&amp;#8217;s judgement of JavaScript is the environment of the browser and the interaction with the DOM. With all of the browser inconsistencies, and the clunkiness of the DOM API, the experience of writing JavaScript can be a bad one. I know I certainly never enjoyed it before. It never really felt like a proper language, but now I think I just wasn&amp;#8217;t doing it right. Somewhere this week I read that JavaScript is the only language that people feel that they don&amp;#8217;t need to learn before they use it. Development often follows a &lt;a href='http://www.mcs.vuw.ac.nz/comp/Publications/CS-TR-02-9.abs.html'&gt;post-modern&lt;/a&gt; approach of Googling for snippets and pasting them into HTML pages.&lt;/p&gt;

&lt;p&gt;I wanted to give JavaScript a chance as a proper language, so I wanted to try it away from the browser. Thankfully, the current popularity of &lt;a href='http://nodejs.org/'&gt;node.js&lt;/a&gt; means that there is an easy way to try out programs using a command-line interpreter. Not everything you write in node needs to be a web server. It is a full JavaScript interpreter built on V8, so it can run any valid script. The other tool that I wanted was something to do unit testing. I find that test-driven development is a very helpful approach in learning a new language, as for every example I try it can give me fast feedback on whether or not my code works as I expect. I looked around for a unit testing tool for node, getting some good advice from &lt;a href='http://twitter.com/david_harvey'&gt;David Harvey&lt;/a&gt; and &lt;a href='http://twitter.com/raoulmillais'&gt;Raoul Millais&lt;/a&gt;. In the end I settled on &lt;a href='https://github.com/futuresimple/jessie'&gt;jessie&lt;/a&gt;, which is an enhanced runner for &lt;a href='http://pivotal.github.com/jasmine/'&gt;jasmine&lt;/a&gt;, and allows you to write &lt;a href='http://relishapp.com/rspec'&gt;rspec&lt;/a&gt;-like specs, and to run them easily from the command line.&lt;/p&gt;

&lt;p&gt;The other thing I needed was a source of knowledge. I read two books which I found helpful. The first was Douglas Crockford&amp;#8217;s &lt;a href='http://oreilly.com/catalog/9780596517748'&gt;JavaScript: The Good Parts&lt;/a&gt;. This is a good introduction, laying out the fundamentals of the language. It is reasonably short and easy to understand. It does not cover the who language - as the title says, only the subset that Crockford considers the good parts. It is a little concerning that the book has appendices called Bad Parts and Awful Parts. The style of this book is terse, at some places to the point of bluntness, but it is quite easy to read. To accompany this, I found it useful to watch the Google I/O &lt;a href='http://www.youtube.com/watch?v=seX7jYI96GE'&gt;presentation by Alex Russell&lt;/a&gt;. This covers few basics, but gives an idea of how to think about the language. The second book I read was Stoyan Stefanov&amp;#8217;s &lt;a href='http://oreilly.com/catalog/9780596806767'&gt;JavaScript Patterns&lt;/a&gt;. This book is much more advanced. It does have an introduction to the language but it moves pretty fast. Don&amp;#8217;t read this book as your first JavaScript book. It is good though, and has lots of useful information about object-creation, inheritance mechanisms and design patterns.&lt;/p&gt;

&lt;p&gt;The main characteristics of the language as far as I can see, some of which were slightly surprising to me, are: JavaScript is a functional language and functions are first class citizens; Functions are the only way to define scope; There are no classes; Almost everything is an object; Almost everything is mutable. These characteristics make it very different from its (almost) namesake Java, which is another source of confusion. There seem to be many ways to try to make JavaScript work more like Java, by implementing things that are a bit like classes and classical inheritance, but I now see that doing this is not really in the idiom of the language.&lt;/p&gt;

&lt;p&gt;I thought I would just run through one of the examples that I&amp;#8217;ve put together this week, which helped me to understand things better. It&amp;#8217;s writing a program to generate the Fibonacci sequence, something that I&amp;#8217;m sure most programmers have done at least a few times in their lives in programming exercises. To start with I wrote a test:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;require&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;./fibonacci&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='nx'&gt;describe&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Fibonacci Sequence&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
	
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;fib&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;FibonacciSequence&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;

  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;defines the first two terms to be 1&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;fib&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;fib&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
		
  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;has each term equal to the sum of the previous two&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;fib&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;fib&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;fib&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;

&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This uses a test syntax pretty similar to the rspec syntax that may well be familiar to Ruby programmers. Although it looks like we&amp;#8217;re using &lt;code&gt;new&lt;/code&gt; to create an object of the class FibonacciSequence, there are no classes in JavaScript. We&amp;#8217;re calling a constructor function, that returns a new object, but there are no classes. Here&amp;#8217;s the implementation.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;FibonacciSequence&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;FibonacciSequence&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='p'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We should also specify what happens in the case of a negative argument. Let&amp;#8217;s say we expect an exception to be thrown. We can add a test for that:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;  &lt;span class='p'&gt;...&lt;/span&gt;
  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;is not defined for negative terms&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='nx'&gt;fib&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;toThrow&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Argument may not be negative: -1&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
  &lt;span class='p'&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note how the expectation has to be set up slightly differently, as we don&amp;#8217;t want to call the piece of code that we&amp;#8217;re expecting to throw an exception while we&amp;#8217;re in the middle of setting up the expectation. We wrap the code we want to test in an anonymous function, and pass that to jessie for it to call later, when the time is right. In the implementation, we throw an error in a fairly standard way. The only thing to note is that as JavaScript isn&amp;#8217;t strongly typed, we don&amp;#8217;t have to throw something that is a sub-type of a particular exception class. There are no classes. So we can throw whatever we want. Here I just threw a string, although you could easily construct your own exception object if you preferred. Updating the implementation gives us:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;FibonacciSequence&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;FibonacciSequence&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;throw&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Argument may not be negative: &amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toString&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='p'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='update'&gt;Update:&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;After posting this, &lt;a href='http://twitter.com/raoulmillais'&gt;Raoul&lt;/a&gt; commented that it would have been more idiomatic to return &lt;code&gt;undefined&lt;/code&gt; rather than throwing the error in the above example. It would also seem to fit rather better with the problem domain, given the way I named my test. Changing this gives the below:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='p'&gt;...&lt;/span&gt;
 &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;is not defined for negative terms&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
   &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;fib&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)).&lt;/span&gt;&lt;span class='nx'&gt;toBeUndefined&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
 &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='p'&gt;...&lt;/span&gt;
&lt;span class='nx'&gt;FibonacciSequence&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;FibonacciSequence&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kc'&gt;undefined&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The other feature that I wanted to implement was the ability to iterate through the sequence, rather than just calculating specific terms. As the sequence is mathematically infinite, an internal iterator wasn&amp;#8217;t going to be much use here, as although it would be very easy, and idiomatic, to pass in a closure to apply to each element of the sequence, this might never terminate. At least for this example, we want an external iterator.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;can be iterated through&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;seq&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;fib&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;iterator&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;seq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;next&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;seq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;next&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;seq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;next&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;seq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;next&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;seq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;next&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;

  &lt;span class='nx'&gt;it&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;can have multiple independent iterators&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;seq&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;fib&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;iterator&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;seq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;next&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;seq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;next&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;seq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;next&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;seq2&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;fib&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;iterator&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;seq2&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;next&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;seq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;next&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='nx'&gt;expect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;seq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;next&lt;/span&gt;&lt;span class='p'&gt;()).&lt;/span&gt;&lt;span class='nx'&gt;toEqual&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Implementing this turns out to be quite straightforward. One of the key messages from Alex Russell&amp;#8217;s talk mentioned above was that when we program in JavaScript we need to reverse our thinking, from objects where we store data and then attach behaviour, to functions which - through the mechanism of closure - have data storage attached. Here my iterator function is defined as a property of the sequence object, so I can access it from the sequence, and when I call it, it returns a new object which is the iterator, with a &lt;code&gt;next()&lt;/code&gt; method. The iterator&amp;#8217;s index is just a local variable inside the &lt;code&gt;iterator()&lt;/code&gt; function, whose state is maintained as part of the closure. We don&amp;#8217;t need to store it in a field. The only thing that looks slightly strange, and took me a while to get my head around, was the need to make the assignment &lt;code&gt;that = this&lt;/code&gt;. We need this in order to store a reference to the sequence object inside the closure, otherwise we won&amp;#8217;t later have access to the &lt;code&gt;term()&lt;/code&gt; method. This is due to the &amp;#8220;special&amp;#8221; way in which the keyword &lt;code&gt;this&lt;/code&gt; works. &lt;a href='http://www.jslint.com/'&gt;JsLint&lt;/a&gt; wasn&amp;#8217;t very happy about me using the &lt;code&gt;++&lt;/code&gt; operator to increment &lt;code&gt;i&lt;/code&gt;, but I thought it could keep its opinion to itself on that one.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;FibonacciSequence&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;FibonacciSequence&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;throw&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Argument may not be negative: &amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;toString&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;===&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;iterator&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;that&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='nx'&gt;next&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;that&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;term&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;++&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;};&lt;/span&gt;
  &lt;span class='p'&gt;};&lt;/span&gt;
&lt;span class='p'&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;So that is the end result, and I think it looks quite neat. It is pretty functional in style. It doesn&amp;#8217;t define any types or classes, only functions, and the test looks pretty much like an rspec test. Overall I&amp;#8217;m quite pleased with the way I was able to write programs in JavaScript once I understood how it worked, and what was idiomatic. I feel I should pursue this some more, especially with the growing interest in Node in the industry.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Agile Engineering Practices in Oxford</title>
   <link href="http://chatley.com/posts/07-04-2011/oxford-agile-engineering-practices"/>
   <updated>2011-07-04T00:00:00+01:00</updated>
   <id>http://chatley.com/posts/07-04-2011/oxford-agile-engineering-practices</id>
   <content type="html">&lt;p&gt;Last week I taught the first iteration of the &lt;a href='http://www.softeng.ox.ac.uk/subjects/APE.html'&gt;Agile Engineering Practices&lt;/a&gt; course, as part of Oxford University&amp;#8217;s &lt;a href='http://www.softeng.ox.ac.uk/'&gt;Software Engineering MSc&lt;/a&gt;. For a while this MSc programme has included a module on &lt;a href='http://www.softeng.ox.ac.uk/subjects/AGM.html'&gt;Agile Methods&lt;/a&gt; taught by &lt;a href='http://www.martinitconsulting.com/agile/home.html'&gt;Angela Martin&lt;/a&gt; which has proved very popular with the students. That course compares the various different named agile methods, and focusses mostly on issues of process and human communication.&lt;/p&gt;

&lt;p&gt;My new course aims to compliment this with an in-depth look at the engineering practices that support the application of such a method to software development, and allow a product to be developed iteratively and incrementally, continuously delivering valuable features. The students on the course are studying part-time, taking time out from jobs in industry, so they brought their own experiences from their working lives. This led to interesting discussion and debate on a number of topics.&lt;/p&gt;

&lt;p&gt;I wanted the course to be very practical, so we spent more than half of the week in the computer lab working on hands-on exercises. With a relatively small class and the intensive format of the course (each module is taught as a solid week of classes) we were able to have one exercise follow on from another, and try to pull all of the tools and techniques together. We started with some work on version control strategies, and then followed this up with creating an automated build and setting up a continuous integration server. Over the next couple of days we looked at refactoring techniques, introducing seams to legacy code to try and get it under test, and various testing techniques at the unit and system level. To conclude the arc we spent some time looking at release and deployment techniques. I encouraged the students to pair program, learn from each other and help each other out.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/apeoxford/elena-ola.jpg' alt='Elena and Ola pairing' /&gt;&lt;img src='/images/apeoxford/shah-david.jpg' alt='Elena and Ola pairing' /&gt;&lt;/p&gt;

&lt;p&gt;We covered a lot of different technical topics, and I found it hard to recommend one book for the students to use as their course textbook. We looked at subjects detailed in Joshua Kerievsky&amp;#8217;s &lt;a href='http://www.industriallogic.com/xp/refactoring/'&gt;Refactoring to Patterns&lt;/a&gt;, Freeman and Pryce&amp;#8217;s &lt;a href='http://www.growing-object-oriented-software.com/'&gt;GOOS&lt;/a&gt;, Michael Feathers&amp;#8217; &lt;a href='http://www.amazon.co.uk/Working-Effectively-Legacy-Robert-Martin/dp/0131177052'&gt;Legacy Code book&lt;/a&gt; and Gojko Adzic&amp;#8217;s &lt;a href='http://specificationbyexample.com/'&gt;Specification by Example&lt;/a&gt;. In the end I gave the class references to all of these books, but recommended Jez Humble and Dave Farley&amp;#8217;s &lt;a href='http://continuousdelivery.com'&gt;Continuous Delivery&lt;/a&gt; as the book that motivated all the themes and gave the big picture of what we were trying to do - minimise the cycle time from idea to delivery, and allow that cycle to be repeated frequently and reliably.&lt;/p&gt;

&lt;p&gt;We had a good week, and (I think) the students enjoyed the class. There is definitely room for improvement though. Our end of course retrospective produced some ideas for things to add and change. The next iteration of this course in Oxford is in January, so we&amp;#8217;ve got some time to tune the materials. I&amp;#8217;m looking forward to it. I should also thank my teaching assistant &lt;a href='http://www.cs.ox.ac.uk/people/jim.whitehead/'&gt;Jim Whitehead&lt;/a&gt;, who was a great help throughout the week.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/apeoxford/class.jpg' alt='The class' /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>SPA2011 - The Great Egg Race</title>
   <link href="http://chatley.com/posts/06-20-2011/spa-great-egg-race"/>
   <updated>2011-06-20T00:00:00+01:00</updated>
   <id>http://chatley.com/posts/06-20-2011/spa-great-egg-race</id>
   <content type="html">&lt;p&gt;At the &lt;a href='http://www.spaconference.org'&gt;SPA2011&lt;/a&gt; conference, we set the attendees a challenge. We invited people to build something during the conference. We suggest they form teams, and use the challenge to show off their development skills, perhaps using a new technique learned at the conference, or showing everyone the benefits of the One True Way (whichever way they happen to think that is). We set aside time in the programme for people to work on their projects, but I think the majority of the work was done in the hallway, the coffee breaks, the bar, and possibly even in other people&amp;#8217;s sessions&amp;#8230; We gave the challenge the name The Great Egg Race after the 1980s &lt;a href='http://www.bbc.co.uk/archive/great_egg_race/'&gt;BBC television series&lt;/a&gt; hosted by Prof Heinz Wolff.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://twitter.com/marcevers'&gt;Marc Evers&lt;/a&gt; and I facilitated, but we based the challenge on an idea from &lt;a href='http://twitter.com/mfeathers'&gt;Michael Feathers&lt;/a&gt; that he presented in his &lt;a href='http://www.xp2011.org'&gt;XP2011&lt;/a&gt; workshop &lt;a href='http://xp2011.org/program?sid=401&amp;amp;o=1'&gt;Refactoring in the 4th Dimension&lt;/a&gt;. In that workshop Michael encouraged people to use his &lt;a href='https://github.com/michaelfeathers/repodepot-ruby'&gt;repo-depot&lt;/a&gt; ruby library to explore some data that he had extracted from some git repositories, to try and extract patterns over time. Is it more common for people to commit at some times of the day or the week rather than others? Are there correlations between commits and changes in complexity? etc etc&lt;/p&gt;

&lt;p&gt;For the SPA workshop, we wanted people to focus on visualising the data in interesting ways. There was a strong theme going through the conference of Javascript, HTML5 and other presentation technologies. We wanted to harness interest in this and have people generate interesting visuals from the repository data. We announced the challenge in the opening plenary session on Monday. Somehow people found time in between all of the rest of the conference activities to come up with some pretty impressive things. Unexpectedly, Michael Feathers dropped by the conference as he was passing through London that day and came to see what people were up to, which was a nice surprise. At the closing plenary on Wednesday, our three finalists presented their work in some lightning demos.&lt;/p&gt;

&lt;p&gt;Dear presenters, if I have described your entry wrongly below, please let me know and I will correct it!&lt;/p&gt;

&lt;p&gt;&lt;a href='http://twitter.com/stonsoftware'&gt;Stephan Eggermont&lt;/a&gt; and Diego Lont used their Smalltalk skills to create some extensions to the &lt;a href='http://www.moosetechnology.org/'&gt;Moose&lt;/a&gt; platform to allow people to dig down into individual commits and changes. The visualisation uses a grid pattern with different colours representing code complexity.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/eggrace/EggRaceStephanDiego.jpg' alt='Stephan and Diego' /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='http://twitter.com/aparker42'&gt;Andrew Parker&lt;/a&gt; produced a visualisation using animated circles to show change. The circles moved, grew and changed colour representing time and complexity, producing a moving chart in the style of Hans Rosling&amp;#8217;s well-known presentations of data. A nice feature was how the colours faded out when the file wasn&amp;#8217;t touched for a long time.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/eggrace/EggRaceAndrew.jpg' alt='Andrew' /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='http://twitter.com/lassekoskela'&gt;Lasse Koskela&lt;/a&gt; created an HTML5 visualisation based on a clock face. Time span forward through the history of the project being analysed, and as commits happened, they were displayed on the clock as the spinning hand passed them, this allowed the viewer so see which parts of the day were most common for checking in. He was also able to adjust the speed, to skip through times in the project&amp;#8217;s history where he knew there was no activity, which was a nice touch.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/eggrace/EggRaceLasse.jpg' alt='Lasse' /&gt;&lt;/p&gt;

&lt;p&gt;A quick and unscientific poll of the audience revealed that the majority of people liked Andrew&amp;#8217;s entry the best, so he was declared the winner (and is pictured below with his prize). Thanks to everyone for taking part in the challenge, I hope you enjoyed it, and got to try out something that you might not normally get to do day-to-day. Thanks again to Michael for letting us use his tools as a starting point.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/eggrace/EggRaceAndrewWinner.png' alt='Andrew Wins' /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Work Experience for Grownups</title>
   <link href="http://chatley.com/posts/06-16-2011/work-experience-for-grownups"/>
   <updated>2011-06-16T00:00:00+01:00</updated>
   <id>http://chatley.com/posts/06-16-2011/work-experience-for-grownups</id>
   <content type="html">&lt;p&gt;At some point last year, I had the idea of spending some time with a team that I don&amp;#8217;t normally work with, with the aim of gaining ideas and experience. Unfortunately I didn&amp;#8217;t get around to putting it into practice, but last week I found I had some free time, and with the help of the good people at &lt;a href='http://www.7digital.com'&gt;7Digital&lt;/a&gt; I was able to do it. I call this Work Experience for Grownups.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.7digital.com'&gt;7Digital&lt;/a&gt; is a smallish but growing company, working in the music industry, with a team of about 20 developers, plus operations, product, sales and business teams making about 50-60 staff in total. The dev team is divided into three sub-teams, focussing either on back or front-end systems, but all work mostly in .NET, and follow agile practices (although practices may vary between teams, depending on what each team feels works best for them). Strangely, 7Digital currently occupy the Shoreditch office space that I worked in about five years ago with &lt;a href='http://www.kizoom.com'&gt;Kizoom&lt;/a&gt; - so it was a little bit strange being back in the office, but with a different company.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/7digital/Office.jpg' alt='7Digital Office' /&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the picture, most of the developers work in pairs. This is a really good thing for an outsider wanting to come and join the team (either temporarily or permanently). A new person can get right into the heart of things and work on something useful, even if they aren&amp;#8217;t particularly experienced in the domain, or with the particular technology being used.&lt;/p&gt;

&lt;p&gt;It seems more common for companies to take on interns or people doing work experience placements who are relatively inexperienced. One of the differences about doing it as a more seasoned professional is that you are (hopefully) able to contribute something to the team. Although you likely wouldn&amp;#8217;t feel comfortable taking on a piece of work on your own (and if you did, then I&amp;#8217;d question how useful a learning experience you were having), you can work reasonably effectively as part of a pair, offering a fresh pair of eyes and possibly new insights on problems, as long as your pair can put up with you asking a lot of questions.&lt;/p&gt;

&lt;p&gt;I spent the week with the Services team, who work on providing APIs to other teams, and to external customers. We spent a fair bit of time working on tests and features, and also trying to debug various problems with bits of infrastructure. From a technical point of view, this was an immersive approach to learning, and so I didn&amp;#8217;t get a full understanding of all, if any, of the individual pieces, but got an idea of how things fit together. Coming out of it, I didn&amp;#8217;t feel I&amp;#8217;d be confident in starting a new .NET project from the ground up, but coming in to the middle of an existing one, I would at least have an appreciation of the lie of the land.&lt;/p&gt;

&lt;p&gt;From a process point of view, I was on firmer ground, and after observing the way the team worked for a few days, felt able to offer a few suggestions, or at least highlight a few things that I&amp;#8217;d noticed. Each of the delivery teams uses some form of Kanban board (although each team has designed their board with different columns etc). We talked quite a lot during the week about the flow of features across the board, release processes, what was holding up things from being released. They release approximately once a week, but there isn&amp;#8217;t any strict iteration cycle (they had tried that before and decided to abandon it). They are trying to get to a state of continuous flow, releasing every feature when it is finished, perhaps releasing daily or even many times per day, but at the moment they seem quite far from that. We spent some time discussing where they want to be, the challenges, and how they might be able to change their process to get there. One thing that seemed very positive was that everyone seemed to be thinking about ways to evolve the way that the team works, and to improve. One comment that I made in a retrospective, about concentrating on pulling features across the board from the right (into production), rather than pushing them from the backlog on the left to fill up empty slots where the WIP limit had not been reached, was immortalised in a poster by &lt;a href='http://twitter.com/ChrisAnnODell'&gt;Chris&lt;/a&gt; and stuck on the wall. That&amp;#8217;ll teach me to be careful what I say&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/7digital/PullFromTheRight.jpg' alt='Pull from the right' /&gt;&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href='http://twitter.com/robbowley'&gt;Rob&lt;/a&gt;, &lt;a href='http://twitter.com/hibri'&gt;Hibri&lt;/a&gt;, &lt;a href='http://twitter.com/bendrury'&gt;Ben&lt;/a&gt; and the team for letting me spend the week with them. It was certainly useful for me, and I hope that it was of some use to them too. Having done this once, it&amp;#8217;s something that I&amp;#8217;d like to do again, perhaps a couple of times per year, as an ongoing way of learning new things by seeing tools and practices in use at the coal face - quite a different experience from reading about them, or trying them out on small personal projects. I also think that doing your first week with a team, on a project, or in a company, is a skill that we can practise and get better at. Learning how to get up to speed more quickly, or what things a new person most needs to know to start being useful on your team, can only be a good thing. I wasn&amp;#8217;t paid for the time I spent with 7Digital, but looked at the week as a pretty cheap form of training. I&amp;#8217;d encourage people to try it, and for more teams and companies to think about welcoming people in. Please let me know if you have ideas about this.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/7digital/RobPairing.png' alt='Rob pairing' /&gt; &lt;img src='/images/7digital/Radiator.png' alt='Information Radiator' /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Extreme Startup</title>
   <link href="http://chatley.com/posts/05-27-2011/extreme-startup"/>
   <updated>2011-05-27T00:00:00+01:00</updated>
   <id>http://chatley.com/posts/05-27-2011/extreme-startup</id>
   <content type="html">&lt;p&gt;At &lt;a href='http://xp2011.org/'&gt;XP2011&lt;/a&gt; in Madrid, &lt;a href='http://mattwynne.net/'&gt;Matt Wynne&lt;/a&gt; and I ran a workshop called Extreme Startup. This is a workshop that we devised to simulate the environment of a startup, where there is high uncertainty as to what the market wants, and teams must iterate rapidly to develop a product. The accepted agile engineering practices are supposed to support working in an iterative fashion, with changes of direction and strategy, without compromising quality. We wanted to see what happened when we increased the frequency of iteration, under the pressure of competition. Would the practices help? Or would some (or all) of them fall by the wayside?&lt;/p&gt;

&lt;p&gt;We asked the participants to form teams, to compete against each other. Most formed pairs. The task we set them was to build a small webserver that could respond to requests that we would send them. We didn&amp;#8217;t tell them in advance what the requests would be, the only way for them to discover this was to build something, launch it into the marketplace, and see what they received. For each request, the response was scored, and running totals kept for each teams score. We displayed a leaderboard on screen throughout the session.&lt;/p&gt;

&lt;p&gt;We played the main part of the game for about an hour, and the atmosphere was tense. Pairs huddled over laptops, tailing logs, programming solutions, checking their scores. The competition was tight, and the top of the leaderboard changed often throughout the session. We spent some time peering over their shoulders to try and determine their various strategies.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/extremestartup/Teams.jpg' alt='Team Playing' /&gt;&lt;/p&gt;

&lt;p&gt;After an hour or so, we called the end of the competition. As a group, we reflected on the exercise, and the decisions that people had made. There were varying strategies, but a common thread was that under the pressure of the competition and varying requests, people had coded quickly, and perhaps messily, and had not written many tests. They weren&amp;#8217;t particularly proud of what they had written, but it had worked. Presumably it was &amp;#8220;good enough&amp;#8221; for the task in hand.&lt;/p&gt;

&lt;p&gt;We want to run this session again, and we want to take more notice of how the scores vary throughout the session. Perhaps we can plot a graph and maybe tie specific events or phases back to particular aspects of the graph. We also wonder what would happen if we ran the exercise over a longer timescale, perhaps a whole day. It wouldn&amp;#8217;t be possible for people to maintain the same intensity and concentration over a whole day, so we wonder how their strategy would change. I also wonder what would happen if the teams were larger.&lt;/p&gt;

&lt;p&gt;This is definitely a fun exercise. We hope to run it again in future, and some of the particpants from XP2011 have gone on to run the session with their own user groups.&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/extremestartup/J+J.jpg' alt='Pair Concentrating' /&gt;&lt;/p&gt;</content>
 </entry>
 
 
</feed>

