Beginning Emacs Lisp

The Problem

A while back I converted an archive of non-code-related files to org-mode. The files had citations in a markdown-like format, so:

> ADA  <br/>
COUNTESS OF LOVELACE  <br/>
1815-1852  <br/>
Pioneer of Computing  <br/>
lived here

which, processed through Calibre, produced a nice readable pdf with blockquotes and linebreaks.

For a while after that, I wrote in org-mode and viewed the files within emacs, so I just indented quotations, like so:

.
    Quandunque i colli fanno più nera ombra,
    Sotto il bel verde la giovane donna
    Gli fa sparir, come pietra sott’ erba.

and then one day I used org-mode’s export-to-html functionality (C-c C-e h o) and I lost all the blockquoting and line-breaks. org-mode needs prose citations surrounded by

#+begin_quote
#+end_quote

to be rendered with <blockquotes> in export-to-html, and if you want it to respect line breaks as well, you need to use

#+begin_verse
#+end_verse

So. Going forward I needed to insert begin/end blocks for new citations, and I had a bunch of older citations I would need to reformat. Here’s what I build with emacs lisp to solve the problem.

The Solution

The Simplest Case

In a new file, about to add a quotation, I want a shortcut to add either #+begin_quote / #+end_quote or #+begin_verse / #+end_verse and put the cursor on the empty line between. This sounds like what yasnippets is designed for, but I wasn’t sure how that would work when I got to converting existing quotations, so I broke out my ~/.emacs.d/mods-org.el file and added two new shortcuts:

(global-set-key (kbd "M-s M-q")
(lambda()
(interactive)
(insert "#+begin_quote")
(newline)
(newline)
(insert "#+end_quote")
(newline)
(previous-line)
(previous-line)))

(global-set-key (kbd "M-s M-v")
(lambda()
(interactive)
(insert "#+begin_verse")
(newline)
(newline)
(insert "#+end_verse")
(newline)
(previous-line)
(previous-line)))

This meets my simplest case requirement and is fairly self-explanatory. Going forward, I can type

M-s M-q ;; q for quote

to get

#+begin_quote
_
#+end_quote

and

M-s M-v ;; v for verse

to get

#+begin_verse
_
#+end_verse

commit

Narrowing the Scope

The fact that I put them in ~/.emacs.d/mods-org.el instead of ~/.emacs.d/key-bindings.el foreshadows the next step: they aren’t global key bindings, I’m only going to use them in org-mode, and in a ruby class they’d just be noise. So, since I’ve already got a hook for entering text-mode (which I’m also using for org-mode), let’s change them from global key bindings to key bindings which are added to org-mode specifically.

I’ve got an ~/.emacs.d/mode-hooks.el file which already has a custom text-mode-hook, so I can add two lines to that:

(defun my-text-mode-hook ()

(define-key org-mode-map (kbd "M-s M-q") ‘begin-end-quote)
(define-key org-mode-map (kbd "M-s M-v") ‘begin-end-verse)
)

(add-hook ‘text-mode-hook ‘my-text-mode-hook)

And change the functions, in the ~/.emacs.d/mods-org.el file, from anonymous functions in the global-set-key blocks to the named functions we have just referenced:

(defun begin-end-quote ()
(interactive)
(insert "#+begin_quote")
(newline)
(newline)
(insert "#+end_quote")
(newline)
(previous-line)
(previous-line))

(defun begin-end-verse ()
(interactive)
(insert "#+begin_verse")
(newline)
(newline)
(insert "#+end_verse")
(newline)
(previous-line)
(previous-line))

Now if we’re in org-mode, the key-bindings do what we expect, but if we’re in ruby-mode and type them, or type (C-h k) to get the definition of a key binding and then type (M-s M-v), we get

M-s M-v is undefined

commit

Reformat Existing

That handles the going forward case, but doesn’t handle the case where I’m in an older file and want to reformat an existing quotation. To handle both, I’d like to check when I use the shortcut to see if I’ve got a selected a region or not. If I haven’t, it’s the going forward case, and I should do what I was doing before, but if I have, then presumably I want to put the #+begin and #+end blocks around the selected region.

We can tell this because emacs lisp gives us a function use-region-p which returns true if there is a region selected. The most basic if block in emacs lisp looks like this:

(if (condition)
(do-true-thing)
(do-false-thing))

so in our case we have:

(if (use-region-p)
(begin-end-quote-for-region)
(begin-end-quote-for-new))

and begin-end-quote-for-new is the old begin-end-quote method, and begin-end-quote-for-region looks like this:

(defun begin-end-quote-for-region ()
(interactive)
(insert "#+end_quote")
(newline)
(goto-char (region-beginning))
(insert "#+begin_quote")
(newline))

An extra bit of inwardness here is that the cursor starts at the end of the selected region, so we can just insert “#+end_quote” and it will show up after the end, and (region-beginning) and (region-end) hold the beginning and end of the selected region, so (goto-char (region-beginning)) gets us back to the beginning so we can insert “#+begin_quote” before it.

commit

This gets us to the point where if we’d selected the first quotation and hit M-s M-v, we’d end up with

#+begin_verse
> ADA  <br/>
COUNTESS OF LOVELACE  <br/>
1815-1852  <br/>
Pioneer of Computing  <br/>
lived here
#+end_verse

which is a definite improvement, but it still has the old formatting codes. Can we get rid of those?

Remove Old Formatting

First off, we only want to do this in the reformat existing case. That’s fine, those two methods (begin-end-quote-for-region and begin-end-verse-for-region) are already separate, so in each of those methods include a (remove-old-formatting) method.

What we want to do in pseudo-code is take the selected region and apply

s/^> //
s/  <br/>$//

to it. (We only need the second transformation for verse, not quotes, and if these got any more complicated we might want two separate methods, but we can leave them in one for now.)

setq defines a variable.

filter-buffer-substring grabs the text from arg1 to arg2 (and we’re using (region-beginning) and (region-end) which return the start and end of the selected region), and with the optional third argument of t deletes the text after copying it.

After that, we’ve got the contents of the selected region in a variable, “in”, and we can run replace-regexp-in-string on it, taking as arguments search-value, replace-value, and string-to-search in, and using setq to define to variable we’re storing the result in.

Once we’ve made all the changes we need, we use insert the finally modified string back into the buffer.

(defun remove-old-formatting ()
(setq in (filter-buffer-substring (region-beginning) (region-end) t))
(setq out (replace-regexp-in-string "^> " "" in))
(setq out2 (replace-regexp-in-string " <br/>$" "" out))
(insert out2)
)

commit

And at the end of that, we get:

#+begin_verse
ADA
COUNTESS OF LOVELACE
1815-1852
Pioneer of Computing
lived here
#+end_verse

Which is very nearly there, but not indented. How about as a last step we indent it, so if we’re viewing it in org-mode it still looks like a blockquote?

Indenting

Let’s put this in our remove-old-formatting method, because again it’s something that we’ll only want in the reformat existing case. Given that it’s no longer just removing old formatting, let’s change the method name to fix-old-formatting, and to keep things at the same level of abstraction, let’s put the old remove-old-formatting lines in a new method called remove-old–formatting-code and add a method indent-if-not-indented. So we have:

(defun fix-old-formatting ()
(remove-old-formatting-code)
(indent-if-not-indented)
)

(defun remove-old-formatting-code ()
(setq in (filter-buffer-substring (region-beginning) (region-end) t))
(setq out (replace-regexp-in-string "^> " "" in))
(setq out2 (replace-regexp-in-string " <br/>$" "" out))
(insert out2)
)

Remember that we have some existing citations in the form

> ADA  <br/>

and some already indented as

.
    Quandunque i colli fanno più nera ombra,

Further, some of the already indented ones have multiple layers of indentation, and setting a single indentation would break that. So while indent-region itself is simple enough, once again using (region-beginning) and (region-end) to give us the selected region, and the third argument for the number of columns to indent:

(indent-region (region-beginning) (region-end) 4)

we need to make it conditional on it not already being indented, so we end up with:

(defun indent-if-not-indented ()
(setq firstFour (filter-buffer-substring (region-beginning) (+ (region-beginning) 4)))
(if (not (string= firstFour " "))
(indent-region (region-beginning) (region-end) 4)
)
)

using filter-buffer-substring again to grab the first four characters of the region (without the optional third argument so we don’t delete it), and if they aren’t spaces, do the indent. If they are, it’s one of the newer existing quotations and we should leave it as it is, as one of them for instance was pseudo-code

.
    count = 500 
    day.each do
      wrote_words?(count) ? 
        count += 100 : 
        count -= 100
      count = 100 if count < 100
      count = 1500 if count > 1500
    end

and not doing that check would have clobbered all the internal indenting.

commit

With that, we finally get the desired end result for the older existing quotations:

#+begin_verse
    ADA
    COUNTESS OF LOVELACE
    1815-1852
    Pioneer of Computing
    lived here
#+end_verse

without clobbering existing indentation for the more recent existing quotations:

#+begin_verse
    count = 500
    day.each do
      wrote_words?(count) ?
        count += 100 :
        count -= 100
      count = 100 if count < 100
      count = 1500 if count > 1500
    end
#+end_verse

End and Afterthoughts

The current state of my ~/.emacs.d/ is here. It is very much a work in progress. Also, having just looked at Sacha Chua’s more literate emacs config using org-babel, I’m quite tempted to try that out, instead of composing the two or three additional explanatory/introductory blog posts that occurred to me would be helpful as I was writing this up.

Notes and Quotes from Conference Talks

What did we do before Confreaks let us catch up on all the conference talks? Here are notes on some that resonated with me recently.


TDD for Your Soul: Virtue and Web Development with Abraham Sangha at Madison+ Ruby

… more philosophy than tech, but thought-provoking.

citing Alasdair McIntyre, “After Virtue”:

“Who am I?

Who ought I to become?

How ought I to get there?”

citing Ralph Ellison:

“The blues is an impulse to keep the painful details and episodes of a brutal experience alive in one’s aching consciousness, to finger its jagged grain, and to transcend it, not by the consolation of philosophy but by squeezing from it a near-tragic, near-comic lyricism.”

Abraham Sangha:

“We’re inviting criticism of ourselves, we’re inviting evaluation of our weaknesses, by TDDing our soul, by writing these tests, seeing where we fail, and trying to implement habits to address these failures: that can be a shameful process. … If you don’t believe you’re good enough, you’re stuck, then why would you invite more pain into your life through this process, so why not just skip it. … But there’s a possibility that pursuing this will actually give us a sense of buoyancy.”


Alchemy and the Art of Software Development with Coraline Ada Ehmke at Madison+ Ruby

Going back in pattern languages before Christopher Alexander to Gottfried Wilhelm von Leibniz (1646-1716): “every complex idea is composed of sets of simpler ideas.”

“alchemy is about transforming base matter, like the stuff that we’re made of, into something more closely approaching divine perfection. That ‘lead into gold’ nonsense was actually part of the pitch that alchemists made to the VCs of their era. They called them royalty, I’m not quite sure why. And this idea that ‘I can take base metal and transmute it into gold? Here: I’ll give you all this money for your metaphysical experiments. I don’t care.’ So they were pretty smart.”

“The Divine Pymander, ascribed to Hermes Mercurius Trismegistus. … It contains seventeen tracts, which talk about things like divinity, humanity, idealism, even monads.”

“we impose our will on the universe, we create a structure that we want to impose on chaos, and the manifestation of that begins in harmony, but slides towards disharmony, because every object in every system is corruptible. … the code is corruptible.”

“all that is apparent, is what was generated or made. … the system does not contain information about the ideals that led to its creation. Unless we are very deliberate about recording our intention and our design, that information is lost, and all we are left with is a system that we don’t understand any more.”

“Christopher Alexander the architect said that a builder should start with the roughest sketch of a building, and by processes that are known to the brain through the pattern language, execute the construction of the building. All things that are are but imitations of truth. The systems we build are reflections of the world. Software system is not and cannot be a single source of truth.”

“Really, alchemy and software development are about identifying ideals, identifying particulars, creating taxonomies, studying them, creating a system for classifying every single thing in a limited or expansive universe.”

“The Divine Pymander ends with this: ‘The Image shall become thy Guide, because Sight hath this peculiar charm, it holdeth fast and draweth unto it those who succeed in opening their eyes.’ I would translate this as ‘The metaphors guide us. Information is there, and ideas want to be recognized.’ I think that the metaphor of alchemy holds true with what we do. Just like alchemy, software development is an inquiry into the essential nature of reality. We break it down, we salve it coagula, we break down complex things into simpler things, we recombine them in novel ways, and we produce an effect on the world, on ourselves.”

“Let’s … dive into disciplines that we have no idea what they even mean, explore them, mine them, find tenets and metaphors, tools that we can use in problem solving, that we can apply to enrich our art, our science, our own magnum opus. Maybe when we do that, we can find that the raw stuff of digital creation can be transmuted into something that more closely approaches perfection.”


Aesthetics and the Evolution of Code: Coraline Ada Ehmke, Nickle City Ruby 2014

Aesthetics of code: correctness, performance, conciseness, readability.

So how do we measure elegance? How about a graph with four lines/axes spreading from the origin, correctness “north”, performance “south”, conciseness “west”, readability “east”. If you can measure and grade those four aesthetics on a numeric scale, then the most elegant code will cover the largest space on the graph

Why does it matter? Einstein said:

“After a certain level of technological skill is achieved, science and art tend to coalesce in aesthetic plasticity and form. There greater scientists are artists as well.”


Eric Stiens’s Nickel City Ruby Conference 2014 talk “How to be an Awesome Junior Developer (and why to hire them)”

On Mentoring:

Don’t hire a junior developer you can’t mentor. It’s not fair to them. It’s not fair to your team. Everybody loses.


Sarah Mei’s Nickel City Ruby Conference 2014 talk “Keynote: Multitudes”

Should you always use attr_reader to access an instance variable rather than accessing it directly, as a good object-oriented principle, because by only accessing it by sending a message you have created a seam which makes it easier to change anything about the implementation later? A good application developer (e.g. Sandi Metz) would very likely say yes. A good library developer (e.g. Jim Weirich) might say no, because adding attr_reader to a class makes data manipulation public, and once it’s public it has to be supported for ever, because people will use it. (And if you do change it, and you’re using semantic versioning, you have to change the major version.)

“So people who write gems have developed a system where they have a very minimal interface, with a very rich set of internal abstractions, which they can use while providing this very minimal external interface.

“So these are just two different approaches to programming [application style at one end, gem/library style at the other], and what we’re starting to see here is there is a spectrum of rubyists, and there is a spectrum of projects: people will write different code at different points of the spectrum at different times, and what the spectrum is measuring is the surface area of our interface. And it seems like a fairly simple distinction but it does produce a huge difference in code structure. And what it means is that sometimes someone who is good at one side of this spectrum will not automatically be good at the other side, right away. … Why does this matter? … Having these endpoints helps us define what else there is. For example, there’s a middle here, and that middle is suddenly quite obvious, actually, and that’s external APIs on Rails apps. Many Rails apps now need some kind of programmatic interface that is versioned, and minimal, because once it’s out there, and it’s got users, you’re stuck supporting it, forever. … And the reason people struggle with external APIs for Rails apps is that it is partially application development and it is partially gem-style development, and there aren’t very many people that are good at both.”

Exciting that Sarah Mei and Sandi Metz are writing a book: Practical Rails Programming.

“… So We Built One” Redivivus

The earlier entries here are the still-relevant ones from my old tech blog “… So we built one”, leaving out specific points and fixes around (say) rails 2.1 and rspec 1.1.4.

Some of my RubyFringe notes seem quaintly remote (we got a preview of the upcoming git feature of creating gists), but much of it is about underlying ways of thinking and still worth pondering. Luke Francl’s remarks on testing being over-rated (not in any way bad, but the most complete set of tests imaginable doesn’t prove that your app doesn’t suck in the way that sitting and watching a user interacting with it might) remain topical and contested to this day.

There will be new content going forward.

John Steel, “Perfect Pitch”

I’m reading Jon Steel’s Perfect Pitch: The Art of Selling Ideas and Winning New Business, and, like Nick Sieger’s remarks about jazz, some of it seems uncannily relevant to programmers. There’s even a reference to “pair advertising”:

There’s a reason why copywriters and art directors work in pairs, and it’s not because writers can’t draw and art directors are illiterate. Ideas get uncovered more quickly when people dig together. And the ideas get better much more quickly when they are shared and debated by a small group of people who like and respect each other.

Words for every shop to live by. Steel also resounds Obie Fernandez’s remarks about the importance of being willing to say “no” to a contract if you aren’t going to be able to do your best work or be proud to put the project in your portfolio, and devotes a whole chapter to Tom Preston-Werner’s conceptual algorithm of setting aside dedicated thinking time.

For anyone else suffering withdrawal symptoms from the stimulating and wide-ranging discussions at RubyFringe, this could be just the book.

RubyFringe, Day Two

Geoffrey Grosenbach spoke from his university background in philosophy and interest in music, and wondered interestingly if developers are less aware that modern methodologies derive from the scientific method because they’re stuck in the implementation phase, without necessarily being involved in coming up with the original ideas or validating the experiments. The link from Spinoza to cloud computing was a long but entertaining stretch. Invoking the Sapir-Whorf hypothesis as a good reason to do a desktop app instead of a web app every so often (or vice versa), for the wider perspective, struck home.

John Lam spoke of how you gravitate to the same problems over and over, drawing lines from IronRuby to his early days metaprogramming in assembler on a Commodore 64 and building bridges between components, and of how you can change your mind, remembering his early paper on how dynamic languages suck. He explained his move to Microsoft on the grounds that he really wanted to build stuff that people would use: you can build stuff in open source, but brilliance alone won’t guarantee that people use it.

Hampton Catlin spoke about Jabl, which he cheerfully billed “the language you will hate”, his attempt to fix javascript (which he sees as a good if verbose general-purpose language but a terrible browser language that needs frameworks to fix it). Jabl will compile into javascript, is backed by JQuery and provides a compact DSL for client-side DOM manipulation. It look neat and quite compact (a good deal more compact than the equivalent JQuery, and a great deal more compact than the equivalent raw javascript), and as soon as there’s a compiler it will be well worth checking out.

Giles Bowkett (note from 2014: if you haven’t already seen it, go watch the video, which is amazing) gave a high-energy performance, demonstrating his Archaeopteryx MIDI software and making an impassioned plea to do what you love and build what you want. Make profit by providing a superior service at the same price point as the competitors: we’re still banging the drum of making your offering less painful than the competition. Also, Leonardo da Vinci was an artist who didn’t ship and so, by “release early, release often” standards, a failure, there were several images of Cthulhu, references to using a lambda to determine which lambda to use (a meta-strategy pattern), and Bowkett’s thought that it was irresponsible in Ruby not to use the power the language gives you. He added that Archaeopteryx may be insane but it’s also great, and “insanely great” he can live with, and that while he may not be able to say (as Jay Phillips used to of Adhearsion) “my career is Archaeopteryx”, being able to say “my career includes Archaeopteryx” is still very good.

Damien Katz spoke about the long and hard road that led to him being the guy building the cool stuff, in his case CouchDB. It felt in part like a counterpoint to Bowkett’s story: took longer to pay off, but he did what he really wanted to do on the chance that someone might recognize it, and pay off it finally did. Katz also noted that while it was easier to get something working in Java than in Erlang, it was easier to get it working reliably in Erlang than in Java.

Reginald Braithwaite spoke about rewrite, which enables rewriting Ruby code without opening and modifying core classes. This makes it easier to scope changes to specific parts of your code. Reg likes the power of opening classes, but doesn’t think it sustainable. If you open a class in a gem, all the downstream users will be affected, whether they want the change or not. Reg also mused on adverbs, like .andand. or .not., modifiers that affect the verbs, the methods, instead of the more usual noun/object orientation. (Reg has since blogged a riff between his talk and Giles’s.)

Tom Preston-Werner spoke about conceptual algorithms, not applied to coding patterns but to higher-level thinking patterns. He gave an extended example of the full circle of the scientific method and its effectiveness in debugging, noting the usefulness of Evan Weaver’s bleak_house plugin in tracing memory leaks. He previewed the upcoming git feature gist, basically pasties backed by github. He discussed some other algorithms more briefly. Memory Initialization starts with disregarding everything you think you know about a problem and working from first principles (it worked for George Dantzig). Iteration is exemplified by the James Dyson new vacuum cleaner design, which after 5126 failures became a resounding succes. Dyson remarked, taking us right back to Nick Sieger’s jazzers, “Making mistakes is the most important thing you can do”. Breadth-First Search relies on the fact that there are over 2500 computer languages, and learning some others just for the different perspective is useful. (He shared a tip from his time learning Erlang and being weirded out by the syntax: just say to yourself, over and over in an affirming manner, “the syntax is OK”. And that helps you get past it and get on to the good stuff.) Imagining the Ideal Solution feels like a cousin of TDD: if you’re not sure how to implement the solution, write out your best case of what the god config file (say) or the Jabl syntax (say) would be, and then proceed to implement that. And Dedicated Thinking Time was an unexpected reflection of a point I first came across in Robertson Davies: it’s important to set aside time for just thinking about things. Sure it’s simple, but it’s sometimes ridiculously hard to implement.

Blake Mizerany spoke about Sinatra, one of the Ruby web app microframeworks, built (in line with Jeremy McAnally’s thoughts yesterday) because Rails was too slow for his needs. He noted some apps in Sinatra: git-wiki (a wiki served by Sinatra and backed by git), down4.net, and the admin interfaces of heroku. He also suggested that for RESTful resources, rest-client (which he called “the reverse Sinatra”) and Sinatra was all you needed, making ActiveResource look like overkill and curl look cumbersome. To complaints that Sinatra wasn’t MVC, he noted that he thought it was, actually, but in any case, insisting on a web framework being MVC felt like over-eager application of patterns instead of starting with the problem. Asked what Sinatra was tailored for, he said back end services or other small bits of functionality. If you’ve got more than a few screens of Sinatra code, it’s probably time to move to another framework.

Leila Boujnane spoke about the importance of being good, and being useful, and making the world a better place by making something that people want. Don’t start with a business model: start by building something useful, and build it well, because a crappy product upsets both the customers and the people working on it. Making the customers feel good about the product is not only good in itself, it’s the least limiting approach, because if your product doesn’t do that on its own you need to cheat or fool people into thinking it’s terrific. In a way, we’re back where the conference started: find a pain point and build something useful to fix it, to everyone’s benefit.

Oh, and the Toronto Erlang group was founded over lunch.

High praise to the folks at Unspace for making the conference happen. It was thought-provoking and loads of fun.

Joey deVilla’s more expansive account: one, two, three.

RubyFringe, Day One

Jay Phillips talked about Adhearsion, his framework for integration VoIP building on top of and simplifying the use of Asterisk. He noted that it can be surprisingly profitable to find a pain point a bit off the beaten track and fix it. This chimed well with Zed Shaw’s remark from QCon London 2007 that if you want to succeed beyond your wildest dreams, you should find a problem and solve it in a way which is less painful than any of the competing alternatives.

Dan Grigsby noted that entrepreneurship was easier for a developer than perhaps it had ever been, because the sweet spot for team size was about 3. If you’re a really good programmer, all you need on the code side is one or two other really good programmers. This matches Pete McBreen’s point in Software Craftsmanship, that a smaller team of really good people will probably be better and more productive than a larger team. The trick that corporations don’t seem to have solved yet is finding that small great team in the first place.

Grigsby added that a more pragmatic test-driven approach to the developer’s dilemma of picking the winners among all the possible project ideas is to build a whole bunch of narrowly-focussed projects, send them out, measure them to within an inch of their lives, and quickly kill off the failing ones. For a similar amount of effort as honing one or two projects for a much longer period before sending them out, you’re left with a couple of projects that are less well developed but you already know they are successful.

Grigsby’s engaging talk continued into more explicitly market-focused directions, discussing finding hacks in the market for the disproportionate reward, suggesting that there are marketing techniques that match Ruby’s better-known programming claim to 10x better productivity, and that exploiting non-obvious relationships was among them.

Tobias Lütke spoke about memcached.

Yehuda Katz spoke about several neat projects, from Merb and DataMapper (coming to 1.0 this summer so almost no longer Edge-y) to sake (for system-wide rather than project-specific rake tasks), thor (scripting in Ruby), YARD (a neat-looking better Ruby documentation tool), and johnson (a ruby-javascript bridge).

Luke Francl spoke on testing being over-rated. He made clear that testing is great, it’s just that there are a lot of other things we need to do (code inspection, usability testing, manual testing), some of which will find different bugs and none of which will find all the bugs. As he pointed out, you can have the most complete set of unit tests imaginable, and it won’t tell you if your app sucks. Sitting and watching a user interacting with the app may be the only way of being sure of that. Francl also pointed out that in addition to writing code and writing tests, developers are good at criticizing the code of others, and the best measure of code quality may be not rcov stats but the number of WTFs per minute in a code review. And, as a side benefit, knowing that your code will be subject to a code review will probably make you tighten up your code in anticipation. (Francl’s paper was also notable for following the Presentation Zen advice of having clear uncluttered slides and a handout that was an efficient text summary of the presentation that bore no relation to the slides at all.)

ETA from RubyConf 2014: see also Paul Gross’s Testing Isn’t Enough: Fighting Bugs with Hacks.

Nick Sieger spoke about Jazzers and Programmers. Go read his summary and savour the quotations (from a different field but still deeply appropriate) from great jazz musicians. “Learn the changes, then forget them” (Charlie Parker). Or the idea of The Real Book (the body of tunes that all jazz musicians learned and created a shared vocabulary that allowed musicians to play together on their first meeting) as the GoF for jazzers in the 70s.

Obie Fernandez spoke about marketing and practical details of contracts. Not only about accepting contracts but about rejecting them, noting that a key acceptance criterion should be if you’re going to want to show off the project when it’s done and keep it in your portfolio. Following on from patterns and The Real Book, he noted the importance when setting up a consultancy of defining projects and of having names for them, and of writing down your client criteria and acceptance criteria and keeping them constant. Noted Secrets of Power Negotiating, Predictably Irrational, and Seth Godin’s Purple Cow as books to check out.

Matt Todd spoke about the importance of just going ahead and making mistakes and learning from them. (Going back to one of Sieger’s quotations, as Ornette Coleman put it, “It was when I found out I could make mistakes I knew I was on to something.”)

Jeremy McAnally spoke of how we should resist the urge to make Rails do everything, even outside its comfort zone where it would be a lot simpler and more maintainable to, say, just write some Ruby code and hook it up to with Rack. How Rails is designed for database-backed web apps, and taking it outside of its 80% comfort zone, while perfectly possible, may not be the best solution, and if you find yourself in a place where the joy:pain ratio has flipped or where you find you’re writing more spaghetti code to fit the solution into Rails than you would be to write the solution on its own, it’s probably time to switch.

Zed Shaw briefly presented some dangerous ideas and then went on to an impromptu music-making session. He left us with the thought that while he was done with Ruby, he was never going to stop coding, because code was the only artform that you could create that other people could then play with.

Joey deVilla’s more expansive account: one, two.

Christopher Alexander Talks Back

Ever wonder how Christopher Alexander felt about being the poster child for software design patterns? In his foreword to Richard Gabriel’s book he answers the question, and poses another. Are our designs as good as Chartres? If not, why not?

In fact, this is so interesting and challenging that I’d like to make a fuller extract, which I hope will be within fair use rules:

In my life as an architect, I find that the single thing which inhibits young professionals, new students most severely, is their acceptance of standards that are too low. If I ask a student whether her design is as good as Chartres, she often smiles tolerantly at me as if to say, “Of course not, that isn’t what I am trying to do. … I could never do that.”

Then I express my disagreement, and tell her: “That standard must be our standard. If you are going to be a builder, no other standard is worthwhile. That is what I expect of myself in my own buildings, and it is what I expect of my students.” Gradually, I show the students that they have a right to ask this of themselves, and must ask this of themselves. Once that level of standard is in their minds, they will be able to figure out, for themselves, how to do better, how to make something that is as profound as that.

Two things emanate from this changed standard. First, the work becomes more fun. It is deeper, it never gets tiresome or boring, because one can never really attain this standard. One’s work becomes a lifelong work, and one keeps trying and trying. So it becomes very fulfilling, to live in the light of a goal like this.

But secondly, it does change what people are trying to do. It takes away from them the everyday, lower-level aspiration that is purely technical in nature, (and which we have come to accept) and replaces it with something deep, which will make a real difference to all of us that inhabit the earth.

I would like, in the spirit of Richard Gabriel’s searching questions, to ask the same of the software people who read this book. But at once I run into a problem. For a programmer, what is a comparable goal? What is the Chartres of programming? What task is at a high enough level to inspire people writing programs to reach for the stars? Can you write a computer program on the same level as Fermat’s last theorem? Can you write a program which has the enabling power of Dr. Johnson’s dictionary? Can you write a program which has the productive power of Watt’s steam engine? Can you write a program which overcomes the gulf between the technical culture of our civilization, and which inserts itself into our human life as deeply as Eliot’s poems of the wasteland or Virginia Woolf’s The Waves?

There’s no question that progress towards finishing a project in a week is more easily and more objectively measurable, and more obviously attractive to the business side. But for the longer-term but still important purpose of getting and keeping the best developers, I think we can’t afford to lose sight of this other axis either.

I Never Heard So Musical a Discord, Such Sweet Thunder

… but, when it isn’t a question of a pack of Spartan hounds tearing a bear to shreds (1), poor listening skills are more a problem than a theatrical entertainment.

I found this post that chronicles eight common barriers to good listening and suggestions to get past them quite interesting. I will not, like Dante in the Purgatorio, go through them all and explain which ones I am particularly prey to, but I know all too well that I’m not in cleared-to-throw-stones territory.

Waterfall as smokescreen and the surprisingly long history of XP

I was reading the ThoughtWorks blogs and found a neat reference to Craig Larman’s keynote speech at Agile India 2006. Larman discussed the oft-repeated statement that agile is not suited to large defence projects, but countered from Sapolsky’s 1972 book on the history of the Polaris system, that “critical path analysis and PERT charts were used as a smokescreen to placate senior management while engineers got on with their iterative development process”. (Quoting the blog entry, not the original book.)

Here’s a further link to a paper he co-wrote in 2003 which chronicles iterative development going back into the 1930s and something very like XP popping up in 1957.