Older blog entries for crhodes (starting at number 56)

The lisp system I work on, SBCL, sometimes shows its age. Although SBCL per se has only been around for five years or so, it is an evolution from CMUCL, itself an offshoot from Spice Lisp, which was started in the early 1980s, borrowing from the heritage of 1970s lisps.

Given this history, it's not entirely surprising that the codebase (200kloc of lisp, plus about 10kloc of C and assembler) isn't 64-bit aware. However, today's applications are definitely nudging the space requirements; Lisp is apparently "big in bioinformatics", and fairly obviously there they'll want to be dealing with large databases.

So, a couple of months ago, Dan and I had a quick hack at porting our existing alpha backend (which was originally crafted as a 32-bit application) to be fully 64-bit. We got far enough to be executing plenty of lisp code, but not quite up to the point that the REPL was functional.

Time passed. Various bugs in the alpha backend were fixed, and so (why not?) I tried again yesterday, merging the previous branch with CVS HEAD. After conflict resolution, the addition of the necessary specialized array types, and three or more bugfixes (plus commenting out of things that break weirdly):

/entering TOPLEVEL-REPL
/about to set up restarts in TOPLEVEL-REPL
/entering REPL
* (* 2 3)

6 * most-positive-fixnum

11520460975

Waitaminute! That doesn't look nicely big enough for a 64-bit lisp. Well, not quite everything is working, despite getting to the REPL; here, the printing routines are slightly broken. The most positive fixnum is meant to be (1- (ash 1 60)) (leaving four bits for tagging objects); that number is 1152921504606846975. So, compare and contrast

1152921504606846975
1152xxxx0460xxxx975

Other things that appear not to work include the compiler itself; clearly, the utility of a compiler-only implementation of 64-bit lisp without a functioning compiler might be viewed as "limited". Since I'm technically unemployed at this point, I'm taking offers of funding...

Thesis minus 8 days.

I tell a lie: it wasn't that bad after all.

Thesis minus 23 days.

Ow ow ow.

There are days when it might be better not to get out of bed, at least in a metaphorical sense.

On the plus side, we are now thesis minus 28 days. Is that a plus? that doesn't sound like a plus. can't wait 'till it's over, though, and I have some free time, or a job, or something of that sort.

Pfffff.

Bugs bugs bugs... some of which were nastily difficult to track down. Particular embarrassments:

  • (ash (1- (ash 1 32)) -40) no longer returns 1;
  • (round 1.3) no longer trashes the stack;
  • (truncate 291351647815394962053040658028983955 10000000000000000000000000) now returns 29135164781, not 29135164782.

How does one find how to fix these bugs? Sometimes by observing strangenesses, and applying binary search to the system until the problem's origin is sufficiently well localized. Sometimes, though, just by thinking very hard...

It is at times like this, though, that the benefits of a test suite are very obvious — if only because some fixes can be deferred on some architectures, while remaining secure in the knowledge that the issue won't be lost.

Inevitably, as one gets nearer to the end of one's funding for any given project (in my case: doctoral studies) one finds less time for peripheral activities. In my case, the first out of the window was keeping this diary up to date: I can offer no apology to the masses of addicted readers other than "sorry". Somewhat more painfully, I've let my music lapse (apart from paying gigs or favours); I haven't even found time to bash through piano duets with another physicist.

I haven't yet managed to kick the Lisp compiler addiction, though. Highlights of the last two months: MacOS X port merged; implementing an ANSIly-correct (stupid) array type structure without any impact on user code; improvement in compiler diagnostic handlability; and a data structure improvement leading to a 25% performance increase in the compiler.

Microoptimizations are the most fun, though; right now, I'm working on implementing automatic detection of when modular arithmetic (as is the default in e.g. C, where overflow wraps round) is wanted, and also optimizing constant multiplies (which, on the x86 processor, is a tricky problem). Obviously, what I should be doing is writing up my thesis...

Rencontres Mondiales du Logiciel Libre

Otherwise known as the Libre Software Meeting. This year, after Bordeaux declined to host it on grounds of organizational difficulties, it was held in Metz; since they started organizing it late, it's not surprising that there were one or two hiccups in the smooth functioning, but there was fortunately nothing which interfered with sitting en terrasse and sampling beers.

Most of the action that I was expressly there for was the dubiously-titled "Very High Level Languages for Writing Applications" track, which in practice was a bit of an excuse for several Lisp bigots to get together and plot the next stages of world domination. Mostly this involved talking about real-time garbage collection, but the demonstrations of McCLIM and especially Marc Battyani's FractalConcept Web Application Framework were very impressive.

Also useful was meeting several researchers who, while not following our track, were nevertheless using Lisp to do neat stuff; Axiom and Maxima developers were on hand to inform us that we needed to implement reliable callbacks from C to Lisp in the next six months.

Apart from that, I managed to avoid most of the politics (not all!) by taking a day to go to visit Strasbourg; highly recommended (though avoid cafés on the Place Kleber; they're overpriced and the beer isn't as good). Then 8 hours of train back to good old England.

So while I'm waiting for the fuss^Wdiscussion about (VECTOR NIL)to die down on comp.lang.lisp, here's a new version of CLX.

"What is CLX?", I hear you cry. CLX is, roughly speaking, Xlib for Lisp. It is an implementation of the client-side of the X protocol. So, why "roughly speaking", then? Well, mostly because by all accounts programming for raw Xlib is extremely painful, whereas the macrology of Common Lisp allows syntactical abstractions to be built, allowing for ease of development.

For instance, the WITH-BUFFER-REQUEST macro allows for rapid implementation of extensions to the X protocol. In fairly short order, we have acquired implementations of the SHAPE, RENDER and XVidModeExtension (sic) extensions, so we can make Lisp applications just as pretty as their counterparts.

And, oh look, something nasty did happen to the guys wearing red.

* Krystof sighs at the irony in CLHS 15.1.2.2
<pfdietz> And its interaction with the rules for upgraded array element types?
* pfdietz realizes that those bizarre NIL arrays are strings!

Most Common Lisp implementations purporting to conform to the standard have only one internal representation for strings: it simplifies the logic; it allows for fast string access (no need to do a type test to see how big each string element); it makes type derivation easy. Several implementations can talk different representations, but internally, they're canonicalized to ASCII, UCS-16, UCS-32 or whatever.

Sadly, since we've previously deduced that arrays specialized to hold no objects must exist, and since strings are defined to be vectors specialized to hold a subtype of character, vectors specialized to hold objects of the NIL type are indeed strings.

Aargh. I have a working prototype, but there are going to be plenty of issues involved in sorting this out. At least they're mostly the same issues as would be involved in dealing with the Unicodization of SBCL, so it's not wasted work. It might even encourage me to do some more refactoring to share more code among the six backends.

Quiet. Too quiet. This is usually the time for something nasty to happen to the guys wearing red.

In our case, that means pfdietz comes along, with his mutant superpower of "being able to read the ANSI specification", and blasts holes in implementations. Since the last time I complained about this nasty habit of his, he's made some other unwelcome discoveries: some more stuff about array element type upgrading; some nastiness about keyword argument checking in various protocol methods; SLOT-EXISTS-P being required to work on condition objects (even though nothing else from the CLOS machinery is required to do so); and much else besides.

On the other hand, much has changed for the better in the SBCL world. In addition to the native threads implementation and the ability to build from CLISP, we have an integrated implementation of CLOS (no more bogus CL:CLASS/SB-PCL:CLASS distinction) and consequently a mostly-compliant MetaObject Protocol; an accurate type system, which is in use to do sophisticated type inference at compile-time; and we're up to 10 contrib modules, including an efficient implementation of MD5, a friendlier read-eval-print loop, and an improved extensible stream framework.

Was that worth waiting a month for? I think so.

Busy busy busy (yes, with real work, too).

On the other hand, I have had the time to do enough mindless debugging to enable SBCL to build using CLISP as a cross-compilation host.

Remember way back, when we were looking at ensuring that SBCL didn't actually have any leakage from the cross-compilation host to the target code, so that in fact the sources, and not whatever compiler you happened to be compiling the sources on, determined the nature of the resulting executable? Well, OpenMCL was a decent enough first choice, because it was based on mature technology and had a suitably non-painful debugger.

So there wasn't going to be anything terribly fundamental about making it work under CLISP; "mindless debugging", I said. The process did pick up one or two real portability bugs (depending on the initial element of an uninitialized array, for instance); some annoying portability bugs (CLISP gives a full WARNING on function redefinition, which plays havoc with detecting failures), and one real leakage:

CLISP has a value of MOST-POSITIVE-FIXNUM of 16777215, unlike CMUCL, SBCL and OpenMCL which all have a value of 536870911. This lower value was leaking through into some type declarations, which were then erroneously signalling errors. Fixing this made it all worthwhile: now SBCL can build, in a slightly roundabout way, on a system with only gcc installed. Oh, yeah, and several bugs in CLISP were exposed and fixed as a result of this exercise, too.

In other news, SBCL has native threads on x86/Linux. Cool.

47 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!