Sunday, June 24, 2007

Common Music pre-Opus 1, part 1

Here's my first attempt at some practical Lisp:
(in-package :cm)

(defvar *major-scale-intervals* '(0 2 4 5 7 9 11 12))
(defvar *minor-scale-intervals* '(0 2 3 5 7 8 11 12))
(defvar *major-scale-steps* '(0 4 2 5 4 7 5 9 7 11 9 12))

(defun scales
(&key (start-root 48)
(end-root 72)
(duration 0.2)
(intervals *major-scale-intervals*))
(let ((collection ())
(scale-length 0)
(scale-notes ()))
(do ((root start-root (1+ root))
(start-time 0 (+ start-time (* scale-length duration))))
((> root end-root) (reverse collection))
(setf scale-notes (scale
:root root
:intervals intervals
:duration duration
:start-time start-time))
(setf scale-length (length scale-notes))
(setf collection (append collection scale-notes)))))

(defun scale (&key (root 60)
(amplitude 1.0)
(duration 0.2)
(start-time 0)
(intervals *major-scale-intervals*))
(apply-notes-to-midi-objects (create-scale-list
:root root
:intervals intervals)
:start-time start-time
:amplitude amplitude
:duration duration))

(defun apply-notes-to-midi-objects
(notes &key
(amplitude 1.0)
(duration 0.2)
(start-time 0))
(let ((collection ()))
(do ((current-note (car notes) (car rest-of-notes))
(rest-of-notes (cdr notes) (cdr rest-of-notes))
(time start-time (+ time duration)))
((null current-note) (reverse collection))
(setf collection (cons (new midi
:channel 1
:keynum current-note
:time time
:duration duration
:amplitude amplitude) collection)))))

(defun create-scale-list (&key (root 60) (intervals *major-scale-intervals*))
(let ((notes (mapcar #'(lambda (x) (+ root x)) intervals)))
(append notes (cdr (reverse notes)))))

The initial aim was to just play a scale, but in the end I've ended up with a function apply-notes-to-midi-object (which is poorly named) that will take a list of keynum values and generate midi events for the given notes in sequence.

All the functions are short and do one thing. On reflecting on them, I am using let variables when I could have probably included them as part of the do loop. I'm happy with what they do, though I might want to add functionality for choosing instruments as well.

The Aftermath

I'm very impressed with the way that Lisp promotes interactive development with the REPL. I wish we had something like this for Java development. I enjoyed the ability to modify and almost instantaneously test and see the results of minor tweaks, leading to more experimental ideas and the encouragement of continual improvement. I look forward to experimenting more with a high level expressive language.

Sunday, June 17, 2007

Common Music

Within the last fortnight, I've been bitten by the music bug. More specifically the Midi bug. About 4 years ago, I started writing some Java classes for sending Midi events and started playing around with the idea of writing a sequencer. But that didn't last long and when I went searching for the old code, I came up empty handed.

Have been bitten and not finding my old source code, I started contemplating how I would go about it this time. Since I've been toying around with Lisp, I considered this from that angle. Thankfully, someone has already done all the hard work. And when I say hard work, this just installed out of the box and I was running tutorial code in minutes. Very nicely done.

Having previous installed and using SLIME, I was very happy to see that CM plays nicely with SLIME. I followed the tutorial and <bzzzt>, wrong answer. Everything had gone so smoothly and yet I was stymied. So, I dove into the world of elisp. With the help of a couple people on #emacs, I'd traced exactly where the problem was (thanks to toggle-debug-on-error and message). With this, I now had the right google search term, which produced a couple of messages that got me thinking about going back to first principles.

The long and short of it is that my .emacs file before installing CM was:

(setq inferior-lisp-program "/usr/bin/sbcl")
(add-to-list 'load-path "/usr/local/lisp/slime-latest-cvs/")
(require 'slime)
(slime-setup)

which just sets up SLIME. I took what was suggested by CM and added the bits they had to give me:

(setq inferior-lisp-program "/usr/bin/sbcl")
(add-to-list 'load-path "/usr/local/lisp/slime-latest-cvs/")
(add-to-list 'load-path "/usr/local/lisp/cm/")
(load "etc/xemacs/cm.el")
(enable-cm-commands)
(require 'slime)
(slime-setup)

This setup prevents CM from loading (I'm sure there is an obvious reason for this, but I'm way too inexperienced to see it today). The sad thing is that no one else seems to have run into this problem. I'm special because I already had SLIME installed, but CM is more for musos than people like myself, so they'd install CM first then SLIME and wouldn't have a preconceived .emacs file hanging about.

So I've fixed this by doing only what the documentation suggests:

(add-to-list 'load-path "/usr/local/lisp/slime-latest-cvs/")
(add-to-list 'load-path "/usr/local/lisp/cm/")
(load "etc/xemacs/cm.el")
(enable-cm-commands)

and now M-cm works and brings up CM in SLIME. Sadly, SLIME on its own is now undefined, but then I can just use CM for all my SLIME work...

Monday, June 04, 2007

XP Boot Camp

XP is something that takes a lot of discipline. With high levels of discipline you can achieve higher levels of quality, which I believe will return better than proportional results for the effort invested. The hard part for a lot of people can be striving for the level of discipline

This is something that I've seen lacking in the vast majority of developers (of which I'd include myself). I've also noticed that on the XP mailing list, there was a small discussion recently regarding the exchange of developers between businesses to encourage the growth of teams and developers. I really like the idea, but I can't see it flying well with most businesses.

But, I do think it would be very beneficial to the XP community and to the businesses that use XP to create an XP Boot Camp. In a nutshell, set up a non-profit group to work for a charitable cause on an open source project. Businesses that wish to improve the skills of their employees would send them to the XP Boot Camp for 4-6 weeks. During this time, they would work with experienced coaches to ensure that they get the full XP experience. Hopefully, this would allow for feedback all around both from the Boot Camp to the instructees and vice versa. And people would be encouraged to come back over the years to help keep their understanding of XP fresh and to allow them to experience new ways of apply the Extreme bits. And I'd hope that they would gain the insight into the level of discipline required and the benefits of the quality that comes from the high levels of discipline.

I believe and have seen that there can be a big difference between thinking about XP and doing XP. Worse case scenario when you want to get XP boot strapped, hire a coach who can put your team through an immersion course. It will save you months, if not years not to mention the value you'll get out of your team sooner.

Quality to go faster

Over the weekend, I was watching a report on the Renault Formula One racing factory and something really struck me. From all of the images and video I've seen of Formula One factories and of the garages at races, they are all very clean and very organized. In addition, these people are trying to out perform one another in terms of innovations and technology. Lots of money is at stake. Quality is very important from a competitive point of view and from a safety point of view. With all of the pressure on them to be fast and accurate, they manage to keep their workplace nice and tidy. What struck was the level of quality that was required to allow these teams to develop high quality work in an extremely competitive environment.

I believe that the more quality that is achieved with a codebase, the more quickly the needs of the business can be achieved with that codebase. I'm not talking about the exterior quality that the users see in the product/service and I'm not saying that the external quality isn't something that is important. I'm talking about the internal quality, the quality of how the code is used to produce the externally seen features.

As a business, why should you care about internal quality.
  1. Maintainability - a codebase of high quality will be easy to read, easy to understand and easy to maintain. Additionally, by definition, the codebase should be low on defects. Add this all up and you should find that less resources are needed for maintenance and support.
  2. Flexibility - a codebase of high quality will be a codebase of many simple solutions combined in simple and elegant ways. This leads to loosely coupled code which is independent of its surrounds. This, in turn, leads to a codebase that is easily modified, requiring less time and resources to add features that will return value.
  3. Retention of Developers - a codebase that is easy to maintain and add features to will allow developers to focus on higher order rather than mundane tasks. Developers prefer challenges to routine (that's what the computer if for, after all). Happy developers will be far less likely to leave leading to less staff turn over.
Unlike Formula One, the pits and the factories aren't as easy to take our sponsors through and demonstrate to them how their money is being spent. I strongly believe that if we could map our codebases to pit areas than a large majority of businesses would be shocked and would demand that action be taken. (Ideally, I believe this is what they should do. What I believe they would do is something completely different...) In the end, I believe that quality is something worth doing from both a business and a technical point of view and that there are great gains to be made in a business by spending the time to constantly improve its quality. The first step is recognizing that is important.