Thursday, 11 February 2010

Developers Learning: The Facts of Life

Learning is like rowing upstream: not to advance is to drop back.

Chinese proverb

Continuing my exploration of the ways we (software developers) can improve our learning, here are a few facts that provide some useful context. None of them are at all specific to the software development but, as ever, I'm writing from the perspective of the software developer, and addressing the development world.

Learning is a basic human skill.

We all do it. We just do it in different amounts. Small children are constantly learning and amassing new skills. Language, cause-and-effect, and social skills are picked up rapidly from birth. As are basic physiological capabilities like eating, walking, and continence. (Although continence might also be considered a social skill of sorts.)

When it arrives freshly formatted, the human brain rapidly absorbs information and develops skills across a wide range of experiences. It's a remarkable device, both intricate and powerful, and we need to learn how to best use it. Unfortunately, it doesn't come with a User's Manual. (Even if it did, most men wouldn't read it, anyway).

Our learning is often too narrowly focused.

Infants absorb information in many disciplines rapidly. And simultaneously. They don't know that they're simply not supposed to. But all too soon, our training starts; we're introduced to the thought police.

Or, rather, at school we hop on board the academic train and our incredible generalised learning capability is slowly frittered away. At primary school we are taught a range of topics. At secondary school these topics are formalised and compartmentalised somewhat. As we progress through the academic system we cut out certain topics and concentrate on those that suit us best (because of interest or aptitude). At (UK) GCSE level, we narrow the focus to about 8 subjects. We progress to A-Level and narrow that focus to 3 or 4 subjects. Then we progress to university level where we focus on a single subject.

This increasing focus in learning is useful in that it allows us time to become highly proficient in one area, and to devote time to practice the specific skills required to master that subject. It also allows us to chose a single topic that excites and interests us: surely a prerequisite for effective learning.

But often such high specialisation is detrimental to your ability to learn in general. It ingrains a lack of curiosity for other disciplines or any appreciation of the wider human experience. However, it is when disciplines collide that we often see the the most exquisite insights (consider, for example, how Alexander's architectural work illuminated the field of software design [1]).

Learning is hard.

When an infant learns, the world is new and exciting; as they coast through it they just absorb stuff. After a certain point, the things you have to learn become less interesting. Adults force you to learn stuff. It involves effort. Effort which you could expend on other tasks, like playing with your friends, or your toys. Then you're given homework and learning starts to take over your precious “free time”. It feels like hard work. It is hard work.

Learning is hard.

That hard work will, though, be rewarded. But it's easy to resent learning as a tedious chore that stands between us and “fun” or “ability”. Many people's early school experience of learning still colours their adult life approach to learning, even if they don't realise it. How often have you balanced the reward of learning something against the effort involved? How often has the initial learning effort put you off learning something new? Are you now automatically programmed to avoid areas you know nothing about because it is uncomfortable to appear ignorant?

Have your past experiences coloured the way you approach learning?

We must learn how to learn.

Many people were spoon-fed information in school, and told not to criticise. This instils a bad attitude to learning; where it is something someone gives you, or that a teacher does to you. Learning is actually a personal process that you have to take individual responsibility for.

Do you take personal responsibility for your own learning?

Don't blithely accept what you're told. Keep your brain engaged. It's dangerously easy to fall into the trap of believing what you're reading or being told is the gospel truth, rather than something that should be evaluated.

  • How many people read things on the internet and presume that they are true? Wikipedia has a genuine air of authority, yet contains many remarkable mis-truths. Some of the tubes of the internet are rather grimy.

  • How many people read things in their newspaper and unquestioningly presume that they are correct? True, there are lunatics out there on the web, but paid journalists wouldn't make things up, would they? Wrong: there are plenty of lunatics in the media, too. If you believed everything you read in the newspaper then you wouldn't eat or drink anything for fear that it would given you an incurable disease.

  • If it's in a textbook, written by an academic, peer reviewed, and recommended by a prestigious university then it must be correct. But consider who paid to write the book, or who funded the research. What are their motives driven by? Many things presented as fact in the most prestigious journals are, in fact, opinion and conjecture backed up by slim arguments. For example, 70% of everything I've written up to this point was made up. Including that statistic.

Be aware that you can learn the wrong thing and believe it's the right thing. This can be at best embarrassing, and at worst dangerous. This is illustrated by the Four Stages of Competence (a classification posited in the by 1940s by psychologist Abraham Maslow). You may have:

  • Conscious incompetence. You don't know something. But you know that you're ignorant. This is a relatively safe position to be in. You probably don't care – it's not something you need to know. Or you know that you're ignorant and it is a source of frustration.

  • Conscious competence. This is also a good state to be in. You know something. And you know that you know it. To use this skill you have to make a conscious effort, and concentrate.

  • Unconscious competence. This is when your knowledge of a topic is so great that it has become second nature. You are no longer aware that you are using your expertise. Most adults, for example, can consider walking and balance as an unconscious competence – we just do it without a second thought.

  • Unconscious incompetence. This is the dangerous place to be. You don't know that you don't know something. You are ignorant of your ignorance. Indeed, it is very possible that you think you understand the subject but don't appreciate how very wrong you are. It is a blind spot in your knowledge.

So be very careful when claiming competence in any subject, let alone any level of expertise.

Wednesday, 3 February 2010

Speaking: QCon London 2010


I will be speaking at QCon 2010 in London this March. Details of my session are listed here.

I'm excited to be talking in the "Software Craftsmanship" track (something I care about - my book is called Code Craft, after all...) My talk title is The Craftsman Learns (or Learning the Craft). It's an investigation of how, why, and when a software craftsman should learn.

Here's a little more info:

Software developers should be perennial students.

Exceptional programmers aren't the ones who know it all. No one possibly can, no matter what the self-professed gurus would have you believe. Truly great software developers know their limits, and constantly strive to push them, to learn new skills and amass a catalogue of new techniques that can be applied to their craft.

As a programmer you constantly face fresh challenges; you will frequently be forced to learn a new language, a new technology, or a new project. And you will have to know it all by... yesterday. It's both our responsibility and, hopefully, our pleasure.

I this talk we'll investigate:
  • how the software craftsman approaches learningwhat information to learn, and what to ignore
  • how to learn new things effectively
  • techniques for quickly picking up new technology
  • healthy attitudes to towards learning
  • the craftsman's curiosity, and how to assuage it

Keywords
: Craftsman, Learning, Soft-skills, Software practice

Target audience
:
  • Software developers who care about their craft and want to improve their coding skills.
  • No assumption will be made about specific technical knowledge.

Live to Love to Learn

Learning without thought is labor lost; thought without learning is perilous.

Confucius

These are a few thoughts on the importance of learning. It's a theme I've been dwelling on lately, as I've been rapidly learning a lot of new technologies, skills, and languages. I am writing on the topic in my Professionalism in Programming magazine column, and will be talking on the subject at a couple of conferences this year.

This blog entry is addressed to software developers, as I am a software developer. However I believe it's applicability extends beyond software development...


Learning to learn

Programming is a creative, intuitive process. I, like many other programmers, like to think of it as an artistic pursuit; one of working a medium to produce something of utility and beauty. But all too often the commercial reality of coding is something more akin to being placed in a meat grinder, until every last ounce of coding prowess and motivation has been sucked from your soul.

Nonetheless, programming is an exciting and dynamic field to work in. One of the main reasons is that there is always something new to learn. Rarely are programmers forced to run around in circles performing the same repeated task for years and years, only discovering new ways to develop RSI and failing eyesight. We continually face the unknown: new problems, new situations, new teams, new technologies, or some combination of these. True, some programming jobs face more excitement than others, more of the unknown than others, and garner more techie thrills. But if you're going to be stuck in an office sat behind a desk, you may as well keep your mind occupied.

We are continually challenged to learn, to increase our skills and our capabilities. If you feel like you're stagnating in your career, one of the most practical steps you can take to get out of the rut is to take the effort to learn something new. On purpose.

Now, some people are naturally better at absorbing new information and “getting up to speed” more rapidly than others. They are better at taking on new concepts and relating new concepts to gather a greater understanding. That's natural. But it's something we can all improve at. You need to take charge of your learning.

Check point

Ask yourself now whether learning is something that you think about consciously as a programmer? Is it something you consider as one of your programming skills? Do you actively try to learn things? Do you willingly put yourself into areas of the unknown? Or do you try to stick to what you know best, looking for an easy life?

Are you motivated as a programmer to find out new information and improve yourself? Do you relish learning? Or is it something of an inconvenience?

Do you want to improve as a programmer? I suspect that in this regard I'm preaching to the converted in this article. An ACCU member reading CVu clearly wants to widen their knowledge. Well done, give yourself a pat on the back! The simple fact is this: if you want to improve as a programmer, you need to be a skilled and seasoned learner. And you need to learn to enjoy it.

So lets think about the what, why and how...

Why learn?

Sometimes you have no choice but to learn; you are faced with a new task and you know nothing about the technology or the problem domain. You've got to get up to speed, and fast. Often the killer problem is that you have no time to do this in, and have to make a work estimate or deliver the first bit of functionality before you'd even have time to gather the vaguest overview of the topic.

The programmer's lot is not a happy one.

But even when you're coasting – working on reserve knowledge, with no need for new information – it's important to keep the grey cells ticking over and absorb new knowledge. One important reason is to simply cultivate a good learning habit; to maintain your ability to absorb information. Continually learning also helps to shape your programming attitude; to prevent you from believing that you're an expert! No one likes a know-it-all, after all.

There are plenty of other good reasons to develop yourself by learning. Your motivation might be to keep yourself fresh, to sharpen your existing skills, or simply to satisfy your natural curiosity. Or the reason might be more mercenary: the strengthen your employability, or allow you to manoeuvre into a programming field you're more interested in.

If you don't keep up a habit of continual learning you will go stale. You'll stagnate. The technological world will pass you by.

This demonstrates a simple learning maxim: Learning. You've either got to, or you ought to.

What to learn?

There's a whole world of things you could attempt to pick up. So what should you look at? Donald Rumsfeld summed up this conundrum in a particularly apt way when he made an infamous White House press conference: As we know, there are known knowns; there are things we know we know. We also know there are known unknowns; that is to say, we know there are some things we do not know. But there are also unknown unknowns – the ones we don't know we don't know.

So what do you pick? Clearly not something you know you know (although learning a topic more deeply, or attempting to consolidate your knowledge on a topic is a valuable task). Instead should you chose something that you know you don't know, or first learn about what you don't know in order to chose what to learn? That might make your brain bleed. Thanks a bunch, Rumsfeld.

Perhaps the list below will help. If you are learning for “fun and personal profit” rather than your job leading you to a specific topic, you might consider:

  • Learn a new technology. For programmers this is the obvious choice. We're fascinated by the different ways we can make electrons dance, and there's a wide field here to mine.

You might choose to find out about a new programming language; there is no shortage of new and interesting languages being developed, there are many widely-used languages that you could learn to gain employability-enhancing skills, and there are many interesting existing languages. Consider looking at a language that promotes a different paradigm to your current languages to learn new ways to approach and solve problems – perhaps a functional programming language like Haskell would be a good choice. In their classic 1999 book, the Programmatic Programmers recommended learning one new language every year [1]. It's good advice. You don't have to become an expert, but do get beyond “Hello, World!”

You could instead choose to learn a new library or application framework; perhaps an interesting low-level utility or a snazzy new high-level UI toolkit. After all, you can never have enough UI toolkits.

Or learn a new software tool. You should never underestimate the usefulness of learning new tools that will make your work more productive and/or more enjoyable. Learn how to use a new text editor, or IDE. Learn a new documentation tool or a test framework. Learn a new build system, an issue tracking system, a source control system (indulge yourself in the new distributed version control craze that all the cool kids are going on about), a new operating system, and so on.

Even if you are not going to use the new technology immediately in your “day job”, learning about it will almost certainly help you to use your existing technology in better ways, and will help you to evaluate new technologies when the need arises.

  • Learn new technical skills. You might want to learn how to more effectively read code, or write technical documentation. You could learn how to manage a software team and climb the greasy career ladder.

  • Learn how to work with people. Yes, this is tediously “touchy-feely” for most code monkeys. But it can be an incredibly interesting field, and very useful. You could look at sociology, or study some management texts. This kind of information will help you to become a much more capable team worker, and will enable you to lead teams into directions that you think they should go in, rather than suffer in silence. It will help you to understand how people are communicating to you, and how to communicate effectively with them. You'll discover how to understand your customer better, and filter their requirements.

  • Learn a new problem domain. Maybe you always wanted to write mathematical modelling software, or do audio DSP work. Without any experience or knowledge you'd be unlikely to fall into a job in a new sphere, so give yourself a head start and begin to learn about it. Then work out how to get practical, demonstrable experience.

  • Learn how to learn. Seriously! Perhaps you could invest your time into finding out some new learning techniques that will help you absorb knowledge more effectively. Do you find there's a constant barrage of information you need to tap in to, and it just seems to flow past you? Investigate ways to seek out, consume, and absorb knowledge. There's a whole lot more to this than I can cover in these C Vu articles, after all! Consider learning and practicing new skills such as mind mapping and speed reading.

  • Learn something completely different. Or, more interestingly, you may prefer to choose something completely left-field with no relevance to your day job, and no obvious software applicability. Learn a new foreign language, a musical instrument, a new branch of science, art or philosophy. Hey, even spirituality. Far from being a pointless waste of time, or a distracting personal hobby, doing this will open your world view wider. If you're willing to look for the interesting themes and techniques you will certainly find that it helps to inform the way you program.

Above all, pick something that interests you. Pick something that will benefit you (the act of learning in itself is a benefit, but choosing something because it will give you fresh usable skills, broadens your insight, or brings you pleasure is a good thing). You will be investing a significant amount of time, so invest wisely!

Monday, 18 January 2010

Writing: New article in CVu

The January issue of ACCU's CVu magazine is hitting doormats around the world. It contains the latest in my Professionalism in Programming series - Live To Love To Learn. This article is the first in a mini-series investigating how we learn as software developers.

Thursday, 7 January 2010

Writing: 97 Things Every Programmer Should Know

The 97 Things Every Programmer Should Know book from O'Reilly, edited by Kevlin Henney has almost come to completion; it's due for publication next month.

They've just posted the list of contributions appearing in the book. I'm pleased to say that three of my five submissions are in the list. You'll be able to purchase a paper copy of the following entries:
  • You've Gotta Care about the Code (link)
  • Improve Code by Removing It (link)
  • Don't Ignore That Error! (link)

Tuesday, 5 January 2010

iPhone: Application preferences/defaults/settings. With defaults.

How to extend NSUserDefaults with default values.

Time for more iPhone shenanigans. Lots of people have contacted me saying these posts are useful - thanks. As I do more iPhone development I discover things that aren't immediately obvious from the SDK documentation (excellent as it is). I'm documenting some of them in my blog partly to find out if I've missed the obvious, and partly to give back to the community - Google has certainly pointed me to plenty of other people's blogs with useful answers.

Today's installment: application settings. Or preferences, if that's what you want to call them. Or settings, if you prefer.

Finding the preferred term

The iPhone SDK provides a neat API for persisting simple sets of application settings. It's easy enough to find, if you know what it's called when you search for it. Don't search for preferences, like I did, or you'll be sent down the Core Foundation dead-end of Preferences Programming Topics. This is a rich and fairly heavyweight API for persisting state. But for a simple iPhone app it's overkill.

What you do need to look for is the Cocoa NSUserDefaults class. That's the puppy you want. It's simple when you know what to look for. This class provides an easy way to read and write fundamental data types (integers, floats, bools, NSStrings, etc).

What's missing? NSUserDefault's defaults.

Again, perhaps I've missed something. But this class is missing something fairly obvious. It has a simple set of APIs to write values against a given NSString "key" name, e.g. setInteger:forKey: It has a set of APIs to read those values back for a given NSString "key" name, e.g. integerForKey:

However, there is no way to discover whether or not a setting has been saved yet. This is important since the first time your application is run no preferences have been saved, and you'll need to fall back on a set of well-chosen default values. The NSUserDefaults accessors return "default initialised" values if a key has not been set yet; e.g. 0 for integers, 0.0 for floats, or a nil string. You can't always inspect an integer for zero and replace it with a default - sometimes zero is a valid setting value.

So what can you do about this?

Adding defaults to "defaults"

We can add this functionality to NSUserDefaults easily enough. The first trick is to determine whether a value has been stored for a particular key or not. It turns out that, no matter what kind of key has been stored, internally everything can be accessed as an object and the objectForKey: method returns nil if no value has been stored.

So you can see whether an integer, for example, has been stored by calling objectForKey: with its key name. The returned id value is nil if the integer has not yet been stored, and non-nil if it has.

Useful.

Now, ideally we'd have a suite of methods that read values from the NSUserDefaults class and return a specified default value if that setting has not yet been made. This can be done neatly using Objective-C's class category facility. Categories allow you to extend existing classes with extra functionality.

Here is some example code showing how to do this for some of the basic types. Once you've put this snippet into your application you can use the methods as if they were an original part of the NSUserDefaults API.

@interface NSUserDefaults (ReadWithDefaults)
- (NSInteger) integerForKey:(NSString *)key withDefault:(NSInteger)value;
- (BOOL) boolForKey:(NSString *)key withDefault:(BOOL)value;
- (float) floatForKey:(NSString *)key withDefault:(float)value;
- (id) objectForKey:(NSString *)key withDefault:(id)value;
@end

@implementation NSUserDefaults (ReadWithDefaults)

- (NSInteger) integerForKey:(NSString *)key withDefault:(NSInteger)value
{
if ([self objectForKey:key])
return [self integerForKey:key];
else
return value;
}

- (BOOL) boolForKey:(NSString *)key withDefault:(BOOL)value
{
if ([self objectForKey:key])
return [self boolForKey:key];
else
return value;
}

- (float) floatForKey:(NSString *)key withDefault:(float)value
{
if ([self objectForKey:key])
return [self floatForKey:key];
else
return value;
}

- (id) objectForKey:(NSString *)key withDefault:(id)value
{
id obj = [self objectForKey:key];
if (obj)
return obj;
else
return value;
}

@end

Writing: Creating a Framework for the iPhone

December's Overload (an ACCU magazine) was published at the end of 2009, containing an expanded article form of my Creating a Framework for the iPhone work.

You can read it online in the Overload Online section of the ACCU website.

If you're a programmer who cares about code, and how to write good code, you should consider joining ACCU. It's not expensive, and is an excellent way to improve your skills in a great international community of programmers. You can read PDF versions of Overload magazine for free if you're not an ACCU member, but to get CVu magazine you have to become a member.