(last edited on September 20, 2014 at 3:58 pm)
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.
Anyway…
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
- Algorithms
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.
to
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.
3. Algorithms
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.
Concluding Thoughts
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.
11 Comments
Wow. It’s like comming up for air, and bringing up pearls.
Hi Dave,
Great post!
Learning a language is all about application and feedback.
If you don’t apply what you learn you lose it pretty quickly. If you don’t get feedback you have no idea that you are doing it right.
This applies to both the computer language and human languages.
Other factors are time and media. If you or I loved talking as much as we do writing, I’m sure we’d be podcasters as much as bloggers.
If you are anything like me I’d imagine you are more comfortable with computer languages because they lack the need for oral and aural discipline.
Best regards
Dan
Whoa.
I’m not a programmer myself, so I think I’ve learnt more about it from your post than in all the years I’ve lived.
You put it in nice frameworks, easy to get language and analogies for a layman like me. Great post!
My thoughts on the language thing. I’m a Chinese guy from Singapore, most people here speak English and their mother tongue. The Chinese here usually speak a dialect too (I guess it’s the same in the US?).
But me, I’ve always failed miserably in Mandarin. But my English has always been top-notch, no problem there. A bit messed up, huh? When I was a teen, I started learning Japanese, and there was no problem there either. I picked Japanese up faster than my own native Mandarin!
A bit later I had to take French in school, failed miserably again. While my Malay studymate friend displayed amazing skills in it, to the point where he’d be able to guess correct answers in advance to stuff we hadn’t started on yet. It was freakily uncanny.
What it feels like is that everyone seems to have an affinity of some sort for a language. Short of having a past life as that native speaker I don’t know how to explain it. English and Japanese came to me easily, and they felt right, where Mandarin never felt like it fit at all.
Each language does have its own subtleties, and I notice there are certain thoughts I can express in one and not the other (it doesn’t translate well). Also, each language, like you pointed out, comes with its own set of cultural assumptions. There’s no way to really speak Japanese if you don’t fit into their culture. Maybe that’s part of it as well.
Dave, I think you’ve struck on something very interesting here.
I’d say that initially, learning a foreign language (let’s take Spanish for example) is significantly more difficult than learning something like HTML. The reason I would say this is because HTML is still based on English; while HTML clearly does not follow English grammatical or syntactical patterns, the use of some even basic English words could help the student feel more comfortable and familiar with this language. When you learn Spanish, however, you’re thrown into a whole new battlefield where you must educate yourself from the ground up, doing everything from relearning how to say “blue” to integrating an alphabet with foreign pronounciations.
The initial language aside, however, I could very well agree that learning another Romance language would be comparable to learning a new programming language; the core is there, it’s just a matter of catching on to a new twist on known words and/or speech patterns.
Good thoughts, David. You present some interesting analogies between spoken/written languages and programming languages, and your observations on where the analogies work (and where they break down) are insightful.
Incidentally, the missing nomenclature that you’re looking for can be understood as “logic” and “rhetoric”. I teach in a classical school (these two subjects, actually) and find that these are often aspects of language that people take for granted until faced with the difficulty of learning other languages.
Logic can be understood simply as the study of the differences between structure and content. So, as you referred to above, we sometimes fail to recognize that understanding grammar (structure) and vocabulary (content) do not mean that we understand language. Logic is the foundation of how these two come together. (That’s probably why it is so useful for computer programming, as well.)
Rhetoric is essentially “effective communication” (as opposed to the more perjorative term that it has become in common usage). So the list you presented of the basic types of sentences you find in your blog describe categories of rhetoric, in a way. Studying rhetoric will help you speak and write more effectively, and it should help you better understand what others mean as well. Perhaps a poor analogy in programming would be the difference between Word and PowerPoint; both have the same general end-result—communicative output—but they are quite different tools in how they bring about that result. Thus, different tools for rhetoric.
To answer your initial question: “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.”
Te
You didn’t really mention language fluency. As you gain fluency in real world languages or in computer languages, it changes how you think about the world. The programmer term is ‘grok’, or to know something deeply.
In design terminology, certain designs afford certain actions. A door knob affords twisting, a handle pulling. In the same way different languages, both real world and computer, afford different styles of thought. You can make a literal translation of a given phrase, but as babelfish teaches us, that usually leaves much to be desired.
In the same way, you can program Java in Python, but you’re working against the affordances of the language. [1] Many great programmers advocate learning a new language regularly (e.g. once a year) because learning new languages means learning new ways to solve problems and this can make a big difference in how long it takes to solve them. [2]
[1] http://naeblis.cx/rtomayko/2005/01/20/getters-setters-fuxors
[2] http://wwwipd.ira.uka.de/~prechelt/Biblio/jccpprtTR.pdf
Development Environment is a bit of a misnomer, it usually indicates the OS, editor, server, etc that make up the space in which you code. A more proper term for the section would be ‘Language Community’ or ‘Language Culture’.
The laguages you’ve listed don’t have a really strong community/culture. I’ll admit that I haven’t done AS since flash 4 and I think the php community has one, but I’ve never run into it. I do know that Python (my preferred language), Perl, and Ruby have very strong, centralized communities. These communities are noticeable because they share common ideas on how problems should be approached.
These ideas are reflected in terminology, shared values (hack vs the right way, execution speed vs programming time, etc), and APIs.
Some examples:
In Perl, “There’s more than one way to do it” (TMTWDI) but in Python “There should be one (and preferrably only one) obvious way to do it”.
In Python, changing how library code works in your code is called “monkeypatching”, in Ruby it’s called “opening a class”.
Perl has ‘Perl Golf’, where the goal is to implement a program in the fewest (key)strokes. Python defines blocks by indention so everybody’s code looks the same.
I use Python in the examples because it’s the most different of the three (Ruby is a cleaned up version of Perl) and because I’m a Pythonista.
The most subtle and pervasive affect of the language community is API feel. As you gain experience in a number of languages, you begin to feel what languages inspired certain APIs. If you’re a Mac fan, you know what API feel is like. It feels exactly like somone takes a windows app (google earth?) and makes a straight port to Mac. The Mac community has repeatedly rejected this and rightly so, it just doesn’t feel right.
The same thing happens in Programming languages. Take DOM, for example, it’s from Java and it feels like Java regardless of the language that you program in (I’ve done it in javascript, java, and python). It feels wrong in anything besides Java. There are alternatives in both javascript (E4X, Mochikit.DOM) and Python (elementtree, Stan) that are far nicer to work with simply because the tree structure fits in with the language. In the Python case, I believe just about everybody has moved to the elementtree api over the DOM API, the javascript world is a bit fragmented.
In any event, I encourage you to learn more computer languages. Get on Rails, learn Python (TurboGears/Django are the rails equivalents in Python) and if you’re feeling adventurous, check out Scheme or Smalltalk (seaside). You may not want to actively program in any of them, but they will dramatically change how you think about programming if you understand them fully.
All: Thanks for all the fabulous posts! I’d like to add my specific comments later, but just let me say that they’ve all opened my mind. Thank you.
You mentioned that most programming languages can be summed up on a double-sided page. This would be the equivalent, I guess, of the small pocket or travel phrase books one can buy before going on a trip where you are not familiar with the language. After a few hours in the plane reading the phrase book, a few mistakes in the “development environment” (i.e. getting a cab/bus from the airport to the hotel, ordering a meal), you can essentially get by.
Just as these phrase books have been somewhat standardized (i.e. they all tell you how to ask where the bathroom is), I would love to see the programming language equivalent. A wiki devoted to quick, essential cheat-sheets or crib-sheets, where a developer could download, read it, practice a bit, make a few blunders and start doing some basic development. I am not pretending that one would become an expert developer in Java by spending a few hours reading and tinkering, but I think that the makers of those phrase books, or the Teach yourself XYZ programming language in 24-hours, are onto something.
On a second theme, I find that when I try to speak another language, native speakers are very gracious and encouraging. People seem to love it when you make an effort to try to communicate in their language and overlook the most obvious errors and mispronounciations and bad accents. Can the same be said of programming languages? In some cases perhaps. Sadly, in many cases, no. Ever spend a few hours trying to figure out some obscure syntax or just can’t find the right way to make your variables act the way you want, so you go to an online forum and ask? The answer, often helpful, is also often: RTFM. Not the most forgiving speakers of this language.
If anyone is award of such programming cheat-sheets, please, let us know!
On the theoretical level, there’s even more commonalities. When you get into application development and design patterns, you get so far away from the language that you see even more commonalities. Implementations of course vary, but the theory is very clear in all cases.
One thing you touched on indirectly that I wanted to bring up is the “skewing” your second, third, fourth languages tend to have. As I started a PERL junkie, my JavaScript has a very distinct flavor. Even with adding languages and additional ways to solve problems, there’s still that little .pl flavoring in there which people seem to pick up. One of my friends, despite being fluent in English still does all his math in Chinese. It simply makes sense to him.
Has anyone else experienced this in their programming- where sometimes a certain solution seems obvious not because it’s right, but because you are comfortable with the structure and style?
Although I come from the foreign language background I’ve observed the same experience with spoken languages.
A short answer is that in your brain your foreign languages are compartmentalized. So they are stored in different little pockets. They may intertwine in certain areas because of some relationship you have established or because they share similar traits.
However when working with different languages your brain has separated them in distinct areas allowing you to move between them without “going crazy”.
Once exception is when someone is raised multilingual or in a programmers case possibly learns languages simultaneously. That’s another story that I won’t go into unless someone asks.
BTW. I also wanted to comment on your observation of general fluency vs native fluency. I think you are dead on in saying that while you can communicate with a broad general group of people it is difficult to connect with them on an emotional level due to your lack of cultural understanding.
The same goes for your programming languages.
However, I think this can be overcome rather quickly through some blood, sweat and tears. If you’ve been in the trenches with someone, or in this case a language / culture, you quickly pick up on it’s nuances and personality. Thus allowing you to feel more natural or intuitive in your movements with them.