My non-programmer friends and relatives sometimes ask me:
Why are there are so many different computer languages?
My co-workers sometimes ask me:
Why are there so many reference books for obscure languages on your bookshelf?
The answer in both cases turns out to be the same: Language matters. The language you use affects how you think about a problem. Psychologists and Linguists (and Politicians and Salesmen) have known about this for years as it applies to human languages, and it turns out to be true for computer languages as well, of course.
I was reminded of this fact just today, as I was explaning some concepts in Object Oriented Programming to a co-worker who’s just coming up to speed on C#, after using mostly C and Perl for several years.
My own first exposure to Object Oriented Programming was back in the (very) early 90’s, with Borland and Microsoft’s C++ compilers. I’m not sure I ever really “got” OOP in C++, and neither did most (all?) of the people I worked with. We mostly just used C++ as a better version of C.
Fortunately for me, I managed to snag a copy of Digitalk’s Smalltalk for Windows not long after that. And suddenly, it all made sense!. Because the Object-Oriented nature of Smalltalk is so “in your face”, you can’t help but start thinking about things in a new way. The version I got came with pretty decent tutorial info as well, which was also a big help.
I never actually produced any large-scale software in Smalltalk (it was impractical for work projects in terms of performance), but the new way of looking at things stuck with me as I continued to write low-level bit-banging code in C. When I came out to California and worked for NeXT, my Smalltalk experience translated, more or less directly, to Objective-C.
Anyway, back to the discussion with my co-worker. There are a couple of different ways of thinking about “using objects” that I’m familiar with, and I tend to think of them as “The C++ way” and “The Smalltalk way”. In some sense, this isn’t entirely a fair characterization, but in my experience, the two views are more-or-less endemic in their respective programmer communities, so that’s how I think of them.
The C++ view:
An object is a combination of some data, and functions that operate on that data. To perform some action, you call a member function of the object instance that has the data you need to work on.
The Smalltalk view:
An object is a model of some part of your problem domain, and each object has its own set of responsibilities and capabilities. To cause something to happen in your program, you send a message to an object, which may in turn send messages to other objects.
Now, it turns out that these two definitions are actually equivalent, or at least compatible, despite the fact that the C++ definition is entirely focused on the implementation detail, and the Smalltalk definition is entirely focused on the semantics.
When you get right down to the low-level implementation details, “sending a messsage” and “calling a member function” are really the same thing. A couple of CPU registers get loaded with a couple of addresses, and then you jump to a subroutine. Yes, I know it’s more complicated than that in the real world, where you’ve got vTables, and dynamically-compiled methods, etc, etc. Work with me here…
The C++ programmers that I’ve met usually come to C++ from a background writing software in C. Because C is such a very low-level language, it encourages (or maybe I should say requires) that you understand the low-level details of how stuff works under the hood – memory management, how structures are laid out in memory, that sort of thing. When these folks start using C++, they apply the same low-level filter to things, and they see a class as just a data structure with some functions attached to it. This is in fact technically true, but kind of misses the point.
As I was trying to explain to my co-worker what I didn’t like about some code of his that I was reviewing, I ran into a bit of a wall. I knew that something wasn’t quite right, but I wasn’t able to articulate the problems well enough. I think I finally figured out that it was at least partly a result of the difference in perspective due to our different backgrounds. Once I figured that out, I was able to take the discussion out of the tactical questions like “should I use a Regular Expression here?”, and into the more theoretical territory of “is this an appropriate way to model the problem you’re trying to solve?”, and I think we made better progress after that.
It’ll be interesting to see whether my co-worker has the same kind of epiphany that I did, or if he’ll pick stuff up more gradually. Given that we’re mostly using C# and C++ at ZING, I suspect it’ll be the latter. You can write code in C# that looks just like C, with the minimal amount of “classiness” wrapped around it to compile. I suspect it would be easier for most folks to learn a new concept in a language where their old habits are obviously not going to do the trick.
Which reminds me of something else I wanted to write…