“Proper Object Code … ?”
A couple of years ago I had an odd thing happen. Back in 2015, after spending 9 years in Austin (mainly for family reasons — my wife is American) my wife and I moved back to Toronto permanently. Two years later I got a call from a consulting/recruiting firm in Houston asking if I would be willing to move back to Austin, relocation paid, in order to take a job. Given that the company in question specializes in Smalltalk, either recruiting Smalltalk developers or, ideally, running Smalltalk projects, in general it wouldn’t have been that odd, after all Smalltalk development is a relatively niche field.
What made it odd was that the role wasn’t doing Smalltalk development, it was doing Java development. Never mind that I would have no reason to move over a thousand miles to find an opportunity to write Java code, it makes little sense to pay over the odds in terms of salary to get me to move, and to pay my expenses to do so, when there are plenty of Java developers in Austin.
The reason, according to the recruiter, was that the development manager at the firm in question “didn’t think that anyone who ‘grew up’ with Java knew how to write ‘proper object code’ “, and therefore would only hire a developer with extensive Smalltalk experience. If it had been a small company one could chalk it up to a whimsical quirk of a particular development manager, but it wasn’t a small company, and development managers at larger companies have to have earned significant credit within the company before finance and HR are willing to let them indulge expensive quirks, which generally means they have a notable success rate. But why would hiring (former) Smalltalk developers increase the success rate at a company that doesn’t (and never did) use Smalltalk?
It seems initially like an extreme statement, but as I thought about it (long after declining the offer — I love Toronto) it started to make more sense, because it’s not a judgement of the ability of different developers, but a statement about their perspective. Now, I know plenty of excellent Java developers who’ve never touched Smalltalk, but the recruiter didn’t say that people who ‘grew up’ with Java didn’t know how to write good code, the term was specifically ‘proper object code’. As I thought about it what ‘proper object code’ implies and why it would matter became the focus. After all, if the code is well written, organized, readable, testable etc., why would making it ‘proper object code’ matter, what advantage would it give the company, to the degree that they would pay extra to ensure it was written in that particular manner?
Smalltalk was the first language given the moniker ‘object-oriented’, for the good reason that one of its main architects invented the term, Alan Kay. He’s since somewhat regretted it, but the term has stuck despite his misgivings, which tends to indicate that it gets at something relevant, even if people are unsure exactly what it is.
The more generic or abstract the term, the more difficult it is to say precisely how it squares with one’s unstated ontology (how we understand what anything is). And terms like ‘object’ and ‘orientation’ are fairly abstract. If we think of ‘object’ in terms of scientific ‘objects’, the compound term becomes essentially meaningless, it’s only relevant if we stick to the defined meaning of object in programming languages, which of course originated with Smalltalk, and can be expressed as ‘a data structure together with the means of modifying it’.
So much for ‘object’, what about the second term, ‘oriented’? In being oriented we’re dealing with (at least) two things, what we’re oriented-by, and what we’re oriented-towards. In the term object-oriented we’re oriented-by objects, and oriented-towards the program we’re writing. Since at the time of writing the program doesn’t yet fully exist, it can only be an imaginative projection of the finished program that we’re being oriented-towards.
Java is, syntactically, based on older languages in the line that began with Algol, with C being the best known of that line. Along with its basic syntax the mode of writing Java is similar, with a write/compile/build/test cycle. This involves a certain metaphor that programmers understand what they’re doing through. The metaphor involves text on ‘pages’ that are kept in ‘files’, which are then stored in ‘folders’ and ‘subfolders. Notwithstanding that neither folders, files, or any other part of the metaphor corresponds to a first class language structure in Java, this metaphor guides most Java programmers without them thinking about it, and is the reason that virtually every development environment is fundamentally a text editor and file manager, however advanced or not they might be. However much one might like to think one is writing object code, the fundamental metaphor that most Java programmers implicitly work from, the metaphor that orients them, has nothing whatsoever to say about objects. In fact, it goes directly against the object-oriented paradigm by focusing on code, more specifically ‘code in files’, not ‘data structures together with the means of modifying them’.
Smalltalk doesn’t use this metaphor of “code in files”. Nor does it have the write/compile/build/test cycle of development. Smalltalk environments aren’t built around a text editor and file manager, they’re built around various browsers, which display objects in various ways. When you write code in a method, which is in a class, it’s a class object. When you save that code it immediately becomes live in the environment, i.e. to whatever degree you just added or modified code, the environment itself has immediately changed.
This consistently reinforces the orientation of the developer as being oriented-by objects, or put another way, the developer has to project the rest of the program from the perspective of writing from an object, and a live object at that.
That difference in perspective changes the manner in which you write and organize your code — it tends to be organized around the data structures. A common refactoring in Java is to move code to a more appropriate class, the appropriateness being determined by the data structure present in the class. But why wasn’t the code in the right class to begin with? Primarily because the programmer wasn’t projecting the program from the perspective of data structures and related methods, but from the perspective of code, ‘code in files.
Sure, in Smalltalk as in Java there is code that isn’t specific to a particular data structure. In both cases that code is referred to as ‘functional’ and is often implemented in a particular style, often as the only method in a particular class, which itself may or may not be written inline. It can be written as a lambda in Java 8+ or as a block in Smalltalk (also called a block closure), but in any event, it’s not associated to specific data. However, the ‘helper’ classes prevalent in Java for specific data types are unusual in Smalltalk, since you would more naturally just implement those methods in the data type itself. Since that code is all written in Smalltalk and available in the environment in most dialects, there’s no difficulty in doing so.
You can write perfectly good code in Java or other ‘object’ languages without adhering to one of the basic notions underlying ‘object code’, but to a Smalltalk developer at least, your code will be organized oddly, assuming it’s still organized well. It’s the ‘it’s organized, but not properly’ that makes a lot of excellent Java code not ‘proper object code’ to someone who is consistently oriented-by objects and writes code from that perspective.
So, why would this be sufficiently advantageous to the company I referred to above? Organizing code in a specific way doesn’t make it run better or in fact change anything at all to anyone except other developers. But that’s the key. It wouldn’t be an advantage unless all the other developers are from that specific background. However, if in fact they are, it makes becoming familiar with someone else’s code that much easier. By ensuring that all their developers have that background, they ensure that gaining familiarity with their codebase is easier. Since adding to or modifying an unfamiliar codebase is the number one cause of new bugs, it ensures that unfamiliarity is kept to a minimum, which in the long term likely saves them sufficient money to make up for the higher salaries and extra expenses they pay to hire developers who have that niche background.