Learning to learn

What does it take to acquire new skills and knowledge? Or a review of Dreyfuss model of skill acquisition.

When we want to acquire a new skill, we are faced with two choices: trial-error, or instruction. One is experience-driven or practice-based, the other is concept-driven or theory-based.

The trade-offs

Trial-error is the built-in mechanism humans come with to acquire knowledge and skills – our thinking processes are optimized for that. However, it may be expensive and impractical in some situations. For instance, learning to pilot an aircraft by trial-error is risky should you want to keep the chances of learning in the future high. We have developed systems that lower the cost of trial-error, though, such as pilot simulators. It can also be time-consuming: we just don’t have the time to trial-error every piece of knowledge our society is based upon!

Learning by instruction appears to be more efficient: we are presented with models and recipes that work, saving us a lot of time that we can use to advance our knowledge further. Nevertheless, the instruction is not always possible; sometimes the map of knowledge of a certain domain isn’t built yet, so we need to rely on the trial-error approach. Even most important is the fact that internalizing abstract knowledge not based on direct experience seems to be more difficult for humans.

This poses a question: how shall we learn?

The Dreyfuss model

In February 1980, Dreyfuss brothers published a seminal paper on how to teach: «A five-stage model of the mental activities involved in directed skill acquisition». This work was supported by the US Air Force, which was interested in improving their training programs.

What they said is 1) we should recognize the role of the first-hand experience in acquiring knowledge and 2) to become an expert it is necessary to learn the rules, guidelines, and maxims of the particular skill we are interested in.

The rules are the principles that always apply, they don’t depend on anything so they are context-free or non-situational. Examples of rules are the valid movements of a piece in the go game, the set of instructions in programming, the techniques in the Aikido martial art.

The guidelines are the principles that only apply in specifics contexts, so they are context-bound or situational. Things like josekis in the go game (sequences of moves in a specific part of the board), the design patterns in programming, or the katas in Aikido.

The maxims are principles that guide us towards achieving our long-term goal, they help us by assigning a value to guidelines: is this joseki worth it if I’m playing for territory in go? Is the ability to grow new features necessary for this specific part of the application? What specific throw should I use if I want to face the next adversary?

For one to become an expert, rules, guidelines, and maxims should be second nature.

Dreyfuss defines a 5-step process someone goes through to gain knowledge: novice, competence, proficiency, expertise, mastery. Others outline different systems that include three stages. What’s important is to realize that the learning process is at its best when we take a practical approach and theory is presented to the learner as they are prepared to assimilate the next artifact – rules, guidelines, maxims.


Learning to learn is probably one of the more important skills when we no longer know what’s coming next. The real world TM tends to be more chaotic and intertwined than the sequential process outlined by Dreyfuss. Realizing where are you at a particular skill will help you in making decisions about what focus on. For instance, am I a novice at skill X? Well, at this point, I’m better off focusing on learning the rules and imitate what others have done. And so on.

Learning also takes a lot of time – someone has even published a number, about 10.000 hours to become an expert in anything. It’s a lot! It may be discouraging. Luckily, a practice-based approach makes things more rewarding, and time flies when we are enjoying the process.

The thing that get us to the thing

Past Saturday, AMC aired Halt and Catch Fire season finale. I saw this tv-show grow over 4 seasons and I’m sad it’s over.

HACF resonated with me because it was about the pleasure of making things work and the cost of pursuing your dreams. We need a whole lot more stories about the woes and joys of creation to learn how to navigate that world and to inspire us. We need more builders and dreamers capable of not burning themselves out.

Bonus points for using the evolution of computers as the McGuffin. But, as much as I liked the history of computers being the central plot of a well done period  drama, HACF wasn’t about computers. The computers aren’t the thing. They are the thing that get us to the thing.

The pleasure of finding things out

This was the first book listening experience that I’ve actually finished. Sean Runnette‘s voice was adequate for setting the tone and rhythm – actually, sometimes I felt I was listening to Feinmann himself!

Having read Surely You’re Joking, Mr. Feynman!What Do You Care What Other People Think? and some other papers/videos, most of the stories in the book I already knew, but it had some new material that made it interesting nonetheless. This is more mathematical/physical intense than the others, probably because it’s mostly focused on the scientific and less in the human Feynman – but also because many chapters are directly transcribed from conferences he gave. It’s also worth noting that, unlike the other two, this book was published without Feynmann intervention: it’s published 10 years after his death.

If I had to choose only a Feynman book I’d choose Surely You’re Joking, Mr. Feynmann! It’s better edited and has more variety. Then, if you are hungry for more, What do you care what other people think? contains new stories. I liked this one, but I doubt it’s a good introduction to Feynmann lifestyle, work, values, and character.

Code simplicity

A review of Max Kanat-Alexander’s Code Simplicity book.


I’ve just finished the book Code Simplicity. It presents a framework for thinking about software development in the form of laws and rules. It’s short but comprehensive. From my experience, the laws and rules hold true. I think the book has value as an overall perspective of what’s important in software development, and there are some chapters that are really spot on: for example, the equation of software design – something that I’ve already included in my glossary and plan to expand.

Code Simplicity doesn’t intend to land the laws and rules to something actionable, though. I’m at a point in my career where I’m focused on consolidating and reflecting upon how to achieve simplicity in software design – that means that I crave for specifics so I can compare them with mine.

As a cross-recommendation, if you are interested in learning about the laws of software development in a manner that is actionable, I’d suggest reading the Beck’s trilogy: Extreme Programming Explained: Embrace Change, Test Driven Development: by example, and Implementation Patterns. Those three books make a great combination of macro-forces (at a project level) and micro-forces (at a coding level) in software design. They were fundamental in consolidating my experiences as a programmer, so I’m highly biased towards them.

Hat tip for the Code Simplicity recommendation: Nikolay.

Turns out algorithms are racists

«Technology is neither good nor bad; nor is it neutral.»

Melvin Kranzberg’s six laws of technology

One of the things I was very into a decade ago was studying the intertwine between technology, culture, and society. From those years, I developed a sensitivity about my role as an engineer, or as an enabler of possible worlds.

This is one of the things I wanted to avoid:

A person isn’t able to clean his hands because the machine sensors are only prepared to detect white hands! That’s a horror story that could make a BlackMirror episode.

This made me think about the mainstream perception of Machine Learning and Artificial Intelligence technology. Lately, some friends of mine are sharing with me clickbait news like Facebook shuts down robots after they invent their own language. They ask me if robots could take over, soon. Well, I can tell you something: at this stage of technology, I am not worried about robots taking over. What I do worry about is how our inability to understand technology creates racists algorithms that reinforce our biases.

Psychological safety

(…) the number-one indicator of a successful team wasn’t tenure, seniority or salary levels, but psychological safety.

Think of a team you work with closely. How strongly do you agree with these five statements?

  1. If I take a chance, and screw up, it will be held against me
  2. Our team has a strong sense of culture that can be hard for new people to join.
  3. My team is slow to offer help to people who are struggling.
  4. Using my unique skills and talents come second to the objectives of the team.
  5. It’s uncomfortable to have open honest conversations about our team’s sensitive issues.

Teams that score high on questions like these can be deemed to be “unsafe”. Unsafe to innovate, unsafe to resolve conflict, unsafe to admit they need help.

— Engineering a culture of psychological safety

Code and decision trees

An example on how changing the language for thinking may help us to simplify our programs.

A lot of what programs do is transforming inputs into outputs. Take, for example, a piece of JavaScript code like this:

itemsToMarkup( items, viewType, galleryType ) {

    let markup;

    switch ( viewType ) {
        case 'gallery':
            if ( 'individual' === galleryType ) ) {
                markup = getHTML( items );
            } else {
                markup = getShortcode( items );

        case 'image':
            markup = getHTML( items );

    return markup;

What’s the purpose of this code? It takes some input data structures and outputs a markup, either proper HTML or a code to be processed by later stages of the pipeline. At the core, what we are doing is taking a decision based on the input’s state so it can be modeled as a decision tree:


By restating the problem in a more simple language, the structure is made more evident. We are free of the biases that code as a language for thinking introduces (code size, good-looking indenting, a certain preference to use switch or if statements, etc). In this case, conflating the two checks into one reduces the tree depth and the number of leaves:


Which back to code could be something like:

itemsToMarkup( items, viewType, galleryType ) {

    let markup;
    const isGalleryButNotIndividual = ( view, gallery ) => view === 'gallery' && gallery !== 'individual';

    if( isGalleryButNotIndividual( viewType, galleryType ) ) {
        markup = getShortcode( items );
    } else {
        markup = getHTML( items );

    return markup;


By having a simpler decision tree, the second piece of code makes the input/output mapping more explicit and concise.