I’ve spent the past several days working on several programming projects, switching between Actionscript 2.0, PHP, SQL, and HTML/CSS. In hindsight, I’ve been deeper into the programming flow than I have in some time, to the point of being reclusive. The question on my mind: why haven’t I gone nuts from switching between languages?
My working theory: like most older programmers, I have that “deep structure” in my brain that is familiar with a certain family of common computer languages. As a result, I have a rather casual attitude toward programming in general: I don’t worry about it too much because I know I can figure it out. I can’t claim to be a master of any particular one, but I can get around without too much trouble.
On a related note, I have several friends who can converse in multiple languages like Italian, Japanese, and Russian. Learning foreign languages was something I was never good at in school, though I’d taken years of Mandarin Chinese and French. I thought I just didn’t have the knack for it, painfully aware of my awful pronunciation and grammar.
Thinking of my relative comfort with computer languages, I found myself wondering if there was some basic mechanism that applied to both programming languages and foreign languages. For example, if I can be comfortable with the broad family of C-style languages and concepts, perhaps this is analogous to someone comfortable with speaking a whole bunch of romance languages? Is there an exploitable commonality here?
FYI, I am not making the statement that a computer language is comparable to a full-blown spoken/written language, though I heard a story about a kid in my high school whose parents tried to get him out of the foreign language requirement in this way: they claimed that Pascal was a foreign language.
From my perspective there are three elements that must be mastered before you can consider yourself a competent programmer. These are, in no particular order:
- Computer Language Syntax and Grammar
- The Development Environment
1. Computer Language Syntax and Grammar
This is the easiest, most mechanical part of “learning” a programming language. There are usually only a few dozen keywords to know, a handful of conditional structures, a smattering of data concepts, and that’s it. You can summarize most computer languages on a single piece of paper (both sides).
I should mention that computer languages have one inherent advantage over real languages when it comes to learning them: the learning environment is the real environment (usually). You write the program, the compiler provides you rapid feedback about what you’re doing wrong, and you learn what each language element is capable of doing through practice. The grammatical patterns become ingrained with actual use.
I didn’t find this to be the case in high school. When I was learning French, the environment was synthetic and non-immersive. Even in English class, I had a terrible time with grammar because we learned it through pattern drills; this was utterly useless to me, because I am terrible at this kind of memorization. I did much better at intuiting my way around words; since I couldn’t remember any of the rules, I had to think whether what I wrote actually made sense. That was, to use a computer programming analogy, my “compilation” test: by reading back what I had written, I could visualize a piece of paper being “smoothed out”. If a phrase generated a logical confusion or ambiguity, that was an error that made the paper “rough”. When the paper felt smooth enough, I was done.
So the easy part of learning a computer language is getting those few dozen words down. The hard part is learning useful compound phrases. This is more than being able to throw out timeless nuggets like “Où est la salle de bains?”; the analogy in writing prose might be learning how to express an idea in a sentence.
Most computer statements can be very brief, but are in themselves are rather uninteresting. Compare:
The dog is red.
color.dog = 0xFF0000;
You can’t write an interesting essay out of simple statements like that; similarly, you can’t make a real program out of simple declarative statements (you’ve made a settings file, which is still useful). To get more interesting, you’ve got to have a few trusty phrases in your arsenal. I just looked back at my last two posts and came up with a list that probably covers 80% of the sentences I use:
- the setup statement, followed by hypothesis
- the observation, followed by interpretation
- the supporting list of facts, objects, whatever
- the clever closing line
- the breezy lightening remark
- the aside into silliness
- the sudden change of tone
- the run-on sentence to effect boredom
- the planting of an idea/phrase for later callback
- the callback
- the juxtaposition of disparate ideas
I’m not sure if this is “grammar”, but it’s how I think of writing. I start from the beginning, and deliver short lines of prose that hopefully convey information + insight, with a dash of personality.
In programming, there are certain constructs that express recurring ideas when strung together in just the right way:
- the conditional loop
- the branching control statement
- the iteration over a set of data
- the efficient initialization of complex variable types
- the conditional setting of variables
- the testing for anomalous conditions
- the dynamic allocation of resources
- and so on.
This is a level of complexity that’s just above simple declarative statements, but just below the implementing data structures and algorithms.
Moving up from sentences, we get into collections of sentences, then entire paragraphs that have some kind of point, and then entire essays that have some larger point, followed by longer works that have many points. And there are corresponding structures and approaches that work in all those cases. Programming is not that much different, from a certain altitude.
2. The Development Environment
Until you apply that language in a real environment, it’s just an intellectual exercise; computer languages aren’t very interesting unless they are used to actually do something. It would be like going to all the trouble of mastering French and never going to France, or at the very minimum talking to interesting French women, oui?
The modern development environment consists of approximately one zillion code libraries, each written by a programmer who is possibly crazy. The trick is to find which packages are absolutely necessary (because there is no other choice) and which are really really good. If you had to choose the breakfast cereal to base the next two years of your breakfast lifestyle on, with no chance of going back, you start to get the idea. The use of code libraries theoretically prevent you from having to re-invent the wheel. Back in the 70s and early 80s, re-inventing the wheel was easy because machines had less memory than a small desktop icon uses, but times have changed. For one thing, the Internet has made it possible to find all the other code libraries. Yay. Secondly, the increased sophistication of graphical, networked computer operating systems puts the modern development environment at about the same level of the Tax Code. Possibly higher, because the Tax Code doesn’t have showstopping bugs (we just call ’em loopholes and look the other way).
The real-world equivalent of the Development Environment is perhaps culture and society. While a lot can be traced back to basic human traits, every culture essentially has its own custom API, which is geek talk for Application Programming Interface. An API is a set of programming conventions that allows one fluent in a langauge to use a programming service. An example of such a service could be something like drawing a 3d polygon on the screen or making a connection to a database to retrieve a row of data. You use those keywords and programming fragments in the computer language to manipulate the API, therefore getting things done without having to do all the world yourself. Meanwhile, back in the real world, we have conventional procedures like “how to have a pizza delivered to your house in 30 minutes or less”, accessed through a standardized interface (the telephone) through the communication of a standardized protocol (“I’ll have a large pepperoni. My name is Dave. My address is Blah Blah Blah.”). Of course, in some parts of the world the idea of home pizza delivery is just crazy talk, so there isn’t an API that you can use. So you’re forced to do without, make your own pizza. Bummer! A motivated individual would create a new business to deliver pizza, which is not unlike a programmer creating a new code library to solve a problem. But I digress.
If “computer language” maps to “development environment” does “spoken language” map to “culture” in an analogous way? In other words, does being fluent in a spoken language necessarily imply a fluency in its associated culture? I don’t think this is the case…one can be fluent in C++ and understand, without a whole lot of trouble, the idea behind Java. This is kind of where I am with respect to computer language fluency. Analagously, one could be pretty fluent in Spanish and communicate with a wide range of Latino communities. I suspect you could even annoy many Puerto Ricans (“I’m not Spanish!”) in the process, and still they’d get the gist of what you’re trying to say.
Even with the ability to speak the language, you probably would not be able to engage with the society at more than a surface level. You are missing the history, the culture, and the sense of identity that comes from growing up with it. Looking back at programming, I could say the same thing about my knowledge of PHP. It’s part of the standard C++ like family of languages, which I speak, so I am not unlike traveller hopping from environment to environment. While I can’t claim deep familiarity in any of said environments (and by extension, the communities that have formed around them), I am conversant enough to at least orient myself and “find the bathroom”, so to speak.
In our rush to make things happen, we usually think of algorithms last. We want to make things now, and as neophytes tend to see only the surface.
Algorithms are ways of solving certain well-defined problems, and consist of a logical set of steps built on a flash of insight. At the level closest to implementation, algorithms are like cookbook recipes: follow the steps, get a nice cake. While I like cake, I am more drawn to the flashes of insight. I ask how did that flash of insight occur? Under what conditions does it occur? And how did it alter our fundamental perspective of the problem? The story of an algorithm is the Hero’s Journey, telling of difficult challenges faced in a series of real-world tests. The challenges met, the Algorithm returns home with results in hand, and the world is a better place for it.
In the real world, algorithms are the “way we do things around here”, what Neal Stephenson calls “the operating system of society”. In his cyberpunk novel Snow Crash, Stephenson referred to the Sumerian idea of me:
[…] the decrees of the gods […] that make civilization, as the Sumerians conceived of it, possible.
The decrees, as described in Snow Crash, were not confined to spiritual matters. They provided instruction on how to conduct civilization itself: when to plant the crops, when to bring in the harvest, and so forth. In today’s world, we don’t have things quite so cut and dried, but there certainly are “standard practices” that we have grown to take for granted, civillization as we know it: The bi-weekly paycheck. The 9-5 workday. The Home Mortgage. The Baby Shower. Team Spirit. These are ideas tied to our daily social experience, designed to solve certain problems, actively shaping our use of language with new words and expressions.
Aside: I’ll just mention that the idea of “languages shaped by experience” reminds me of Delphi, Python, and Ruby (computer languages all). Not that I know any of them, but in my mind that’s where I file them away (under: “computer languages, worth looking into someday”).
Understanding the totems behind societal (process) expectations is as much a part of the language as the world (dev environment). The world (dev environment) is comprised of the things we talk about (the hardware/software APIs programmers use). Societal conventions (algorithms) are what we do with them, in pursuit of fulfulling some role (making software that works).
Knowing the history of a place helps put things into perspective too. Take the study of modern idioms, for example, or “getting” jokes based on current events. In computer environments, we have expressions like “strings”, “ls”, and “reboot”; these have ancient roots that are a part of my foundation, and therefore color my understanding of computer systems. When I look at a computer, I see basically an overgrown version of my 8-bit micro. Sure, there’s more STUFF in it, but it’s still all memory-mapped I/O driven by a CPU that accesses banks of memory, its cycles scheduled by some kind of hardware interrupt mechanism to share the system bus with other coprocessors. And therefore, it does not scare me. Maybe it should, but it doesn’t.
I have no strong conclusions to share, but in summary this is what I was trying to say:
- I seem to be fluent in computer languages, and am able to move from language to language without too much stress. Why am I not going insane?
- I have never been able to pick up a real language like French or Chinese, for whatever reason.
Knowing a computer language by itself isn’t enough to be a programmer; there are at least two other areas that require study and experience. The sum of all three is what has lead to my “fluency” with programming in general (“best practices” born of experience might be the fourth).
Similarly, learning a language–say, Spanish–has the implication that there’s more to it than just the grammar and vocabulary. The environment, the culture, and the operating procedures are all part of the package.
The primary difference between learning a computer language and learning a foreign language is that I’ve had confidence in knowing what I’m dealing with. It’s easy to be overwhelmed by number of details, unless I know one thing: it’s just a computer. And I know exactly what a computer is. It is the same problem at a different scale compared to my old 8-bit Apple II, but the method of attack is pretty much the same.
So what is it that would give me the confidence in learning a real language, that I missed when I was a kid? Is there an insight that would make this into another kind of problem I know how to handle? Breaking it down into syntax, culture, and operating procedure and then re-integrating it into an immersive learning environment might be one way. Maybe just diving in and babbling, suspending all my foolish notions of being “being adult” so I learn how to make the sounds correctly.
p>Food for thought! Time to get back to work, though, to start plowing another field of code.