What’s it like to use those languages?
I have had colleagues and others ask me, “what is it like to use those non-mainstream languages?”. I have never given an answer that I think is satisfactory. It doesn’t seem possible to answer this question satisfactorily, without educating on all the fundamental programming and mathematical concepts that are on hand. I want to convey what it would be like to someone who is familiar with the typical mainstream languages such as Java and C#, without having to dive into a lecture about category theory or type-classes or what-have-you. It is also hard to answer this question when there is so much pseudo-science around; I have to contend with absurdities such as ‘design patterns’ and ‘X driven development’ and sometimes even the hijacking of terminology such as ‘automated testing’ and ‘type-safe’ and … (I could go on and on).
Instead, I propose a hypothetical scenario that the inquirer is likely to be able to imagine. Then point out what it is like from their position in light of this hypothetical position. Hopefully then, I can simply say “it’s like that” and have the question answered satisfactorily. On with the story…
Imagine there was a programming language called Java Prime (Java’). It was just like Java, except it had no such thing as java.lang.Object or a common supertype. Instead, to represent universal type arguments, we used generics, even for such functions as equality i.e. {<T> boolean eq(T t1, T t2);}. We maintain the usual Java rules of invariance in type arguments i.e. C<T> is a C<U> iff T = U as opposed to say, covariance, C<T> is a C<U> iff T is a U. For example, in Java, a List<String> is not assignable to a List<CharSequence> even though String is a CharSequence.
Now imagine a new programming language called Java Prime Prime (Java”). This language is not as powerful as Java’ because it doesn’t have generics! Now imagine that Java” had mass adoption because learning generics is too hard, ‘not for the real world’ and ‘only relevant in academia’. We could hypothesise about how the result would look. Here is one scenario; you cannot write a function to compute the length of a List; instead, you have to write a function for each and every type that may be applied to a List. Then, some bright guy would register listlength.com and start the ListLength project. He would ship a JAR file containing the length function over many different types. He would attract fellow contributors and even write some kind of plugin facade that would allow you to compute the length of Lists of types in third-party APIs. listlength.jar would be a 100MB jar file that you could download.
However, some other guys aren’t into the length library. After all, it only works on List; what about Set and all the other types? Furthermore, the function should be called ’size’ not ‘length’. So now we have a debate about the correct name of the function and size.jar is 150MB and has Eclipse integration (somehow?). The debate is quite circular and often attracts personal attacks and so on. You watch this debate from the sideline; sometimes laughing at its silliness, sometimes feeling quite empathetic toward its proponents.
The hypothetical size of listlength.jar and size.jar is infinity. It could indeed go on forever and it keeps many people employed. To threaten the monopoly on list length would attract the harshest of criticism, despite any irrationality of that criticism. Imagine walking passed a ‘length guy’ and a ’size guy’ having a discussion and whispering into each of their ears, ‘generics’. You would attract many kinds of irrational responses and you could even catalog each one perhaps assigning some to the blatant logical fallacy group, the anti-intellectualism category and intersections of categories and so on, anticipating and sometimes even making predictions which response is about to be used based on body language. You could chart them and determine which response is likely to follow from which and so on. In fact, you could get a darn good idea of the way the system works; much better than the length or size guys ever will while their bubbles haven’t popped.
The fact of the matter is that you just wrote infinity lines of code by saying a single word. This might sound knee-jerky and quite out-of-nowhere, but it is absolutely true. The fact that the statement appears both extreme and is absolutely true should start ringing some alarm bells for the length and size guys, but they have already prepared their defence against these kind of attacks. You might even say things like, “the length and size libraries are the most useless things I have ever seen” even though it is so popular that it appears on some people’s CV! You don’t write a web application without first downloading listlength.jar or size.jar (depending on which establishment you subscribe to).
So you plod on, using generics in Java’ as it were, having already written the list length function (and the set length function and… oh wait, I’m not going there :)) once and for all and you have no choice but to ignore the length and size guys, despite their curiosity about what it is you are doing. If you ever present your length function to them, be prepared for charges such as ‘how confusing’ or ‘look, it’s longer than my length function! (while pointing at the <T> declaration)’, but if you’re like me, just sigh and keep on working.
Imagine, however, that you were placed under duress to use and even contribute to the length library. Suppose you worked for Java Joe and Joe, the Senior Architect, demanded that you use the length library, because of the usual irrationalities (too hard, not for the real world and so on). You question him, but the authoritarianism is clear and so there you sit, about to write a line of code for the length library. Suppose now you type 20 characters of code. Have you made progress? Do you feel like typing another 20? You sit there totally aware that the very act of typing 20 characters is no different with respect to progress as it is to doing nothing at all. You wonder if you should even just sit there; why not just go to the beach? After all, you’ll be making the same amount of progress as Java Jim; your colleague madly bashing away at his keyboard. It’s quite an anxious feeling to sit there in a state of logical inconsistency as a result of suppression of reason and thought. How would you deal with it?
That’s what it’s like.
- Attempting to make undeluded progress against the wishes of a well-controlled establishment
- As a devout humanist, I watch people labour over a completely futile task under what appears to be nothing more than a spell
- Dealing with the irrational criticism and charges of blasphemy that are attracted by making statements that challenge the establishment (despite their truth value)
- Dealing with suppression of reason, stupidity and (often inadvertent) authoritarianism
I hope that gives you a taste ![]()
December 20th, 2007 at 10:14 am
I totally understand what you’re saying except I’m not so harsh (”sigh and keep going”) though I end up doing the same thing. Eventually they are forced to do whatever I am doing
December 22nd, 2007 at 5:15 pm
People only remember embarrassment and accomplishment. The Parable of the Infinite Jar of Objects is one way to embarrass people: through metaphor. Design patterns is one way to summarize accomplishments through metaphor. In embarrassment and accomplishment, people can build a sense of aesthetics that allow them to see past notions like “software development phases”, and lift up higher truths about evolving technology. If it requires The Parable of the Infinite Jar of Objects to see these higher truths in terms of embarrassment, then so be it. If it requires reading Design Patterns: Elements of Reusable Object-Oriented Software and Refactoring: Improving the Design of Existing Code to see these higher truths in terms of accomplishment, then so be it. However, I’d prefer it if embarrassment and accomplishment were seen as two sides of the same coin.
Metaphors are an important vehicle for accepting each side of the coin, because metaphors aren’t too prescriptive. In written language, we tolerate more complexity, as it requires more time in reading and writing to accomplish the same analysis and design using speech communication. The subtle nuance suggested in The Parable of the Infinite Jar of Objects is that although you may be forced to express everything as an object in one way or another, having too many objects impedes communication. The water shed moment comes after the embarrassment, and the opportunity presents itself to illustrate through metaphor how to accomplish agility: pare down the model.
The first thing that can be taught about analysis is that models are not right or wrong; models are more or less useful. How far do you go in modeling? As far as is useful. There’s always more than one way to model a problem. There’s also no necessary way to begin visualizing a model. Modeling is an iterative process, and it doesn’t need to start at the best place. With any reasonable starting place, the model will converge on a similarly useful model.
What is the difference between Euclid’s Euclidean geometry and Hilbert’s Euclidean geometry? They both modeled the same problem, but with different perspectives. Euclid and Hilbert were looking at the same picture, but starting from different angles and distances.
Sometimes, the modeling path chosen will not end up in a robust model. Invalid solutions are not necessarily completely discarded. Although we should heed “plan to throw one away; you will, anyhow”, then it is useful to pull back and ask if some of our initial assumptions are invalid. By teasing away the assumptions that don’t apply to the particular problem, the model becomes more robust.
A good example of design patterns capturing higher truths is the Sorting Pattern: implementing a sorting algorithm using a divide-and-conquer approach. All shuffling algorithms can be decomposed into Split and Join semantics. The number of shuffles it takes to sort a list depends upon the splitting decision. Selection Sort splits a list into two elements: the first element, and the rest of the list. Merge Sort splits a list into two halves. Quick Sort varies in how it splits a list, but makes a best effort to split a list evenly. The ingenuity behind C.A.R. Hoare’s design of Quick Sort is that all of the complexity is in the Split: there is no Join code. The Split/Join model is a very robust model that separates the model into two models for improved decision-making. We can see the advantage of the robustness of this model in Introspection Sort (IntroSort) used in the SGI implementation of the C++ Standard Library: IntroSort combines Quick Sort, Heap Sort and Insertion Sort.
December 25th, 2007 at 1:50 am
eclipse-size-plugin.jar would obviously win; it would generate size methods on the fly for all accessible types in the project space
The only thing I can find in java that requires such preposterous levels of workaround is primitives; you can’t template on them so if you care enough for e.g. an implemention for IntList and the like, you’d need to write a code generator. Which is exactly what one of those java collections API extensions (apache’s, or google’s, I can’t recall) does. No good, but, fortunately, performance of the wrapper classes is sufficiently close to the primitives themselves that it doesn’t really matter.
Therefore, I’d say your metaphor is fundamentally flawed; java’s problems lie in its ‘half-assed’ness. It has a static, explicit type system, but then the notion of whether or not any variable/attribute/parameter can hold null is completely dynamic. It chooses the ‘enumerate all common use cases’ vs the ‘create meta programming directives like operator overloading and let library builders sort it out’ paradigm, which has a few redeeming features to some, but then doesn’t do it right, because new and obvious use cases (such as BigInteger and BigDecimal needing operator support) aren’t added in a timely fashion.
It has closures, but they carry 4+ lines of cruft just to write them (anonymous inner classes - function pointers that close over lexical scope. That’s close enough to ‘closure’ in my book, but you need to wrap all non-final variables, you have to jump through some hoops to escape from the closure using e.g. a return or break or continue, and, of course, you need to write both the class/interface name and the method name). Discussion to do something about the cruft finally shows up for java7, but then half the proposals act as if anonymous inner classes don’t exist and write a new type system instead.
Just point such people to Scala. It doesn’t just run on the JVM, like python or ruby - it actually takes some pains to produce class files that look and feel like a java-generated class file from the perspective of a java developer. They have getters and setters and sensical hashCode and equals implementations and such - most of that invisible for scala code, as it should be. You can therefore use scala on a few files in a java-based project and the people you work with (or yourself if you go back to java for some of the files) don’t really notice.
Java isn’t the only language base that has to deal with lots of conflicting similar implementations of the same concept. Python has a bunch of rails-wannabees, all very very similar and yet all different (TurboGears and Django are virtually the same thing, for example). I imagine its a common problem for any language with such an enormous userbase. Again, though, java doesn’t really carry it to its logical conclusion; there is no CPAN-like database for java. There’s the maven repository but there are plenty of writings to find online about the many things Maven does very very wrong.
Fortunately to java programmers, and the JVM (which, in my book, is made up mostly of win), recent pressures in programming language world seem to have kickstarted improvements to java into gear. Most of the above issues are now being addressed, though whether it’ll help will remain to be seen.
December 25th, 2007 at 5:43 am
Hi Reiner,
None of the issues that I am alluding to have been addressed. The metaphor is not ‘fundamentally flawed’, since some of your premises are incorrect. For example, “…in java that requires such preposterous levels of workaround is primitives”. I’d be happy to elaborate here, but I fear falling into that ‘lecture about Category Theory’ that I have so far avoided.
In the meantime, please take my word for it, it’s like that
December 25th, 2007 at 12:36 pm
Yes, because telling me: ‘no, no, my language is better, just take it on faith’ is nothing at all like managers telling you to stop confusing them with ‘complicated’, ‘unreadable’, ‘what-the-hell-language-is-that’ nice, clean, flexible, maintainable code. None whatsoever.
Your post sort of changes tack, starting with a promise to explain what using more refined languages will be like, but ending with the fairly ‘duh - obvious’ conclusion that the need to dance to some idiot boss’s fiddle is very bad for your codebase. That’s the real conclusion of your post, I think - if you get the sense that doing X is the cleaner way, try and fight for it, and don’t listen to any book, guru, or bosses premonitions. You might be wrong, but making the mistake is the only way to really learn.
Unfortunately, this puts your last comment in a bit of a bind, as it seems to be telling me to shut my yap and just follow the sheeple - blame languages that lack elegance as the only thing standing between me and the promised land of programming. Thing is, I use many languages, and not one of them magically makes my code jump over the moon, or magically eliminates all bugs. A man can dream, perhaps.
Maybe I need that lecture on category theory. I could maybe compare it to the many tutorials on haskell type classes for kicks.
December 25th, 2007 at 6:37 pm
Hi Reiner,
Please be assured that I certainly do not encourage you to ’shut your trap’. Quite the contrary, I strongly encourage challenging any establishment in the name of progress.
I’d be willing to help you understand software abstraction and all the topics at hand that I am deliberately avoiding; choose your medium. I recently ran a Scala training course for Red Hat/JBoss and I’m running the same course again after Christmas. It was called a ‘Scala training course’, but really I was teaching advanced concepts with a language that supports some of them (we also touched on Haskell98).
You’re not in the area I assume
but I strongly implore you to seek further and definitely keep your trap yappin’ 