Computer as she is spoke
I've just finished giving a session of our Advanced Rust training at
$DAYJOB. Overall I felt confident, the trainees were actively participating, and I think I could answer most of the questions I was asked accurately and helpfully. There is, however, one thing I'm frustrated I could not answer properly. The one question they kept coming back with was: "How do we know what is a good or bad way to express <pattern> in Rust?".
The first answer I came up with was: experience. I knew a good way to express what they wanted in Rust, and I knew it was superior to other ways to try to do it, but oftentimes, I could not express why, nor could I give them a general decision rule.
This reminded me of a viral post making the rounds about the order of adjectives in English. If I tell you that I am a lovable tall twenty-something blond-haired Belgian man, I would lie to you, but you wouldn't find anything too shocking about my statement. On the other hand, had I told you that I was a Belgian twenty-something tall blond-haired lovable man you may not need to know me for it to ring fishy.
These two sentences are grammatically correct — at least at a "low level" where they are both composed as a subject, verb, multiple adjectives referring to the noun completing the verb, and finally the complementing noun itself. Yet, the first one sounds better, more idiomatic. That's because in English, adjectives have a (somewhat) defined order which goes as follows:
- physical quality
Most English speakers are not conscious of this rule and yet abide by it. Indeed, if your experience of school was anything like mine you may have learned the formal rules (the grammar) governing your native tongue many years after you started abiding by them entirely unconsciously. We often think of our mastery of a language as a two steps process (though these two steps are admittedly highly overlapping): we can understand it before we can speak it, or rather we often understand it much better than we speak it. I would like to propose a third step or level, that comes after these first two: the ability to understand and express the rules governing a language. This study of the language and the description of the rules governing it are done by grammarians (or is it linguists? I'll call them grammarians). What I want to argue here, is that programming languages are very much like natural languages and can be studied in a very similar way.
So far I have mostly referred to the rules as "governing" a language. Tongues — save for a few exceptions have overwhelmingly existed long before they were studied, and formalized. Countries have standardizing bodies that try to unify the languages (not unlike C has had), but those are created way after their object of study was. In this sense, grammar laws "govern" our languages much like the laws of physics "govern" our daily life. They exist before being studied and are merely there to be discovered, not decided.
At a low level, programming languages are very different. When we think of the grammar of a programming language, we think of its place in Chomsky's hierarchy, or how easily it can be parsed. Languages have often been crafted from the get-go to ease their parsing by programs. Contrarily to natural languages, at such a low level, the grammar rules have been decided not discovered. They define the language, not the other way around.
Abiding by these rules is enough to get a program to be accepted by the parser, but it does not necessarily mean that the program will compile (for example it could fail to type check), work, or be easy to develop. Experienced developers know rules that guide them when they write code, often unconsciously. I know that trying such or such pattern from the world of OOP in Rust will fare poorly but I am at a loss if asked to explain why. Much like I speak French without thinking about why I am conjugating in this or that way, I only go back to the programming rules I know when faced with something that does not come intuitively, and I am sometimes completely unable to explain why I choose to formulate something the way I did, even though I agree with other speakers that such is the proper way to phrase it.
There is certainly an argument to be made that experience is the only teacher and can not be packaged in words and abstract descriptions and transferred to somebody else. Monads may be burritos to you but only because burrito is how you remember the struggles that brought you to the final enlightenment. After all most of what I learned, I learned by reading code, much in the same way that I learned French by hearing it around me. But even French pupils in school learn the language's rules and sometimes have to resort to actively thinking about them to speak correctly.
Design patterns are kind of the higher-level grammar of programming languages but I find the discussion around them to be very prescriptive. I think I wish we had discussions more about studying the style of different programmers, or groups of programmers, explaining why such patterns work well in one language but poorly in another. In a way, I think that the discussions I'm exposed to around design patterns do not allow me to grow through the three stages of shuhari (or what I understand them to be). I wish we would study programming more like we study other forms of creative expression. No one would pretend to tell you how to write a novel, compose music, or create a dance. They would describe to you what has been done by others before you, and you would build your style from this. I feel like currently, we are both overwhelmed by a highly prescriptive discourse on how things must be (a "how" which amusingly changes faster than I can keep track of) and at the same time severely lack the language and tools to speak about programming style.
I'm not sure where this brain dump is going, but I have not written in more than a year here, so I guess it's not like I'm nuking my usual post quality by putting this out there. I hope you found this analogy interesting nonetheless.