The Rants, Raves, Gripes, and Prophecies of Paul R. Potts
Contents by Category
Contents by Date
OK, let me talk a little more about what I'd like to accomplish with my hobby programming projects. If you've read Zen and the Art of Motorcycle Maintenance, consider this a Chataqua (that term comes a little more naturally to me given that I grew up pretty close to Chataqua, New York, and have been to programs there a number of times).
First of all, the primary goal is to learn some new concepts and languages. It is awfully difficult to learn programming idioms and concepts in the abstract, so I'll need to set myself some small projects. In particular:
* Continuations. This is a big topic in the Scheme community, but in
most other languages continuations don't really exist. Nevertheless, the language research community considers continuations to be very important; they are considered an essential tool for compiling other languages, and now a number of people are talking about using continuations to simplify management of state in web applications. Nevertheless, they seem to be very difficult to explain: see recent threads on the Lambda the Ultimate weblog. I suspect that they are a little like closures and recursion in that they are easy to understand once you've used them for something, but experience with static languages actually hinders understanding. So, I'd like to use them for something. Perhaps a small web project using SISC. Perhaps for kicks I could then attempt to translate the same code into Common Lisp, which does not support continuations directly, using an implementation of continuations in Common Lisp, which might allow me to once and for all understand it, and also perhaps to port it again to Ruby, which supposedly features continuations as well.
* Macros. In the past I've attempted to write some Scheme macros, and
failed because of incompatibility of various Scheme implementations with the RSR5 standard. I've tried to write Dylan macros, but never quite got them right; the Dylan reference manual is not very useful as a tutorial, and it wasn't clear if the Gwydion Dylan implementation matched it properly. I suspect that I need to go back to Common Lisp and work my way through Paul Graham's On_Lisp, and then work from there to see if I can do the same thing in Dylan. I'd like to understand clearly all the varieties of macros and what people mean when they characterize a macro implementation as such-and-such, hygienic or not, functional or not, etc.
* Monads. Another concept that people on Lambda seem to have a great
deal of difficulty explaining. Haskell is probably the poster child of functional languages using monads.
* Scheme. I've used Scheme just enough to appreciate its simplicity
and usefulness; I've done some volunteer teaching, attempting to introduce grade school students to Scheme programming and recursion. It would be useful to dig a little deeper into Scheme to master continuations and macros in the language, and perhaps even write something useful in it.
* Common Lisp. I'm a little uncertain on this one; do I really want to
clutter my head with the huge extent of Common Lisp idioms and library functions? Should I consider Common Lisp to be a relic in and of itself, useful mainly for informing the design of newer languags, or the future, in which we'll just give up on less powerful languages and use Lisp? It seems a little difficult to keep Scheme and Lisp uploaded into my brain at the same time, kind of like switching between C and C++. But I can't deny the abstraction power of Common Lisp macros, and I'm really jonesing to work through Graham's book.
* Dylan. Yes, Dylan. Still my favorite multi-paradigm language.
Showing a few wrinkles and cracks, like a lack of native continuations, but still incredibly powerful if only for its multiple inheritance support, generic functions, multiple return values, full support for higher-order functions, and the possibilities of static typing and efficient compilation. (I keep hoping one day I can stop worrying about efficiency altogether, but that doesn't happen; what happens is that we try to take on bigger data sets and more complex algorithms). I keep hoping to find a piece of the Gwydion Dylan project where I can contribute something useful: even redoing error messages, or improving error checking, or basic documentation: these are the itches I'd like to scratch. But delving into the compiler is discouraging; I get frustrated by the compile times and daunting complexity of the Gwydion implementation's innards. The maintainers seem to have given up on Mindy, so there's an opportunity there: what would it take to write a tool that can boostrap a big Dylan implementation? (A hell of a lot, probably). I'm wondering if d2c really has a future. The Functional Objects compilers look a little more promising, but I haven't even gotten a toehold there, and I hate to have to keep rebooting to swap between Linux and Windows.
* Ruby. My favorite of the scripting languages, and the one that has
been the most enjoyable to use: it has a laughably simple syntax, takes ideas from many of my other favorite languages, and is refreshingly light on weird idioms, relying instead on a handful of common concepts like the code block (closure).
* Forth. Yes, Forth. If Lisp can be characterized as a "programmable
programming language," then Forth is another one. Aggresively simple in implementation, it is another one of the languages where the language gurus seem to expect you to be able to roll your own implementation. Forth is concise: both its great strength and great weakness, and enables metaprogramming, in its way. I've been doing a lot of embedded code work and looking at horribly complicated and error-prone implementations of relatively simple concepts. Much of this C code could be laughably simple in Forth, even the multi-threaded code; the code would probably shrink in size by at least a factor of ten, if not more. That's got to be worth exploring. I have not found a good implementation to try this out. I think it could run on a much less powerful embedded CPU than the one that it now requires. Even the exercise of refactoring into Forth words would surely teach me something about the refactoring I already attempt to practice.
* OCaml, Haskell, Erlang, D, Lua, etc. Perhaps worth looking at. So
many languages, so little time.
* NewtonScript?. To implement my own version; to play with. It could
be interesting to model the parent-proto inheritance concepts in a different language. If I could do something to contribute towards an open-source revival of the Newton, that would be great, but it is a little bit beyond my capabilities, what with the hardware engineering and prototyping.
If I could do some networking, produce some prototypes or code that I could use to get a new job, contribute to an open-source project, or use some of this code to further my weblog or other projects, that would be great too.
I'm looking at a few different languages now, primarily languages that allow at least some facility to create DSLs (Domain Specific Languages) and allow metasyntactic extension (macros). Here are the ideas, in no particular priority, broken down by language:
* Weblog Tools
I have a love-hate relationship with blosxom, my weblog software. It's Perl, which I loathe, but Perl made it very easy to install and allows it to use extensions in a uniform way. It's frustrating to extend and customize.
I've got a vague plan to build a weblog framework in Dylan, called Dybbler. I'd start by attempting to implement Markdown in Dylan. There's a basic web platform, called Koala. But I'm also told that it is not very far along, and that the startup time for d2c application code makes it frustrating to use compiled Dylan programs as CGI scripts.
It will also be difficult, if not impossible, to deploy a Dylan CGI on my ISP's site, at least without renting a dedicated server, so it would be an internal experiment for the time being. It might be possible to buy a fixed IP and host my own weblog at home, but I'm not sure I want to take that all on at once, what with security issues, spam and zombie attacks, and all that fun.
I'd like to arrange a better publishing mechanism. It would be nice if I could mail myself weblog entries and get them posted automatically. I spent a little time last night messing with my IMAP mail server and the Ruby IMAP support class. It was laughably easy to log in and walk through the messages and get header information, but the method to actually retrieve the message text seems to be either missing in action or obscure beyond belief.
In general, I'd say that the "let a thousand flowers bloom" world of web frameworks, Wikis, blogs, etc., is not really converging, something better is around the corner, and it isn't C# and it isn't Java.
* Embedded and Small Server Tools
I've got a bug up my rear end also about the need for more advanced tools in embedded systems. Java, including hardware Java implementations like ARM's Jazelle, seem promising, but as Peter Housel put it, once you've taken the red pill (using truly powerful languages), it is awfully hard to go back. A typical industrial embedded application is so mind-numbingly badly designed and over-implemented, it seems like there must be plenty of wasted memory and CPU to reclaim for the sake of using a rational toolset. One question I haven't seen answered adequately is whether I can build Dylan, Scheme, Common Lisp, or Ruby applications for a platform upon which I want to forbid not only garbage collection, but dynamic allocation altogether. Allocate everything on startup, and never cons, and never GC. It seems like this ought to be possible. Maybe a DSL Lisp dialect specifically for embedded code?
I'm also interested in seeing what I can get running on a Kuro Box ($160 micro-server platform). Could I get a JVM, SISC, web server, and database running on one of those things, to allow me to build a web application in Scheme, implementing state with continuations? What about using Common Lisp or Ruby on Rails? Any of these projects could turn into a useful article; all of them together could make a book.
* The Book
Then, there's the book idea. I've long wanted to write a book on Dylan programming and the Gwydion project. It might be more valuable to do a book on the Lisp family of dynamic languages for GUI, scripting, and web applications.
* And All the Rest
It seems like I'm proposing a lot. What I'm really trying to do is find my next job, one that I might enjoy doing. That's about it.
Oh, it would be nice to go back to school and get an advanced degree in computer science, but it would have to be a place like MIT or CMU that would teach me something useful about language implementation and design. And I'd have to get paid while I went, while still having time to raise my children. And I want to teach English, Math, Computer Science, and write science fiction too. And play Stick. Hmmm. One lifetime is starting to look like not quite enough. Maybe I could give up sleep. Maybe this is some kind of midlife crisis? I guess if you don't have goals you'll never get anything done; the key is deciding what to give up on.Tue, 04 Jan 2005 Programming Projects, Part 1
Now that our life is settling down slightly, I'm trying to see if I can set some learning goals in the area of learning, and possibly doing something useful with, Lisp-ish languages.
Last night I got SLIME + Emacs working with SBCL on my PC running Fedora Core 2. It is perhaps strange to say, but despite programming for so many years I've never learned Emacs, and in fact barely learned vi. I was reasonably proficient in vi at one point, when I used it to do some complicated multi-stage regexp-based search and replace, but whenever I'd try to dig into Emacs I'd quickly get hit with a wash of key remappings, startup scripts, and complications.
Key mappings are like obscure command-line switches that vary between UNIX dialects to me in that I tend to forget them rather quickly. I've finally used CVS often enough that I remember the basics, but most of my paid work has been with co-workers that don't tend to know, trust, or want to use command-line tools.
In my work developing drivers for MacOS? X I was using specific command line tools (like kextload and various kernel debugging tools) all the time, but it was really uphill convincing people to use CVS at all, even with a GUI front end, which had some annoying limitations. Trying to get the other developers to use CVS on the command line was a complete non-starter. Prior to that, in working on MacOS? 9 tools, there wasn't a command line (unless one wanted to use the somewhat orphaned MPW tool suite, which I didn't, preferring to use the Metrowerks CodeWarrior? suite that I was familiar with).
Apple also had, to some extent, a philosophy of leaving behind the command-line world with everything in text files, preferring binary data for file metadata and resources, and a scripting mechanism that tries to abstract out the particular scripting language itself and access application data via a hierarchy of callbacks done by unwinding something that could almost be considered binary s-expressions. I drank that Kool-Aid, writing code to support AppleScript?; it is all very interesting and very powerful, but also somewhat narrowly confined to its own niche, and like many ideas that are too complicated in execution for the average programmer to embrace, probably will remain so.
Believing that the whole world is Windows, though, many Windows programmers without wider experience are, if anything, even more provincial. They may not even be aware that their beloved Microsoft Visual Whatsis can be executed at the command line and that underneath it all there are basically Makefiles, albeit a species designed for non-portability.
It also probably has something to do with never having really teethed on UNIX when I was younger. Pre-college, I used word processors running on the TRS-80, Apple II, and Commodore 64; in college, I used (for coursework) VAX systems, running the VAX editor on VT100 or other terminals; for extra-curricular projects I used Mac systems, running what was variously called THINK or Lightspeed Pascal and C. During my senior year, I believe, the college put in a small UNIX box of some kind, but aside from becoming confused by key mappings and trying the various items in the games directory, I never really got the hang of it. Emacs always seemed like one of those infinitely configurable but endlessly complicated things like X-Windows; sure, I could somehow read mail and news and everything else in my editor, just like I could allegedly share all my directories between boxes and run GUI applications across the network, but there was rn and mail, so what was the point?
Anyway, I say this all by way of expressing my trepidation over embracing Emacs. I feel more comfortable in either the full-blown IDE mode with an environment like Macintosh Common Lisp, or directly at the command line. Emacs feels like something in between - excessively customizable, and excessively complicated. But if this is what is needed to learn Lisp macros, I'll give it a shot.
So what am I trying to accomplish again? More on that next time.Thu, 29 Jul 2004 Functional Developer Opens Up!
I found out today that Functional Developer, the flagship Dylan compiler and IDE, has gone open-source. That's exciting news. It even applies to all the extra libraries that Functional Objects used to sell.
Of course, it is a huge project, and it now leaves the Gwydion project in a unique bind: they now have two high-quality, advanced, and extremely large codebases to work with. The two are "compatible" only in that most of the straight Dylan code involved is at least largely portable, modulo compiler and library bugs. Some of it has already been used with the Gwydion d2c compiler. That's something. So, where to start?
I took a shot at compiling the Ravensbrook memory management codebase. This required a few tweaks to suppress warnings, but seemed to work after that. That's just the beginning, though. Functional Developer has a full-blown GUI for Windows, and an alpha-level command-line compiler for Linux. It hasn't been ported to MacOS X yet. They don't even have full build instructions for Linux yet. The MacOS X port would be a great project to work on, but it is also quite intimidating. Porting the IDE would involve a complete implementation of the DUIM libraries. That could be valuable for both compilers. And it appears that someone has done at least preliminary work on generating PowerPC instructions!
But Dylan is already fragmented within the d2c project, because of the separation between the byte-code interpreter, Mindy, and d2c. Mindy's main use these days seems to be in boostrapping d2c. There's another interpreter project, Marlais, which seems to be at least marginally active; it is a true interactive interpreter, but I'm not sure how well it works at the moment. And of course there's the buggy and abandoned Apple Dylan, which won't run in emulation under MacOS X, and is even more unstable than usual under MacOS 9. That one's out of the game, but lives on in spirit.
For the moment, I should just try to finish my somewhat derailed Dylan sample code project, and consider what I could do with a PC running the full version of Functional Developer, together with all the optional libraries, on Windows. I don't have the PC, but maybe a suitable machine will magically arrive on my doorstep. Stranger things have been happening recently. But would it allow me to do anything that would help me find a good job? Would it contribute anything useful to the Gwydion group? Or would it just distract me from my job search? I'll meditate on that and see where it leads me.Sat, 17 Jul 2004 Queens and Knights
I've become aware of a job opportunity in Cambridge, MA. The company offering the job want to see a programming example. They recommend solving one of two problems posted on their web site. This one looked the most interesting to me. They say:
Unless otherwise specified, you may use any language you like for the programming problem. If you send code for a problem, please include the final answer in the body of your email and please send code that actually compiles and runs, so we can test it -- no pseudo-code please. If you're submitting a program, try to make it as efficient as possible.
Queens & Knights
In 1850, Carl Friedrich Gauss and Franz Nauck showed that it is possible to place eight queens on a chessboard such that no queen attacks any other queen. The problem of enumerating the 92 different ways there are to place 8 queens in this manner has become a standard programming example, and people have shown that it can be solved using many different search techniques.
Now consider a variant of this problem: you must place an equal number of knights and queens on a chessboard such that no piece attacks any other piece. What is the maximum number of pieces you can so place on the board, and how many different ways can you do it?
I was just recently going through old papers and looking at a solution to the Knight's Tour problem I wrote for a computer science class in my sophomore year of college. The Knight's Tour asks for a "tour" in which the knight, using his unique L-shaped move, touches every square on the chessboard once and only once. My program allowed the user to specify the size of the chessboard (there are "degenerate" cases; obviously, on a 1x1 or 2x2 board the knight cannot move; on a 3x3 board the knight either starts in the center square and is stuck there, unable to move, or starts on an edge square and can quickly hit all the edges but can't get into the center).
I ran solutions up to a 10x10 board, but this was about eighteen (!) years ago, and the code was written in Pascal for the VAX 11/750. I can't remember if the 10x10 solution ever completed. The standard 8x8 board took some time, perhaps an hour or more, depending on the load on the system. My fellow students and I took great joy in all firing off our programs at once and watching the system crawl. I put in diagnostic output which would dump out an ASCII representation of the board in progress, and as you may guess, the I/O was much more expensive than the search, and so the runtime would increase by at least an order of magnitude.
We were studying recursion, but deep recursion in VAX Pascal was dicey: deep searches tended to blow up the stack. A follow-up assignment for some classes was to implement the solution using a hand-rolled stack data structure, which was considerably more efficient. I don't think my class implemented that program; we did something else with stacks. In any case the lesson taught, inadvertent or not, was that was recursion was a powerful tool for performing a brute-force search of a problem space, but "real" programs would not use it because building and unwinding the program call stack is expensive and the program is likely to run out of stack space.
Now I know that VAX Pascal probably didn't properly optimize tail recursion. I've got several other programming techniques and more expressive languages at my disposal these days. So I'm going to take on the Queens and Knights problem and see what I can come up with. I have friends that would probably try it using a genetic algorithm or a purely functional language like Clean, but I'm not quite to that point; I'm going to write it in Dylan, using the Gwydion implementation. I'll first re-implement the Knight's Tour to warm up, using a naive technique, and then see if I can start to improve the run time.
You can follow my efforts on my Wiki here.
P.S.: I have an initial Knight's Tour implemented, using a combination of iteration (to track starting positions) and recursion (to backtrack) along with a table of offsets to describe the moves. This took me about one work day, so I've certainly come a ways since 1986. The Gwydion d2c compiler is still frustratingly slow, although using a BBEdit worksheet helps; it doesn't quite have a real-time listener for writing and testing functions interactively, like Apple's Dylan did (and yes, I'm familiar with d2c's interactive mode; it is still too slow and fragile). I'd like to try this using Functional Objects Dylan, but I don't have access to a working PC at the moment, and the free version is missing some basic library functions (I believe format-out is missing, for example, unless you pay for at least the minimal console libraries package).Mon, 01 Sep 2003 Second-guessing the Compiler
So, did you hear the one about the programmer who decided to rewrite all the logical tests of the form
if ((x) || (y))
if !(!(x)) && (!(y))
On the grounds that the PowerPC uses "NAND gates," where the Pentium used "AND gates," so the second expression would run faster on PowerPC hardware?
When I heard this, it caused me to utter some kind of sound... I don't remember the details, but I think it involved spraying coffee all over my monitor.
Of course, the two are logically equivalent (work out the truth table for yourself, if you don't believe me). I don't have any idea whether there really is a difference in the performance of OR logical operators on the PowerPC. I sincerely doubt it, keeping in mind that even the assembly instructions are abstract, as far as the hardware is concerned, and I don't have any way of knowing what is really happening in the hardware when a simple OR test is executed. If the hardware chose to execute the OR comparison using NOT and AND, I'd never know, and wouldn't care. But the second one certainly looks a lot more obscure, and that was the programmer's real point. (The "baffle 'em with bullshit" defense; if it looks complex, it must be complex; it will be harder for someone else to maintain; perhaps it will ensure job security.) (Don't bet on it; if anyone who worked under my supervision wrote this without a very good reason, he or she would be out on his or her ass).
It gets better. CodeWarrior is pretty good compiler. It looked at this code, and determined, pretty much as a human could with a little thought, that it made more sense to reduce the code to a simple logical OR. So that's what it did. So even if the original programmer had been right, the processor wasn't executing the logic he wrote. He hadn't looked at the resulting code. So there was, for yet another reason, no reason to write it that way.
Now, the people who wrote CodeWarrior's optimizer aren't dumb. It has undergone years of tweaking by very smart people. If there was some great optimization to be gained by rewriting logical operations to support the PowerPC's "NAND gates" more efficiently, they would have implemented it; it would be described in the PowerPC documentation, to guide compiler writers; and programmers would be griping about it. IBM and Motorola have a vested information in getting optimization advice out there, to make their chips appear more competitive. There isn't a reason to rewrite the logic like this, so they didn't.
If you've been living under a rock and haven't heard: optimize after you get it working. Optimize what you can measure. But the best initial optimization you can do on your code is to design it well and express it clearly. After you've tested it, crank up the compiler optimizations and test it some more. Measure its performance. Profile the hot spots. Optimize those parts. It doesn't make sense to waste effort optimizing instructions that are only executed once, during the startup of the program, which is not noticeably slow. If your program is slow on a modern CPU, it is far more likely that you are doing something wrong algorithmically: looking up some information by traversing a long linked list every time a function is called, for example, instead of using a more efficient structure such as a tree or hash.
Don't get me wrong: there's a place for serious hand-optimization. I've worked hard to hand-optimize DSP assembly code in order to reduce the number of cycles necessary to restart a disconnected data transfer across a PCI bus. I've tweaked interrupt routines to block for as few instructions as possible. I've also worked to determine why a program that draws animated meters is using thousands of times more CPU time than I expected. (Because it was drawing far too much, far too often, due to a bug that was easy to find by single-stepping the code with a source-level debugger). But in these cases I had some way, even if it was an imperfect way, of measuring the results. And you can bet your ass I was carefully commenting the code to explain why the implementation no longer appeared to be as simple and straightforward as possible. Not just to benefit some abstract future maintenance programmer; that maintenance programmer could be someone I know and love - myself.Tue, 05 Aug 2003 Dylan
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.