Version 19 of Ousterhout's Dichotomy

Updated 2006-01-07 08:32:58

FW: Surprising after all these years that this never got a page. Well, here goes...

Ousterhout's Dichotomy, proposed in the early 80's by John Ousterhout as a software development paradigm, asserts that the world of application development is divided into two languages: a compiled language focusing on disk access and efficiency such as C, and a higher-level, typeless or loosely-typed scripting language with a simple, basic syntax. Tcl was created by John originally to fill in the role of that second language. For this reason, Tcl is sometimes referred to as a "glue language," since it sticks lower-level components together with ease.

The motive behind this model is that standard compiled languages are good for writing low-level algorithms to perform the basic computational tasks required, but not very good at all for less computational, more descriptive tasks like defining interfaces. Tcl's implementation of the dichotomy, for example, basically involves writing functions in C and converting them to Tcl procedures using the fairly simple Tcl API, then writing scripts to tie the functions together and create a working application out of it.

This should, in theory, relieve a lot of the same code organization problems that things like Object Orientation were designed to help amend. If the dichotomy served its purpose completely, someone using Tcl this way should need neither C++ nor incr Tcl to keep their code clear and modular. This is part of the reason why some eschew idea of putting an object orientation extention into the Tcl core.

The most archetypical application is probably to write most of your application in C, then use something like Tcl/Tk to make a cross-platform GUI. This avoids, for instance, the need to rewrite your interface three times just to distribute it on three different platforms.

By the way, many applications provide a language for the user to automate tasks - for example, a macro langauge in a word processor, or UNIX shell scripting and DOS BAT files. Tcl can be and often is used for that sort of purpose, but Ousterhout's concept is primarily focused on making the application itself written partially in the higher-level language, not for user automation.

The main argument against the idea is that it supposedly rigidly categorizes based on "compiled" and "interpreted" languages and defines their roles, when a growing amount of languages compile partially into virtual machine code, or at least use a bytecode internally (even Tcl does this!). Some people for this reason declare the underyling premise wrong, so it has picked up names like "Ousterhout's false dichotomy" and "Ousterhout's fallacy" over the years. However, to this day there is no language versatile enough to perform high-level tasks as easily as a scripting language and efficient enough to perform low-level tasks as fast as a lower-level one. There need not be a rigid line between the two types of languages for it to be an effective way of characterizing software development.

Tcl was originally designed to be used that way, but don't feel stifled by it. There's no clearly defined line between "Tcl script using a few C libraries" and "C application glued by Tcl." For a random example, take WaveSurfer, a basic audio editing and conversion program. That's either a GUI written in Tcl/Tk for the basic functionality of the Snack audio toolkit, or a Tcl/Tk application that happens to use Snack. So there's nothing strict here, it's just a way of thinking about things.

This is a quote from Ousterhout himself in 1994:

I didn't design Tcl for building huge programs with 10's or 100's of thousands of lines of Tcl, and I've been pretty surprised that people have used it for huge programs. What's even more surprising to me is that in some cases the resulting applications appear to be manageable. This certainly isn't what I intended the language for, but the results haven't been as bad as I would have guessed.

But Tcl has long evolved since then, and is better at forming very large applications like that - so if it works for you, great.


I'm a bit hazy on this myself, so feel free to correct me if I got anything wrong. :)


MAK disagrees with "If the dichotomy served its purpose completely, someone using Tcl this way should need neither C++ nor incr Tcl to keep their code clear and modular". There are many levels and goals to modularity beyond that which is available or addressed by interfacing a low level and a high level language like C and Tcl. If you're like me, you tend to think about every project in terms of just how many useful modules you can make out of it, both for code reuse and productization of individual sub-modules. An interface between one or more C modules and one or more Tcl modules is only part of it. Also to be considered are scripts that are independent modules -and- lower-level libraries that are also modules that have nothing to do with scripting, and there are issues of code clarity and such with each.

By way of example, consider MIB Smithy SDK, which is written in C++ and provides SNMP and MIB features to Tcl. It is the core module of the flagship product (MIB Smithy), whose GUI and some text processing features use Tcl. But these things are not where the architecture ends. MIB Smithy (the application)'s Tcl code is comprised of many modular pieces for reuse in other future applications that might involve Tcl/Tk and may or may not have any C/C++ based internals. The SDK, too, is internally comprised of separate modules: four, actually. There's a level of architectural modularity between both the SMI database and the SNMP engine so that they could easily be made separate. But each of these are actually two modules: a core C++ library and API that is the basis for a module interfacing to Tcl for each. Why? So that it will be relatively easy when the time comes (actually I've started looking into it already) there can be versions of the SDK to link into C++ applications and versions of the SDK for other scripting languages (Python, Perl, etc). And, of course, those core C++ modules consist of other even more general-purpose modules for potential code reuse or productization.

In summary, the link between low level compiled languages and high level scripted languages is only part of a much bigger picture when it comes to architecture for diversity. That applies just as much to straight Tcl - which means there certainly are plenty of cases where Tcl could benefit from OOP features as much as the choice between C or C++ for a low level module. Tk widgets are very object-like*, and yet you have to go through a number of hoops to gain a similar level of objectification in plain Tcl (even for your own collections of standard widgets). Why?

* Though it would be more object-like, IMHO, if geometry management - pack/grid/place/etc. - were done through the container. e.g.:

  set hWndTop [toplevel]
  set hWndBu [button -text "Exit" -command "exit"]
  $hWndTop pack $hWndBu

But were that the case it would make adding other geometry managers a pain without other OOP features.


FW: I wasn't saying that in practice you should avoid OO when using this paradigm, but in general, and IIRC John agrees with me here, object-orientation addresses many of the same basic problems that scripting does.

DKF: Of course, it does it in a different way. This means that there's actually room for having both OO languages and scripting languages. This is a good thing. There are other useful paradigms which can help a lot with certain classes of problems, such as functional programming and logic programming. IME, it is useful for a programmer to have experience with as many different paradigms as possible, as it allows them to see more different ways of looking at a particular problem, and hopefully one in which the answer becomes fairly straight-forward.


Category Concept