My perception is that currently the vast majority of computer programming related material available on the Internet focuses mostly on the technical side of programming. By "technical" I mean simply that many sites introduce you to the topics such as programming languages, utility libraries, general algorithms, editors, compilers, debuggers, version control tools, and so on.
While theory of computation, basic principles, practical implementations, and concrete programming tools are very important topics to learn, it is good to remember that programming is also a mental process.
As programmers, we strive to form logical thoughts in our minds and then we proceed to express them using different programming languages. The emotional side is also sometimes involved in programming. For example, when you work on critical code the correctness of which affects important infrastructure and possibly millions of users, the prospect of creating fatal bugs can cause fear and stress. On the other hand, if our project is just for our personal fun, then the possibility of introducing bugs, or botching releases in some other way, does not usually cause anxiety. Those are two examples of the psychological aspect of computer programming.
Using online material, you can learn for example about using VIM, GCC and GIT, but knowing those tools will not create any working source code for you. In order to write your own programs, your brain is involved. So clearly we are talking about your mind and mental processes. We refer to a Wikipedia article to clarify in broad terms what psychology means:
Psychology is the science of behavior and mind, including conscious and unconscious phenomena, as well as feeling and thought. It is an academic discipline of immense scope and diverse interests that, when taken together, seek an understanding of the emergent properties of brains, and all the variety of epiphenomena they manifest.
In school, we are often forced to learn things that do not interest us. Depending on a person's preference, it could be e.g. geography. When you get out of school, you probably have very little use for knowing facts like:
But I argue here that with psychology it is a different situation. Psychology should be as important to study as reading, writing, mathematics, logic and philosophy. Why is this so? Simply because for us human beings, our minds are almost constantly switched on. During the waking hours, we think and feel all the time. We go through emotions that influence our mood and even our behaviour. For instance, when you feel anxiety, that often negatively affects your ability to operate. But when your mood is better, you also perform better in general.
Psychology helps us to analyze our mental processes and make corrections to them. This is one of the main benefits of psychological research. The process of mental self-analysis is called introspection and it is definitely an important skill worth learning. Studying existing psychological results enables us to identify possible bugs in our minds that we might not detect on our own. That is what I have learned and hence I recommend studying psychology so that you are familiar with the basic results.
Note that even during sleep, many people enter a strange dream world that also involves mental processes, but it is not known what is the significance of dreams regarding human consciousness. Sigmund Freud wrote about dreams, but I consider his results too one-sided and pretty unscientific. His interpretation of dreams seems to serve only as a support to his psychoanalytic theories. The topic of dreams is very complex and we will ignore it in this article.
Only when we have lost consciousness, our brains are switched off. What I am trying to say is that in our everyone life we just cannot escape from our minds. There are mental processes running inside our minds, and this fact is what makes psychology an immensively useful, very generic branch of science.
It is of course clear that psychology is not among the so-called hard sciences such as biology, chemistry or physics, but despite that it is highly important. Many of the smartest people like Timothy Leary have worked in the field of psychology. In my opinion we should pay attention to the results that they have discovered even though admittedly the results are not as exact as in the hard sciences.
The reason for that certain vagueness concerning psychological results lies simply in the fact that human beings are rather complicated objects. I prefer to use the term "objects" here and avoid the term "machines", because even today, we do not know for sure why or how consciousness emerges. In the philosophy of mind emergent materialism advocates the stance that given sufficiently advanced hardware platform (e.g. human brain, large groups of neurons connecting to each other forming brainware) causes consciousness to somehow "emerge". However, the exact mechanism of this emergence is totally mysterious to neuroscientists, psychologists and philosophers alike.
American philosopher Daniel Dennett has written a book called Consciousness Explained. It was first published in 1991 and in that book Dennett argues for emergent materialism. As far as I can remember, his model of a human brain is that it is simply a Universal Turing machine running in several parallel threads. Based on the theory of computation, we know that adding more tapes to Turing machines does not expand the set of computable functions, so a parallel Turing machine is computationally equal to a Turing machine having just one single tape. Nevertheless parallelism increases throughput of the system with respect to time, so having multiple threads would allow human brain to process information faster, and to handle input data from multiple sources concurrently (i.e. to process incoming data from our eyes, ears, skin, etc.).
In Dennett's book, there is a hilarious comics part where a scientist explains how emergent materialism is supposed to work. When the scientist arrives at the point where he explains how the consciousness actually emerges, he just writes on a blackboard:
"...and then a miracle occurs."
So Daniel Dennett is a very honest and smart person. Daniel knows well that his proposed model does not really provide a detailed explanation. His model is more of a form: "This is how it has to happen, because I cannot think of a better alternative. But I do not have the exact details, sorry about that!"
Despite the lack of details in the explation, the case for emergent materialism is still pretty strong. Just think of Alzheimer's disease. It causes serious physical damage in the brain, corrupting the brainware. After those changes have taken place, we can observe in several patients that their personality has changed too. It is quite possible that after having been diagnozed with Alzheimer's disease, a person who was previously friendly and easy-going, becomes very evil and even violent. We cannot predict the exact consequences of brainware corruption, but we can observe dramatic shifts in the mental processes of Alzheimer patients.
Very strictly speaking, if we apply only logic, there is no absolute certainty that this is an instance of cause-and-effect. Resorting to an extreme form of skepticism we could be perfectly logical and imagine a possibility that some parallel, unknown phenomenon has taken place during the same time window, and brainware corruption and the mental changes have no cause-and-effect relationship at all.
But thinking realistically in the spirit of empirical science rather than pure logic of modalities, I suppose we must admit that Alzheimer's disease is what causes the personality changes. If so, what does it prove? I think it proves that changes in the brainware can in certain cases cause changes in the mind. But it does not prove that the cause-and-effect chain must always be unidirectional in all cases. It is indeed quite likely that the mental processes can also cause changes in the brainware. Are there any examples of that?
Think of a person who is going through a rough patch in his or her life. Let's say he or she has lost a job, and is depressed because of that reason. Now it makes perfect sense that that mental state, caused by losing the job, may be reflected in the brainware's state. I am not a neuroscientist and do not know the exact workings of brainware, but just for the sake of argument, we could say that the serotonine or dopamine levels are lowered in the brain.
In this awful age of materialistic medicalism, uninformed psychiatrists and psychologists would probably take blood tests from the patient, inspect serotonine and dopamine levels, and conclude that they are lower than on average. Then they would prescribe some kind of mental medication to the depressed patient, saying: "Start taking these new expensive pills and your depression will be cured". But the real cause of the patient's depression was mental and caused by losing a job.
Instead of using medication and trying to solve the issue on a brainware level, this depression case should have been handled using psychotherapy (i.e. discussions with the patient) and not by prescribing mental medication pills. However, greedy companies that manufacture mental medication products want to sell them in large quantities. It is actually very profitable business for them. It is alarming that many psychiatrists support that business by "curing" mental problems using chemicals in cases where that is clearly a wrong approach.
A nice analogy for demonstrating the insanity of the current psychiatric methodology is the following. Suppose we have a bug in our C program. We know where bug is and know that we could fix it by changing the C code a little bit. Then we would recompile the program. But the uninformed psychiatrists would tell us that our C program bug must fixed by manipulating the RAM circuits in the physical computer hardware and the fixes should be done by altering electricity in the circuits.
But let's not go deeper into that topic so as not to deviate too much. I am very worried about this trend, though.
So far we have provided some background information in order to stress the importance of psychology in general. We have also tried to show you that the relationship between mind and matter is a difficult, unresolved issue. The mind and consciousness just might live in the abstract realm of Platonism, in the same universe with numbers and other abstract objects. But the brainware is part of material world.
It is evident that we cannot solve the well-known dualism problem here, but suffice it to say that respected scientists like Albert Hofmann have argued that psychedelic drugs could well constitute "cracks in our material reality". Thus one logical way to solve the old problem of mind versus matter, and dualism in general, could be the surprising realization that there is really no dualism at all. Instead everything we experience is mental - that is all there is. That line of thinking would be a valid alternative ontology opposed to materialism.
Our introduction was possibly too long for some readers, and we do admit that we occasionally perhaps sidetracked, too. But we defend this approach by arguing that it is probably better to be too detailed than to leave relevant things unexplained.
After all, if you think that psychology has no relevance to programming, or even that it is a totally useless subject, then getting extra information just might convince you otherwise. In any case, let's finally continue with the main topic of psychology of computer programming.
When you want to create a computer program, your mind is activated.
Before and during the second stage I guess most people use their own mixture of top-down and bottom-up principles. To create a large program, it is necessary to sketch out the overall structure in some detail - this is the top-down method. The bottom-up method, on the other hand, prefers to start by writing some code first, with the intention that the overall structure will eventually become clear after you have written something that could be needed in the larger whole. The bottom-up approach somewhat resembles the workings of evolution in nature.
According to Wikiquotes, a famous hacker Ken Thompson, the original inventor of Unix operating system has said:
I am a very bottom-up thinker. If you give me the right kind of Tinker Toys, I can imagine the building. I can sit there and see primitives and recognize their power to build structures a half mile high, if only I had just one more to make it functionally complete. I can see those kinds of things.
Ken Thompson's words are a clear indication that programming indeed requires analytic thinking and that means that psychology is involved, too. I am not an expert in psychology, and I do not have that much knowledge about the workings of our minds, especially when it comes to programming. That is why I have adopted a different approach in this article.
Back in 1971, Gerald Weinberg published a very useful book called The Psychology Of Computer Programming. I bought a hardcover edition some years ago. This is what it looks like:
In the rest of this article I am just going to show you some of the results that Weinberg presents in his book, with my own comments added where I consider them necessary.
What about the validity of Weinberg's results? The Psychology Of Computer Programming was published decades ago. The field of computer programming has changed immensely if we think about the computer hardware and software.
For one thing, in 1971 there were no home computers in existence. The practice of programming was available only to special experts and selected few computer scientists who had access to mainframes and smaller computers. There were not so many programming languages and tools were also primitive compared to the software that we now have in 2018.
It is true that the technical side of computer programming is not the same anymore. Nobody can deny that. But remember that the topic of Weinberg's book is The Psychology Of Computer Programming. His focus is mainly on mental processes and not on the irrelevant details like whether our target hardware has 64KB or 96GB RAM available. I know quite well that this book even mentions punched cards in some of the examples, but that fact does not concern the topic of this article.
I believe that human minds have not in general evolved that much since 1971. If that assumption is mostly correct, then I guess we can be confident that Weinberg's psychological remarks are still valid today. The basic principles of programming are also pretty much the same now as they were in 1971, but of course there are differences, too.
Before we continue, it must be noted that I will not attempt to give a totally comprehensive analysis of each and every aspect of this book. Doing that would in essence amount to repeating the whole content in my own words, and that would make no sense. It would also take too much effort. If Weinberg's book interests you a lot, I hope you can borrow it from a library or buy your own copy - perhaps second-hand if it is not available as new.
I actually just discovered that Weinberg released an updated edition in 1998, so you should probably go for that version. But I have not read it, so this article is only about the first edition.
In my opinion this book is not an absolutely fabulous masterpiece, but it does contain much wisdom and numerous helpful lessons. The Psychology Of Computer Programming is also probably the first to even attempt analysis of the psychological side of computer programming. We must give Weinberg lots of credit for his unique approach. He is among the pioneers in the field and his book is a very important contribution to the pool of scientific knowledge.
My modest goal here is just to pick some pieces that I think could be interesting and useful to the readers. So let's get started with The Psychology Of Computer Programming.
On page 28 Weinberg tells us of a case where one of his students had problems with a PL/I program. It was a classroom assignment and the student's difficulties were related to one particular line of code that seems complex. The student finally managed to get it right, but rather than leaving it at that, Weinberg asked the student to write down the thought process that he went through when facing the problem.
The student's list contains 5 entries describing what the difficulties were. One of the difficulties was just that there were so many parentheses that it was difficult to balance them. In those times the text editors had very few features - nowadays balancing would be easy, but that does not invalidate the psychological point. Weinberg writes:
However, even though we must start with the introspection, we cannot stop there, for then we would be practicing magic or religion, not science.
His conclusion is that even though this particular student had problems with, say, 5 levels of nested parentheses, we cannot deduce from it a general scientific law that 5 nesting levels should never be exceeded. This is self-evident, but worth mentioning. However, I guess analyses such as the one mentioned here can clarify and reveal individual's limits and thus they are useful to the people who do introspection.
This book is not limited to individual psychology, but also comments on social psychology, meaning relationships between human beings. Starting on page 47, Weinberg says of groups:
The study of the programming groups is important for an understanding of the other types of programming organization. Even when there is a formal organization of the programmers into teams and projects, informal connections arise much as they do in an "unstructed" group. Indeed, the first lesson we must learn from social psychology is the difference between formal and informal groups.
He then adds:
Many serious mistakes have been made in imagining that formal structure was the only structure in an organization. […] in a computing center, even if it is completely at the service of the individual programmers, an informal structure always grows to correct and complement the work of whatever formal structure exists. Sometimes, if the powers-that-be are sufficiently wise, innovations in the informal structure can be implemented formally, although not always as exact equivalents.
Nowadays we can have groups of individuals working on shared software projects, but because of Internet, the collaboration can happen using mailing lists or common programming websites. But the group structures could still be there, and it is important to remember good manners and politeness in communication.
I have a very fitting example here. Just a few weeks ago Linus Torvalds reached the next plateau of his enlightenment. After having received complaints, Linus finally realized that his messages on the Linux Kernel mailing list have not always been very appropriate. Personally, I do not care about swearing, but personal attacks are not acceptable.
Linus quite honestly publically admitted that he has made some mistakes in his social life, and promised to correct those mistakes. He said he is going to take a short break from the Linux Kernel project and come back soon with a new, better attitude.
This is a very remarkable case showing what kind of changes introspection can be bring. He said something like: "I am not a very empathetic person, but I am working on it.". So clearly he had examined his inner mental processes and personality features in order to improve them.
It has been clear for years that Linus has fantastic technical skills, good taste and very logical mind, and now he is taking steps to improve his social skills. We have to respect him for that. I have had similar social problems in the past, sometimes using language that is too outspoken or even rude.
In my opinion the most valuable and applicable teaching in Weinberg's book is about egoless programming. On page 53 he writes:
Although [programmers] are detached from people, they are attached to their programs. Indeed, their programs often become extensions of themselves - a fact which is verified in the abominable practice of attaching one's name to the program itself - as in Jules's Own Version of Algol, better known as JOVIAL. But even when the program is not officially blessed with the name of its create, programmers know whose program it is.
That remark seems as true today as in 1971. Weinberg goes on to explain why attaching to programs could be bad:
Well, what is wrong with "owning" programs? Artists "own" paintings; authors "own" books; architects "own" buildings. Don't these attributions lead to admiration and emulation of good workers by lesser ones? Isn't it useful to have an author's name on a book so we have a better idea of what to expect when we read it? And wouldn't the same apply to programs?
Weinberg then argues that if people actually read programs, then the reasoning could be valid, but he says that they do not read them.
That was probably true in 1971, but in this respect the book is outdated. In the current era (it is now 2018), programmers have access to perhaps even millions of software projects that are either open source, free software or both. I am not sure about the exact amount.
Developer sites like github.com enable us to read as much source code as we want. There is no end to it. So nowadays people actually do read lots of source code, although that fact naturally applies to programmers only - the general public does not read source code, for the very obvious reason that they cannot understand it.
However, I think his next point is still valid:
The real difficulty with "property-oriented" programming arises from another source. When we think a painting or a novel or a building is inferior, that is a matter of taste. When we think a program is inferior […] that is a matter of at least potentially susceptible to objective proof or disproof. […] When the computer revealed a bug in his program, the programmer would have to reason something like this: "This program is defective. This program is part of me, an extension of myself, even carrying my name. I am defective.". But the very harshness of this self-judgment means that it is seldom carried out.
Weinberg then explains the familiar basic concept of psychology called cognitive dissonance.
A bit later he asks "What is to be done about the problem of the ego in programming?". He then writes that changing mental attitudes is possible and that it has happened since the earlier days of computing. Weinberg brings up a convincing example:
John von Neumann himself was perhaps the first programmer to recognize his inadequacies with respect to examination of his own work. Those who knew him have said that he was constantly asserting what a lousy programmer he was, and that he incessantly pushed his programs on other people to read for errors and clumsiness. Yet the common image today of von Neumann is of the unparalleled computing genius - flawless in his every action. And indeed, there can be no doubt of von Neumann's genius. His very ability to realize his human limitations put him head and shoulders above the average programmer today.
This piece of information is important. We get to learn an interesting fact about John von Neumann, one of the most intelligent human beings who lived in the 20th century. Based on von Neumann's immense achievements in several fields of science, we could indeed erroneously suspect that he might have been self-centered and even excessively proud of himself.
But according to Weinberg, this genius was constantly criticizing himself. Apparently that kind of attitude enabled him to keep progressing and stay humble despite his tremendous logical abilities.
Weinberg's following example, however, is not about any well-known superstar of science, but rather it is an account describing the attitude of a more ordinary yet very skillful programmer. The following quotation will be pretty long, but I do not want to shorten it, because Weinberg has chosen his words well:
Consider the case of Bill G. who was working in one of the space tracking systems. His job was to write a simulator which would simulate the entire network of tracking stations and other real-time inputs. His system had to check out the rest of the system in real-time without having the worldwide network on-line. The heart of the simulator was to be a very small and very tight loop, consisting, in fact, of just thirteen machine instructions. Bill had worked for some time on this loop and when he finally reached the point of some confidence in it, he began looking for a critic - the standard practice in the programming group.
Bill found Marilyn B. willing to peruse his code in exchange for his returning the favor. This was nothing unusual in this group; indeed, nobody would have thought of going on the machine without much scrutiny by second party. Whenever possible an exchange was made, so nobody would feel in the position of being criticized by someone else. But for Bill, who was well-schooled in this method, the protection of an exchange was not necessary. His value system, when it came to programming, dictated that secretive, possessive programming was bad and that open, shared programming was good. Errors that might be found in code he had written - no "his" code, for that terminology was not used here - were simply facts to be exposed to investigation with an eye to future improvement, not attacks on his person.
In this particular instance, Bill had been having one of his "bad programming days". As Marilyn worked and worked over the code - as she found one error after another - he became more and more amused, rather than more and more defensive as he might have done had he been trained as so many of our programmers are. Finally, he emerged from their conference announcing to the world the startling fact that Marilyn had been able to find seventeen bugs in only thirteen statements. He insisted on showing everyone who would listen how this had been possible. In fact, since the very exercise had proved to him that this not his day for coding, he simply spent the rest of the day telling and retelling the episode in all its hilarious details.
Weinberg then explains that Marilyn in turn asked for help to criticize her analysis, and with team work three more bugs where found. The author also informs us that the final result was positive. After the team had corrected the bugs, the simulator was used in more than a dozen installations for over nine years without any errors.
He goes on to say that this is not an isolated case and that programming groups like this do exist. Next he asks an important question:
Why, then, are such groups not more conspicuous? Why is the practice of "egoless programming" not more widespread?
According to Weinberg, the idea of this practice being rare is partly just an illusion based on lack of real knowledge about current methodologies. He reveals that many successful software companies are indeed using egoless programming, but that fact is kept as a proprietary piece of valuable information. So it is very much a secret method that companies prefer to keep to themselves in order make their own software quality better.
Weinberg does not elaborate that point further, but it is obvious to me that these companies do not want others to know about egoless programming, because in the commercial world based on capitalism, that would benefit their competitors. In other words, egoless programming would also enable the competitors to raise their product quality.
That would of course create more fierce competition in the softmare market and companies never want that, because they want to sell their own products to maximize their own monetary income. This is a basic fact of capitalism that applies not only to software companies, but I guess to almost all companies.
The author then offers another possible reason:
Secondly, groups working in this way tend to be remarkably satisfied and stable, so that the programmers we find wandering from installation to installation are not likely to have come from such a group. Moreover, these gypsy programmers - to achieve a constantly escalating salary range - must encourage the myth that the best programming is the product of a genius, and nothing else.
The book also says that at the time of the writing, there is not much research that has focused on comparing egoless programming and the "traditional" programming based on the mythological geniuses doing their work. I suppose that information could be outdated even though it was true in 1971. Weinberg also mentions that in any case the comparisons are difficult, because measuring facts like these is not exact, and it is not entirely clear how the experiments should be conducted.
I mentioned in my lengthy introductory sections that psychology is, by practical necessity, a somewhat vague branch of science. This is because we are dealing with human beings and we have to account for many factors in experiments. This is probably an example of that kind of vagueness. We cannot conclusively prove that one method is always better than another, because things might be different for different people and groups. But it does seem that egoless programming could be a path to a certain kind of enlightenment and wisdom.
Despite that, I am fully aware of the fact that some programmers insist on working alone, and it is not my intention to push egoless programming method to those who do not find it comfortable or useful. However, in these days most notable programmming projects are so large and complex that working in isolation is not often possible. That is why psychological issues and attitudes enter into picture. Now in 2018, it is possible that programmers work in their homes, being physically isolated, but using Internet they now have access to chat systems, email and programming forums.
So the people who you ask to evaluate and criticize your code do not have to be in the same room with you. To take a practical example, you could create your own fork of a project, create your branch using a version control tool such as git, write your part of code, and then push your branch to github.com for others to see. The maintainers could suggest some changes, you would evaluate their request, make changes and corrections, and push your changed branch for re-evalution. This process could repeat for several steps if necessary.
I am not entirely satisfied with this brief exposition of Weinberg's psychological results. While I personally think that the concept of egoless programming is by far the single most important insight in The Psychology of Computer Programming, that book admittedly contains other valuable information that I have omitted. Fortunately nothing prevents you from reading the book by yourself. If you choose to do so, it is likely that reading the revised edition is the best choice, because it must have lots of updated information and examples.
The reason for omissions is mainly my own impatience. I currently have several interesting projects in my TODO
list and I have to schedule and allocate my mental resources the best way I can. This means that I have limited time to re-read The Psychology of Computer Programming. I still hope this article will be useful to many readers.
In conclusion, I personally think that egoless programming is a psychological principle that:
I suppose that once you have overcome the initial mental barriers (such as fear of presenting bad code for others to analyze, and then being embarrassed when errors are found), egoless programming should be pretty easy to put into use. Despite that, it might not happen instantly.
It is my understanding that egoless programming often requires a major shift in our attitudes. Like Weinberg said, if you feel that your code is an extension of yourself, you may have difficulties accepting criticism concerning the quality of your code. But on the other hand, if you feel that code is just code even though you worked hard to write it, then your attitude is clearly more relaxed. That probably means you will be more receptible to constructive criticism. You will realize that your peers criticized the code, not you as a person.
If it worked for John von Neumann, why should we not at least give it a try? He was a genius, after all.
Note that adopting the "code is just code" attitude does not mean that the correctness and quality of the code no longer matters to us. On the contrary, egoless programming asserts that code quality is extremely important. It is not a license to publish bad code simply because the other programmers are expected to catch our possible mistakes during the code review.
Egoless programming is just a psychological attitude towards programming. According to my understanding, the two main benefits are:
To sum it up, I am not claiming here that egoless programming is some kind of a miracle cure for all software development problems. But it appears to be a very central, basic principle that really affects the everyday life of programmers. I know adopting this method has worked fine for me.