During the last year I’ve been helping run a monthly series of dojos for the London Clojure User Group. In the course of it I have had the chance to watch a lot of people grapple with functional programming. As a result of this and also looking at the way a lot of my colleagues at ThoughtWorks work I think programmers can roughly be divided into two groups: Intuitive and Reasoning.
To characterise both of them a little, I think that Intuitive programmers tend to use domain language a lot, rely heavily on tests and TDD, often find it difficult to articulate what they are doing in their work, they like small source code files because they like to see everything a file does at a glance, they prefer outside-in problem solving and like the opportunity to go back and revise their work.
Reasoning programmers like to discuss a problem before coding and explore edge-cases and what-ifs, they like to work in the REPL or have in-editor code evaluation, they quickly move from a domain to an abstraction and then work in that abstraction, they don’t mind a thousand line source file as long as it is logically structured (that’s what the search function is there for), they prefer “bottom-up” coding where they distil their abstraction to its essence and having implemented that create the required behaviour by composing their abstractions.
Both sets of programmers can be great at their work but often if they are unaware of the characteristics of how they like to work then there can be massive amounts of tension as the two wrestle back and forth. The Intuitive developers feel angsty when the Reasoning programmers start hacking out code rather than refactoring, Reasoning developers get frustrated at the aimlessness and game playing of the Intuitive’s attempts to generate the minimum amount to make their tests pass.
Reasoning programmers probably feel that in terms of communicating they have the superior style as they are able to advance arguments and logical constructs that can be interrogated. Those articulated models though can feel arid and irrelevant to Intuitive programmers, what does some obscure mathematical formula have to do with trying to make sure the frog doesn’t get run over when it crosses the road?
Intuitive programmers seem to be better at switching contexts and adapting to change as they can quickly see the “outlines” of any problem and their techniques are about honing that initial perception into a functional solution. By contrast a Reasoning program is wary of uncertainty and is unhappy drawing unjustified analogies between different situations.
In FP terms Reasoning programmers have their behaviour emerge as a logical consequence of the operation of lower level abstractions; their code looks like algebra and domain data is passed in to the top of their processing chain. Intuitive programmers on the other hand, fix behaviour in their tests and fill their code with domain language that aims to match the natural language of the organisation, the depth of their function calls is usually smaller and they are swifter to bind calculations to intermediate variables.
I think I am an Intuitive programmer (and therefore I worry that I am miscasting Reasoning programmers through my lack of understanding) and in my work most of my colleagues are as well, it is in the nature of consultancy to have to adapt to constantly changing domains, code bases and expectations. We do have a few Reasoning programmers though who do exactly the same work but do it via thinking deeply through problems and drawing logical inferences.
If there are issues between the two groups then I think it occurs when there are no concessions between the two; common flashpoints being testing, writing defensive/guard code and giving time to discuss problems and problem solving strategies. The two also agree on a lot of things for very different reasons: for example both like to rewrite code, refactoring is a formalised practice for Intuitive developers whereas Reasoning developers often want to apply new insight or learned ideas (“This could all just be monads!”).
An important point is that neither approach is “right” both types of programmer arrive at the same results if their experience, ability and other factors are equal. They are purely styles of working.
Love this post, thanks for sharing this.
We’ve had lots of conversations in the past at our shared employer around “business” developers versus “language” developers but it always left me a little bit cold – “business” tends to be used in a pejorative way even when caveated with “some of my best friends are business developers”.
The distinction you have drawn based on observed behaviour of a number of different languages and language paradigms is a really useful one.
Hey, thanks for writing this up. I just did a google search for ‘intuitive programmer’ and the results were surprisingly sparse. It just occurred to me today that I have a different style of coding that gets me ‘in the zone’ – I flit from idea to idea and build up the solution in a totally non-linear way.
I haven’t put all my thoughts together on the matter but it seems to have a big impact on how I should think about pair programming (should I even bother?) and about comparing myself to other coders.
Anyways, I’m glad to see someone else verbalize this idea at least. I will have to post my own article about it once I have thought about it some more!
Classic example of the Perceiving vs. Judging personality types at work (MBTI system). Most commonly INTP vs. INTJ. Not really doing the same thing, but appropriately combined, possibly yields the best results.
I was just going to write something similar; however, I do not believe it is so simple.
Over 12 years in development, I have primarily seen introverted Ts of the non-intuitive variety. The NTs easier to find in this profession than most, but they are still greatly outnumbered.
Honestly, I think STP fits the OP’s definition of “intuitive programmer” much better than NTP. I am an INTP, and while I approach programming with spontaniety and intuition, the code I produce very closely matches his description of a “reasonable” coder’s code. That’s the N in me, exploring theory and seeking beauty in logic, abstraction, and efficiency. Domain language is so boring. Business logic is that trivial stuff I use to validate the completeness of the underlying code.
I would agree, in this case my meaning of the word intuitive is closer to the meaning ascribed to “Sensing”. I guess if I had to imperfectly pack this into Myers-Briggs I would say that my idea of an intuitive programmer is xSTJ.