While working with people who write code I keep noticing three vaguely defined but nonetheless distinct "roles", or "styles of thinking", or "behavioral patterns", or "skill sets" — I don't really know how to call this classification per se, but I came up with a descriptive name for each class.
I wonder if other people had similar impression.
Scientists research the field before starting to write code, devise a mathematically correct solution and then try to implement it as true to the model as possible. Along the way they don't care about readability, maintainability, performance or architectural beauty and usually end up with a mathematically correct spaghetti code. Which is not to say that it is immediately usable because scientists hate to work around ugly real-world cases that don't fall perfectly into their model.
Their understanding of things is based on scientific proof rather than on intuition which allows them to solve extremely complex problems where human intuition doesn't work well.
They are good at math and seriously consider it a perfectly understandable language to explain their solutions to others.
Engineers work by iteratively cooking up an imperfect but working solution and improving it watching how it behaves. They consider the solution "correct" when it complies to tests covering an arbitrary subset of use cases. Though they actually use the word "correct" as a shorthand for "ready to be made even more correct". Likewise, when they say "all" or "nobody" they usually mean "most" and "few".
To work with the notion of correctness as a process, rather than a state, they care very much about programming languages, tools and coding methodologies to produce beautiful maintainable code.
While trying to explain their solutions to others they tend to drown in the details of implementation precious to their heart, losing the big picture and skipping reasoning.
Teachers aren't as fluent in the realm of formal logic as scientists are, nor can they achieve the magical level of craftsmanship endemic to engineers. They are usually content with the broad understanding of how things work and quickly lose interest in endless refinement of a product to perfection, preferring instead to learn something new.
The unique skill of teachers is empathy — the ability to step into another person's shoes and understand how they think. This makes them able to explain things to other people, as well as understand explanations made by scientists and engineers. They are good at teaching (obviously) but also at writing documentation, talking on behalf of the team and hiring people.
Teachers posses a specific feeling of how much they can get sloppy with facts and deviate from truth to achieve better understanding of their explanation.
An ideal start-up team consists of a scientist and an engineer whose strengths and weaknesses complement each other very well. They don't need a teacher from the start simply because there's no one to teach yet.
A team of scientists starts building a system with a barely useful but already complicated implementation, while a team of engineers starts with a simple ("lightweight") code base that mostly works but probably has drastic data-loss bugs all over the place. Both teams evolve their systems: scientists make it easier to use while engineer cover remaining use-cases. Over time their systems become pretty much functionally equivalent but engineers still have the advantage in that their system becomes usable sooner.
Scientists are invaluable to engineers because they can prove that something just can't exist and save engineers from desperately chasing an unrealistic ideal. A good example is a CAP theorem that finally relieved engineers from trying to build 100% consistent and 100% available distributed systems. They probably still need teachers to explain this to management.
Mixing of skills
As in role-playing games, these roles are by no means mutually exclusive: they are inclinations rather than limitations. A really experienced scientist can be a better engineer than a "natural" engineering rookie.