Languages and speed of development
Well — my portal site is almost ready to launch. Roughly two-and-a-half months of part-time effort (a few evenings a week, plus the weekends) from first idea document to implemented software, running on my hosted server, with my own domains, trademarks applied for, etc. Not bad, if I say so myself. Although I have to admit a lot of the development speed is actually due to using the Python-based Web development framework, Django. Being accustomed to Java/J2EE/Tomcat-based development and deployment, I’m amazed at the speed and productivity that this development environment gives me. Python feels quite comfortable, Django fits my way of thinking perfectly. Almost everything is exactly where I would have expected it. The build-test-fix-turnaround is phenomenally fast.
I’m not sure that I would want to use this for every kind of project, though. I’m still not sold on untyped programming languages, for instance.
For one thing, I still miss all the support my Java IDE (IntelliJ IDEA) gives me during the coding — most of which is due to the typed programming language. In IDEA, code completion is very helpful. As is the continuous background checking of the implementation, flagging potential semantic and runtime errors even before I’ve started compiling — sometimes even before I finished typing. The Python IDE in Eclipse just cannot keep up. Since it has no idea what my shiny new variable blaBatz actually is, it cannot reasonably provide me with any code completion suggestions once I write “blaBatz.get” and press CTRL-SPACE (or whatever).
Additionally, while I agree that Python as an interpreted OO scripting language is a pretty powerful beast, I just wouldn’t be comfortable (yet) using it in a larger-scale development project — perhaps even a distributed one, with external developers, etc. For software development of this kind, I think there’s a lot to be said for some up-front design and cleanly specified, typed interfaces. I know that TDD can do a lot to solve some of the problems I’m envisioning; write test cases, run the test cases against new code in the version management system to find out if someone broke the build. And — as always - integrate early and integrate often.
For the kind of projects I’m envisioning, I have the feeling that a hybrid programming language might be best. Allow me to write untyped implementations if I want to. Don’t foce me to catch or declare exceptions. But give me the ability to provide types (and have them checked both at compile-time and at runtime) where I think this is necessary. Today’s machines are fast enough to justify compile-time and runtime type checking. Allow me to specify something like Java’s Interfaces in a Python package. Give me the ability to express which type I plan to send you and what I’m expecting to receive back. Clean interfaces, which are enforced at all points during the development process. Within the modules, inside the packages, the developer can be free to ignore type constraints and the necessity to predeclare variables, etc. But from the outside, the implementation needs to adher to the contracts (to use Bertrand Meyer’s term) that we agreed on beforehand. I know that types and interfaces and contracts are going to change in the course of a project. Especially, if we take the ideas of agility seriously. But I want to have a way to make these changes explicit. If we do change an interface, I want this change reflected in the declared types and interfaces. As software development progresses, I think this will also allow me to discover “stress lines” in the software. Whe an implementation change in one place leads to subtle changes affecting other parts of the implementation. Yes — we should catch all this with unit tests. I want the code to break before we’ve even run the first unit test, though (or — if you prefer — declare type checking as the first unit test, which needs to be successful before any other tests are applied). To me, looking at a set of typed interfaces is still an excellent way of discovering things about the software design which I would otherwise have to extract from reading the unit test cases. Or, possibly, the comments. One thing we all know, though, is that comments somehow never keep up with the implementation. When we’re in the “flow”, how many of us actually take care to not only change or refactor the implementation, but also make sure the comments stay in synch?
So - give me Python plus Interfaces plus Django plus Database abstractions. And if you ask me what I intend to do in my next project, I’ll tell you I really want to PIDDle.
Tags: Django; Python; Software Engineering; Design-by-contract
Bookmark on del.icio.us
Add this post to digg.com
Bookmark on reddit.com

May 22nd, 2006 at 8:40 am
Did you ever read the Ousterhout paper on scripting languages?
http://www.tcl.tk/doc/scripting.html
It really explains what niche you should fill with dynamic languages, and which niche should be done with typed/system languages.
The power of current dynamic languages moves the border somewhat in the direction of the dynamic languages.
Also nice reading:
http://www.equi4.com/moam/doomed.html
May 22nd, 2006 at 12:19 pm
But the nice thing about dynamic languages is that you can add this yourself. See for instance this article on adding type checking in Ruby:
http://erikveenstra.nl/monitorfunctions/index.html#5.1.0
May 22nd, 2006 at 1:25 pm
Michael — thanks for the pointers. I’ll be sure to print the articles out and read them tonight.
Michiel — I don’t understand Ruby enough to follow these short examples. But from what I understand, this will only give me runtime checking, does not really make types a part of the language definition or class model and is little more than a macro for runtime “asserts” which check the types of the arguments. Or am I missing something?