Paul R. Potts
So, it has been a while since my last entry… please bear with me. I’ve been putting in evenings and weekends trying to build a large proof-of-concept in code, using the Dylan language. Aside from politics, it has been uppermost on my mind, so here are some words on Dylan.
Although the language has yet to prove itself commercially viable (Apple pulled the plug on its Dylan implementation and closed the Cambridge R&D lab which developed it; the Gwydion project is now open-source, and Functional Objects, which spun off the Functional Developer IDE from Harlequin has announced its intent to open-source the rest). Although the various implementations have flaws, Dylan remains my personal favorite language and should be, I believe, considered the worthy heir apparent to Common Lisp.
Its most obvious difference from Scheme and CL is a Pascal-like infix syntax, rather than the familiar prefix, parenthesized notation. One could argue that it is the Lisp syntax, or lack thereof, that makes code-as-data S-expressions and language extension via macros possible. It certainly makes it simple to implement, but Dylan has proved that it can be done without the Lisp syntax. Hardcore Lispers will argue that the syntax is “just syntax” and therefore irrelevant, but Apple calculated, quite rightly I believe, that to improve the acceptability and promote the language beyond the existing Lisp community, a more familiar syntax would be necessary. I think this is true, but of course this has been “necessary but not sufficient” to promote widespread acceptance; many other factors, obviously, are involved in language acceptance.
Like many things Apple developed during the 1990s (QuickDraw GX typography, OpenDoc, system-wide encryption, and a long list of others), the implementation could not keep up with the concept. Apple’s Dylan IDE, implemented in Macintosh Common Lisp, ran painfully slowly on a Quadra 800 with 40 megabytes of RAM (this machine sported a 68040 at 33 MHz). I’ve never had a complete explanation of why this implementation ran so slowly, but it has something to do with an inefficient implementation of an object database for all source records and compiled code objects. Apple’s IDE was far ahead of its time; ten years later, IDEs have not yet caught up, although I have had the pleasure of using systems such as IBM’s VisualAge for Java which have gotten part of the way there. To see my notes and screenshots of Apple Dylan, take a look at these pages on the Dylan Wiki.
Both the two major current implementations, Gwydion Dylan and Functional Developer, are a little bit rough around the edges, especially in error-reporting and ease of configuring projects. Dylan has an extremely sophisticated module system that gives you fine-grained control over how bindings are imported and exported; it is much more advanced and flexible than C++ namespaces, but it extracts a certain penalty in overhead when building a complex, multi-module project out of text files. Refactoring code under the Gwydion system becomes somewhat painful when I must adjust “use” declarations, “export” declarations, .lid files, and module headers at the beginning of source files. Not to mention the makefiles. Failure to get it right results in somewhat opaque, and sometimes downright childish, errors (“puked when trying to load module…”), (“can’t handle hairy classes yet,”) and claims that I’m trying to define a class in a circular manner. Clearly it is still a bit of a hackers’ tool, and user-friendly error messages are not its strong point, but it does the job. And unlike some scripting languages, generating efficient code, and providing a clean interface to C, are design goals that have been achieved. d2c generates C code, essentially creating a virtual stack and named locals for temporaries, as if C were its machine language, and executing very low-level C constructs. It is a case study in optimization. Providing type specifiers allows the compiler to generate very optimized code; leaving everything open provides maximum flexibility for the developer. (In the Lisp tradition, variables don’t have types, but values do; Dylan allows you to give your variables types, and the compiler will enforce them).
Although Dylan’s module and type system should enable exact tracking of dependent changes and thus minimal recompilation, the d2c compiler seems to always recompile each file in the project, and as the maintainers note, “d2c generates fast code slowly.” I’ve been trying to ameliorate this situation by building libraries, but library support is off-the-bat slightly broken under MacOS X; the Carbon library is slightly broken as well. I’ve found a few bugs, and already received one patch from the maintainers. I’ve had to work around some strange behavior. I’ve had to revise some of the distributed libraries. I’ve managed to patch these things up, but communication with the maintainers via the mailing list has been flakey as well. I can’t exactly complain; It is an open-source project; I can contribute fixes to the maintainers. But contributing patches to an extremely sophisticated compiler requires a pretty deep understanding of the compiler internals, and despite its failure to be user-friendly to questionable code, this is a very advanced optimizing compiler.
As open-source projects go, no one would claim this is a good starter project. Most of my working time is committed to paid work, but I am still going to do what I can to contribute. I’ve wanted to see Dylan succeed for almost ten years now. Even if it succeeds for no one but me, that’s a strategic advantage and an opportunity to write code at a higher level.
Functional Developer is a more polished implementation, although it is still capable of bringing my Windows ME machine to its knees after a bit of use. (This is probably more a comment on Windows ME than on FD). Its error messages are also sometimes a bit confusing, and there are some slight differences between what d2c finds acceptable and what FD does. The interactive debugger is a bit baroque. But it works; I was able to port a lot of code, checking it into CVS from a Gwydion Dylan project and checking it out on the PC.
There’s a great potential for someone to coordinate a serious development effort here. Dylan is languishing, and it doesn’t deserve to. It already provides, in a formal and sophisticated way, what scripting-language writers are struggling to provide. It has higher-level functions; it has multi-methods; it has advanced capabilities for optimization. It has a macro system. What it lacks is a user base and a supported commercial implementation worthy of the language design itself. That sophisticated module and export system? It cries out for a graphical tool. (That’s how I keep track of my exports and imports: I draw them with OmniGraffle, a great graphing tool for MacOS X, and let it lay out the graph for me). The error handling? It cries out to be polished up, not abandoned. Did you know that four books on Dylan have been published? Probably not. They are all out of print, although you can still get copies of two of them. But they aren’t the last word. The language cries out for an O’Reilly book. Maybe I’ll be the one to write it.