Bradley Lucier wrote:
I've studied the Gambit source code a bit, and even made some contributions over the years, but Marc's programming style is something I have not seen elsewhere---highly macroized and layered, there are patterns in the coding techniques but not ones that I've been able to unravel in general. Perhaps one way to help new developers get into Gambit would be fore Marc to take a subsystem and write down an explanation of how the macros and layers of code for types, exceptions, constructors, functions, ... of that subsystem work.
Speaking as someone who has ported Gambit once and simply couldn't port it a second time, the sheer amount of indirection is incredibly painful.
The thing is ... I think it's a *scheme* thing, or, perhaps more accurately, a Scheme-implemented-in-C thing.
If you dig under the covers of any of the actually useful schemes, they *all* have these painful levels of indirection. If you try to implement a scheme, you wind up creating similar levels of indirection the moment you hit the hard features like continuations, tail call optimizations, GC, etc.
I tried looking at various schemes for porting to embedded hardware. I was looking for something with a useful core that is around 1-2 KLOC. That's what all the "Schemeophiles" claim it takes to implement a Scheme.
They lie. It simply doesn't exist. Everything is 10 KLOC (and, really, that's so useless that you really need about 50-60 KLOC) and up and they all have incredibly painful amounts of indirection.
Sure, there are lots of small "schemes". Either they are metacircular and leave the tough stuff to an underlying scheme (not useful, thanks for playing), or they always have something that doesn't work: tail-calls are broken, continuations don't work, the macro systems are hosed, etc.
And, one of the things which I think contributes is the fact that the advanced features make other features more indirect. For example, tokenizing and parsing a Scheme expression is quite obnoxious using C. However, once you get continuations running, it is a big win to pull that code up from C into Scheme itself, pass the result back and hold the partial parse in a continuation. Of course, now the parser has this particularly opaque indirection in the middle of it that makes it hard for newcomers, but allowed the original maintainer to wipe out several hundred lines (at least) of C parsing code that really didn't work for a lot of corner cases anyhow.
Any scheme that becomes useful seems to be be very large and accumulates lots of indirections in the implementation.
-a