Posted by Anders
Sun, 01 Jul 2007 20:20:00 GMT
About intentions, two stages in the history of programming and the corresponding stages in the individual programmer’s skills.
Stage A – How do I get it to do what I want?
In the beginning of a programmer’s learning there is a struggle to simply get the machine to do something, anything. Much like when you try to communicate in a spoken language you’ve just started learning, you can’t express some concepts, invent awkward statements instead of words you don’t know, and get things plain wrong.
You have a pretty clear idea what you want to say, but you struggle to communicate it.
“I need a lift in your el truck-o to the next town-o!”—Brad Pitt, The Mexican
In the early programming languages, there wasn’t much more to it than this. The language was very limited and even though it could theoretically express everything, you couldn’t communicate it. The higher level concepts and ideas was not expressed in the language, but in the documentation or, more likely, remained in the programmer’s head. Even though you learn the language to perfection, there’s little difference in what you can express.
Stage B – What do I want?
“I want a helmet. A cheese helmet. A helmet full of cheese. You just pop it on your head and eat all day.”—Denis Leary
Once you master a language, the focus shifts away from the language itself. If you know what you want to say, you can often express it directly, less limited by the language. Ever higher levels of abstraction and expressiveness in languages makes this increasingly simple. (Learning the language in the first place isn’t necessarily any simpler). Constructs like classes allow you to express very abstract concepts and ideas in just a few statements.
The original purpose of a language, communication, can now be achieved. The problem is now to find out what you want, your intention, so that you can express it.
Understanding and Documentation
While most of what programmers do these days is firmly in “B”, there are a lot of ideas with roots in “A” that still linger in our minds. Our ideas about how and when to document our code often have their origins in a time where the languages couldn’t serve the purpose of communication. There was no option but to annotate everything with natural language if you wanted to communicate. When we left machine code for procedural languages this need was reduced a lot (to merely procedure-level comments), and object-oriented languages reduced even further (maybe to just class-level comments). This is all under the assumption that the language’s abilities are actually used.
The intensive documentation required in “A” also sometimes created the belief that the documentation should be extensive enough for someone, with no prior knowledge of the system, to understand it directly.
But just like in any natural language, the individual statements don’t make sense unless you know their context. In a program the context can be very big, ranging from knowledge about the problem domain to the technical solutions preferred in the programming team and can not be expected to be learned from low-level documentation within the code.
The purpose of the code is communication with the other programmers working on the system (and with the compiler). Like any natural language, you use people’s shared context to make the communication more efficient, at the expense of the outsider’s understanding of it.
Getting to B
“I CAN WRITE COBOL IN ANY LANGUAGE”—Unknown
While a beginner may naturally be in “A”, there is no guarantee that experienced programmers will be in “B”. While it is a requirement to know the language well to do “B”-style programming, it isn’t enough. Just using a modern language doesn’t make our code more communicative. We can still write long methods with three-letter variable names in Java, as we did in C. We can still organize and name our Ruby classes entirely without connection to our problem domain.
We have to strive to keep accidental complexity and technicalities to creep into how we write and organize our code. Using good naming on everything from variables up to modules, we have to keep the code close to the intentions that originate it. When the intentions change, we have to use Refactoring to make the code reflect the new conditions. If we don’t use these new opportunities, we’re also stuck with the needs for heavy documentation and other practices of “A”. Even if we don’t write code for the “outsider” audience, we still need to communicate as clearly as possible.
“Getting the words right”
The big challenge is to know what your intentions really are. Unless they are truly clear in our minds, they can’t be clear in the code. This is where design tools like Test-Driven Development (TDD) is a big help. By forcing us to reason and express what we really want our code to do, it makes it easier to write code that also communicates this intention.
The more recent Behavior-Driven Development (BDD) concept emphasizes the TDD idea that the tests themselves should be used for communication. BDD tools typically encourage you to state your intentions in natural language, together with code that verifies each intention (paradoxically similar to the early documentation practices). Unlike other forms of documentation, it is harder for this one to become out-of-date and misleading.
The TDD/BDD ideas seems like a parallel, but orthogonal, development to that of the modern languages. They are adding more ways of communication, but at the same time as helping us use the existing ways better.
Thus
There are a lot of opportunities in “B”, as long as you actually take advantage of them. For novices, there is the need to master their programming language, to gain the ability to express themselves in it. For experienced programmers, it’s important to really use the abilities to communicate that modern languages provide, supported by the available tools.
Posted in Ruby, Java, Programming | Tags language, rambling | no comments
Posted by Anders
Tue, 19 Jun 2007 19:30:00 GMT
I knew the issue of Unicode and Japanese was complicated, but I didn’t know what a language geek I was until I enjoyed this nice overview:
Unicode in Japan
I guess this explains why Ruby still doesn’t have proper Unicode support.
Posted in Ruby, Programming | Tags japan, kanji, unicode | 2 comments
Posted by Anders
Sun, 15 Apr 2007 10:07:00 GMT
When I first tried RSpec it felt like a good tool that forced you to write your tests in a form that’s very close to what’s considered best practice. There are a lot of ways to abuse Test::Unit or JUnit, but if you know what you’re doing you’re usually still close. RSpec was good enough for me to change to it, but didn’t feel like a big deal.
But after some time with RSpec I’m now writing a lot tests in Java again. What I realize is how hard it is to organize tests well in JUnit. The tool is fighting me all the way, you just can’t make simple tests easily. If you want to take full advantage of the setUp() methods you have to create a lot of classes. This quickly makes it hard to get an overview over your tests. It just can’t be compared to RSpec’s “context”. I believe JUnit’s way of having exactly one setUp() per class is the problem. Maybe some way of allowing multiple setUp() would be possible.
There are a lot of other differences between RSpec and JUnit, the conditions for example (assertTrue vs. should_eat_cake) and the naming of the test cases. But still the organization of the tests make a big difference. There’s nothing for Java that really does that today. Test NG does an attempt, but at the cost of a little more complexity. But there’s nothing preventing it from being done.
Posted in Ruby, Java, Programming | Tags junit, rspec, testing | 1 comment
Posted by Anders
Mon, 09 Apr 2007 15:20:00 GMT
I was going to use ActiveRecord for some simple storage in a small application I’m hacking on. Since ActiveRecord itself has support for lots of databases I figured that it didn’t matter which database I used for testing1.
In Java I would have used Hypersonic, or some other self-contained in-memory database, for this. Looking around in Rails land, you find that most people use Rails’ testing features and run their tests against a separate instance of their production database, usually MySQL. Other people use Sqlite3, which seems to be the simplest database around.
Since I don’t have a production database (and generally dislike MySQL2), I looked at Sqlite. First of all, it requires Sqlite itself to be installed. In OS X this is already done, but it will be a problem elsewhere. Then there’s a confusing selection of different gems with drivers. But once you get the right one installed, it seems to work fine.
Once I started working with it, I ran into a problem. Every time something is wrong with the database structure, no matter if it’s the whole database missing or just a single column misspelled, I get the same error:
`table_structure': ActiveRecord::StatementInvalid (ActiveRecord::StatementInvalid)
Since I was changing the database structure a lot, I got this all the time. Don’t know if this is Sqlite, the driver, ActiveRecord or me that’s to blame, but it wasn’t very practical.
Since my patience is very short, I simply dropped the database storage feature from my app. :) But there seems to be two issues here:
- There is no self-contained, gem-installed database for Ruby
- The error handling in Sqlite, or something on the way to Sqlite, isn’t very good
I now hope that someone will tell me what an idiot I am and that I should use some other driver, or some other database.
1 I’m using RSpec, which is the best testing framework since sliced bread.
2 Bleh.
Update: By enabling debug logging in ActiveRecord you’re supposed to get more information out of it. I’ll try that the next time I work on it.
Posted in Ruby, Programming | Tags databases, testing | no comments
Posted by Anders
Tue, 05 Sep 2006 00:42:00 GMT
The talk about Joel Spolsky’s in-house language Wasabi reminds me of my experiences at a previous employer:
In some glorious past the company founder and some other wizards had created an object-oriented language of their own, more advanced than Objective C (for this was in the days before Java). Using this language they wrote a successful application which the company was built around.
When Java arrived, they created a Java-syntax pre-processor to their language, and machine converted their entire code-base to an almost1 Java syntax. But the compiler, runtime and libraries where still very much non-Java. Imagine not having the java.lang.* and java.util.* classes.
By the time I joined them, the founder and most of the wizards had left the company. The system had evolved into something very big and complex, parts of it essentially being an application server. The remaining programmers, very few with any experience, where left to develop this system. As a result there was very little maintenance done on the underlying language and platform, even though bugs and limitations in it was a constant nuisance. It simply had to be worked around.
For the programmers, it meant that their previous Java education and experience wasn’t as useful. Everyone had to be trained in-house and you couldn’t just go to the computer bookstore and buy titles about it. Neither could you share experiences with anyone outside the company, making the place a bit intellectually isolated. There may have been some documentation, but hardly comparable to what you’ll find on a mainstream, or even obscure, language and system. The ones who tried to move to other companies found that their lack of real Java experience was a problem2. Unsurprisingly morale wasn’t very high.
The company’s solution? Developing another application server of their own, in parallel, this time in pure Java. But that’s another story.
1 Differences in language type systems forced them to weakly typed workarounds, causing endless troubles.
2 For experienced software developers it may be less critical, but for the ones just out of a short education it was a real problem.
Posted in Ruby, Java, Programming | 1 comment
Posted by Anders
Sun, 11 Jun 2006 16:50:00 GMT
On May 30th I did a presentation of Madeleine to a gathering of Stockholm’s Ruby on Rails people. I enjoyed it a lot, I hope my audience enjoyed it as well.
I got some interesting questions and ideas. Hopefully some of the ideas will be in future versions in some form.
Slides as PDF
Posted in Ruby | no comments