Thursday, 29 March 2007

Book ideas

Ideas for books to write:

"Make me think: The School for Genius":
  • A guide to figuring things out for yourself
  • Learning philosophy:
    • discovery learning
    • learning by doing
    • drawing connections
    • open-ended
    • verification (how do I know that's right?)
  • Guides the reader through the essence of several subject through hints and puzzles
  • Unconventional approaches
  • Suitable for bright teens & life-long learners

Don't turn to the back of the book

Sometimes laziness has strategic advantages. When I was doing my PhD I did my literature review very late in the piece. This had the advantage of not contaminating me too much with existing ideas early on. And when I did get around to it I knew enough from my own trials and tribulations to be able to read the literature intelligently and critically.

I had a similar experience while teaching myself Operations Research in my first significant job in Industry. I had done a one-semester course -- not long enough to learn too much -- and so I was able to produce the real-life problems with a degree of freshness, rather than trying to (mis-) apply the known "solutions".

Generally speaking, I advocate mastery of fundamental ideas and techniques. These are often the most portable and adaptable. By contrast the advanced techniques can be quite specific, like an organism that has a evolved to fill a very narrow niche.

Turning to the back of the book, listening to lectures etc. may seem faster, but taking the slow hard road is a richer path. And in saying this I am in excellent company ...

Clearly Feynman was of the "no, don't tell me the answer" school of learning":

The deal this time was that Feynman would teach Fredkin quantum mechanics and Fredkin would teach Feynman computer science [27]. Fredkin believes he got the better of the deal:

`It was very hard to teach Feynman something because he didn’t want to let anyone teach him anything. What Feynman always wanted was to be told a few hints as to what the problem was and then to figure it out for himself. When you tried to save him time by just telling him what he needed to know, he got angry because you would be depriving him of the satisfaction of discovering it for himself.’
Feynman constantly emphasized the importance of working things out for yourself, trying things out and playing around before looking in the book to see how the experts’ have done things.

From Richard Feynman and Computation [pdf]

Tuesday, 27 March 2007

Books Wishlist

Here's a list of gift ideas for me.

Let me know if you commend or hate anything on the list, or if you want to send me a copy!

  • Goldberg, Writing Down the Bones, "Wherein we discover that many of the 'rules' for good writing and good sex are the same"

More to come ...

Monday, 26 March 2007

Aesthetics, Programming and the Sex Link

How to code like a girl prompted this post.

My (male) friend’s piano teacher told him:

“If your hands do not look beautiful, your music cannot sound beautiful.”

The teacher was female.

Do aesthetics play a big part in programming? Absolutely.

Clearly the importance of aesthetics has not triggered a rush of women into the profession of programming.

Perhaps – as in mathematics -- it is something to do with the abstract nature of the beauty involved?

I know that my partner -- whose hobby is making patchwork quilts (geometry) and whose addiction is doing Sudoku and Kakuro (NP-complete puzzles) -- is not interested in making the abstraction leap into hobby-programming in Prolog or Scheme. I, on the other hand, have made one quilt, solved one Sudoku and one Kakuro, and that was enough.

I did have some success getting my then seven-year-old niece interested in Logo Turtle programming, but this was compromised by her being "taught" computers at school. Maybe my daughter (aged 16 months) will be a better bet in a few years time?

Interesting Solutions to SICP Chapter 1

I have started working through SICP chapter 1, using the Dr Scheme interactive environment. I will post my more interesting solutions and comments.

Ken Dyck gives a more complete solution set.

Comment: Rather than finding the larger two explicitly, I find the smallest and use a simple mathematical identity.

My solutions:

Exercise 1.3. Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.

(define (f a b c)
(define (lt a b) (if (> a b) b a))
(define (least a b c) (lt a (lt b c)))
(define (square x) (* x x))

(+ (square a)
(square b)
(square c)
(- (square (least a b c)))))
Comment: Rather than finding the larger two explicitly, I find the smallest and use a simple mathematical identity.

Exercises 1.17 & 1.18: Devise recursive and iterative algorithms for multiplication that take a logarithmic number of steps.
(define (mul-recursive a b)
(cond ((= b 0) 0)
((even? b) (mul-recursive (double a) (halve b)))
(else (+ a (mul-recursive a (- b 1))))))

(define(* a b)
(define (mul-iterative r a b)
(cond ((= b 0) r)
((even? b) (mul-iterative r (double a) (halve b)))
(else (mul-iterative (+ r a) a (- b 1)))))

(mul-iterative 0 a b))
Comments: Observe how similar the two solutions are. The iterative solution is especially easy to follow if you expand out an example.

Good Traits in a Software Developer

Over at The Bleeding Edge Purumu has blogged about 5 traits of a good developer:

1. Curiosity
2. Good analysis skills
3. Patience
4. Abstract Thinking
5. Communications

He suggests that having these traits trumps knowledge of a particular technology and I heartily agree. Technologies change -- oy do they change! -- but these traits are key ingredients for valuable team-members in the software development biz.

I could add "initiative", "originality", "sense of humour", and "commitment to quality", but that might make the list a bit long!

To what extent you can "put in what God left out" is a re-hash of the eternal nature / nurture debate, but I think that it is clear that given some of these traits, and willingness to learn, it is possible to train at least some of them up further.

Now, do these traits have a role to play in hiring, reviewing and professional development?

I think so. Joel Spolsky recommends hiring "smart people who get things done", which is also sound advice, but this breaks it down a bit further.

On any team it's good to have people who are particularly strong in the various traits, making the team very strong overall. But is better to enhance one's own weak points or further develop one's strong points? Personally, I favor evenness of development, which goes towards making people into stronger generalists rather than specialists.

Why? It increases flexibility, so that the individual can tackle a greater variety of tasks and in particular complex tasks which require multiple abilities, which I believe will help keep job interest high. From a team perspective there is greater overall capability and flexibility in task assignment.

Now, it's not that I am against people have personal specialties, it's just that I think that these will emerge naturally out of personal interest, while it can take a little bravery -- and encouragement -- to develop in which one feels below par (and may have avoided working on for this reason).

Ultimately, development of traits such as these may shape roles and career paths. It all makes good food for thought.

1. What kind of activities can enhance these traits?
2. Are these traits measurable or quantifiable?

Sunday, 25 March 2007

Let's Get Functional

Last week I watched Harold Abelson's introductory SICP lecture, courtesy of Google Video. SICP is short for Structure and Interpretation of Computer Programs, which is a much copied course given at MIT, and the title of Abelman and Sussman's now classic introductory text to Computer Science. Besides the video lectures, the complete text is available from the above link online. Thank-you!

Talk about insightful! This is what Computer Science is really about. Probably more advanced than most undergraduates can cope with, I am taking the time to look at these classic texts because I suspect that functional programming (FP) is about to become much more important.

Why? Besides the intrinsic pleasure in learning and extending oneself, multi-core CPUs are starting to go main-stream, and I believe that FP is our best hope to take advantage of a new age of parallel hardware.

So I plan to brush up by going through some / most of SICP (and doing the exercises), before moving on to one or more of Haskell (especially for monads), OCaml, and F#.

SICP is draws many examples from mathematics, so with my background it looks very inviting. Others may prefer How To Design Programs, another freely available text.

* * *

Abelson says that when you look into a computer language, you should ask:
  • What are the primitives?
  • What are the means of combination?
  • What are the means of abstraction?
The primitives are the "building blocks"; the means of combination are the ways of putting the primitives together; and the means of abstraction are ways of building composites (out of primitives and other composites) when the primitives are insufficient. If the composites are then indistinguishable from the primitives, you have something truly powerful.

This prompted an interesting thought the following day:
Do these criteria also apply to computer applications?
More on this later ...

Wednesday, 21 March 2007

How programming and its theory can expand the mind

From the preface to Simply Scheme (my emphasis):

There are two schools of thought about teaching computer science. We might caricature the two views this way:

The conservative view: Computer programs have become too large and complex to encompass in a human mind. Therefore, the job of computer science education is to teach people how to discipline their work in such a way that 500 mediocre programmers can join together and produce a program that correctly meets its specification.

The radical view: Computer programs have become too large and complex to encompass in a human mind. Therefore, the job of computer science education is to teach people how to expand their minds so that the programs can fit, by learning to think in a vocabulary of larger, more powerful, more flexible ideas than the obvious ones. Each unit of programming thought must have a big payoff in the capabilities of the program.
I subscribe to the radical view, although my Computer Science education is more of a self-education, so I would say that it is a case of learning to expand one's mind appropriately.

Now, a further benefit of learning to program at increasingly high levels -- beyond the ability to deliver bigger and better programs -- is the accompanying mind-expansion. That this will have benefits in other areas of thinking and doing was a key thesis of Seymour Papert, and motivated his work with Logo etc., in the foot-steps of Piaget.

Of course other disciplines may have similarly transferable benefits, but computer science / programming seem to be under-rated in the wider community in this respect.

For example, when I started a law degree -- later abandoned -- it seemed to me that a background in programming would be very helpful to whoever was drafting statutes. Thus far I believe that there is no such trend.

Contrast this with the preponderance of lawyers in parliament!

Tuesday, 20 March 2007

Inspirational Quotes

I wake up every morning determined both to change the world and have one hell of a good time. Sometimes this makes planning the day a little difficult.
E. B. White

Thursday, 15 March 2007

What Would a Functional Progammer Do?

As C# adopts features from functional programming languages it is becoming increasingly possible to program in an-least partially functional style as part of your day-job.

At time of writing I am using C# 2.0, which has reasonable support for lambda functions in the form of delegates, but they are ugly, because of the presence of strict-typing / absence of type-inference. You need to think things out functionally and then translate into the clunky C# 2.0 notation.

Things will get better with C# 3.0 and a host of functional-inspired features, including limited-type inference and cleaner notation to support LINQ.

Anyway, yesterday I was pairing with a colleague working on implementing some experimental enhancements to some core algorithms, and we were running into difficulties. Because the implementation was in C# we were thinking in an imperative way, and after running through a few options and hitting various dead-ends I asked Peter, "What would a functional programmer do?"

We were working on variations of an in-place algorithm, where a functional programmer would tend to write -- wait for it! -- a pure function. In our case a more functional approach was going to be a lot easier. Our context had blinkered us. And once you take a step back and put the functional hat on, other avenues open up.

So, here's a short list of things a functional programmer might do, and which are worth thinking about when you're trying to solve a programming problem:
  1. In-place modification or pure function?
  2. Higher-order functions: Does treating code as data lead to simplifications?
  3. Can monads help?
Of course the amount that you can do may depend on language support that is present. Item 5 is a reminder to get on top of the monads concept: "If you can't understand it, you won't recognize when you can use it!"

All of this is in aid of the ideals of better abstractions, clearer and more understandable code, leading to higher quality and greater satisfaction and success.

There's a paradox that one may need greater understanding to express things more simply, and that for someone with less understanding the higher. clearer expression may be incomprehensible. But that's really old news: Look at the history of science and mathematics. Example: Want to know the area under a funny looking curve? Easy if you know calculus. Don't know calculus? A simple explanation may be hard to come by!

Now for the big question:

If Jesus were alive today, would he use a functional programming language? Who knows?

But Moses would, for sure.

Tuesday, 13 March 2007

Strategies for Software Quality

Today we -- i.e. the team and I -- are trying to fix a recalcitrant bug. This is always somewhat frustrating, but since our bug count is low, it means that the bugs that are left are tough to track down and kill.

The good news is that we have a work-around for the affected party, but we have yet to reproduce the problem on anyone else's machine. And of course, if you can't reproduce it, it's difficult-- although perhaps not impossible -- to fix it.

In terms of general strategies for creating high quality / low bug-count software, the following have worked well for me:

1. Design By Contract (DBC): Read Object-Oriented Software Construction (2nd ed.) by Bertrand Meyer and become a much better programmer. Although you need the not-widely-used Eiffel language to get the full benefit of this approach you can get 80% in any language by implementing cheap pre-condition and post-condition library. It allows you to write down what you think you know about the program state and allows the computer to catch errors early and close to point-of-failure. The name of the game is localizing the error.

2. eXtreme Programming (XP)Practices: Especially:
  • Pair programming: Two heads are often better than one
  • Test-Driven Design/Development (TDD): Overlaps somewhat with DBC, but very useful (write the test, make it pass, re-factor). Note: I tend to use DBC to test the pre-conditions, and TDD to sample the post-conditions, to reduce the overlap.
  • Continuous Integration: Saves you from "merge hell" when working on a team
  • Sustainable pace: Working long hours will damage the code-base
3. Make the code beautiful by re-factoring
  • "Don't Repeat Yourself" (eliminate duplication)
  • Find the right abstractions (unify and split as needed)
4. Don't optimize too early: Optimization reduces flexibility and clarity, and hides bugs.

5. Good diagnostics: If a bug does occur to a user make it easy for them to send you an error report with the information that you want: Error-code, OS version, app. version, stack-trace etc. With rich diagnostics you may be able to fix some errors that you can't necessarily reproduce.

6. Learn: Look into higher-level and academic languages for rich ideas (e.g. Eiffel, OCaml, Haskell, Lisp, Prolog, etc.) and see if you can use them to simplify your code.

What I don't use so much is exceptions and defensive-programming. Serious users of DBC and TDD both find that exceptions are needed a lot less often than you might think. Defensive-programming is trumped by DBC.

Patterns are useful, especially for talking about software design chunks, but they aren't the key to my approach.

Parting quote:

"There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies." — C.A.R. Hoare.

Monday, 12 March 2007

Inspirational Links

This is a list of links that I found evocative. Naturally, it's a work in progress:

What am I doing?

What are you Doing?
There's a great training game for Improvisational Theatre called "What are You Doing?". You need two or more people:

The first person starts miming something, say: Casting a fishing line, and the next person comes along and says "What are you doing?" The first person has to reply with something unrelated to what they are miming. Then the asker starts miming the named activity, until another person comes along, and asks "What are you doing?", and so on.

The idea is to not think in advance of the unrelated activity. It's kind of fun, quite challenging, and surprising what "pops out" of your mouth. Those taboo subjects take a while to work out of your system. It's all about spontaneity and giving the internal censor a bit of a holiday. Creativity on demand!

I should try some of these games out on my work colleagues.

What am I doing right now?
I'm in the process of re-factoring some software. This is a bit like editing a piece of writing. You see a way to improve the writing, and you make some modifications. The name comes from factoring an expression -- yay maths! -- in a form where the factors can be more clearly seen. For example:

x^2 + 3x + 2

can be rewritten as


Why? I'm not adding features. I.e. I'm not directly adding business value.

Well, it's a bit like gardening. If I don't prune and fertilize, eventually the plants are going to get over-run with pests, the soil is going to become exhausted, and the yields will go down slowly but surely.

Now, the kind of re-factoring that I'm really interested is in finding better abstractions. Today's effort is based on a recognition that certain concepts need to be separated, while others need to be unified.

The hard bit is to do this all step-by-step so that the program still compiles and the tests continue to pass. Having recognized what needs to be done at a broad level -- the creative bit -- the execution is a little tedious, but strangely relaxing.

What motivated me to do this instead of prototyping ("spiking") some new features was a recent viewing of almost all of an excellent video presentation on the Agile project management process Scrum, in which Ken Schwaber he explains how software can become "Design Dead" over time, by neglecting these kinds of activities.

Basically: Cutting corners to meet deadlines is a "great short-term tactic, but a terrible long-term strategy". It's insidious, gradual, hence highly dangerous.

Reflection of the day
It's interesting to contrast these two activities:

  1. The impro game emphasizes spontaneity and playfulness
  2. Re-factoring is superficially about good planning and being methodical
But you can't re-factor well without creative insight, so there-in lies the similarity.

Thursday, 8 March 2007

What's a Kibitz?

Q: What's a kibitzer?

A: A kibitzer is the guy who watches your card game and tells you what to do. He doesn't play, just advises. It's from the Yiddish. The players and definitely the kibitzer are Jewish. A dibitzer is the guy who advises the kibitzer, "Tell him to play that card".

So a kibitz is a piece of unwanted and probably unhelpful advice.

Q: So what's this blog about?

A: It's just a place for me to jot my thoughts, store my links and commentary, and indulge in the odd / regular rant, and do a bit of "creative" writing. What used to be called a "diary", back in the day when we had things called record-players and sent bits of paper with hand-writing on them in envelopes by mail.

Q: So what's in it for me?

A: Unless you are me: Nothing, nil, nada. Go away! Read my other blog. Rack off. Do something useful with yourself. Or go read Reddit.

Q: I'm still here.

That's not a question.

Q: I know, but I'm interested in what you are writing. Can I leave comments?

Well, it's your choice. Yes, you can leave comments, but stop trying to be polite already. This is not the place. Kapeesh? Now, get back to work!