... until the collector arrives ...

This "blog" is really just a scratchpad of mine. There is not much of general interest here. Most of the content is scribbled down "live" as I discover things I want to remember. I rarely go back to correct mistakes in older entries. You have been warned :)


Thoughts on Java

Java is my most recently acquired programming language.  I cannot yet claim fluency, but that fact alone is not enough to prevent me from having some strong opinions.   For the most part, I enjoy programming in Java.  It strikes me as a language which is a reasonable compromise between (say) C++ on one side and Smalltalk on the other.   By that I mean that it retains the strong-type checking (mostly) of C++, and the dynamic behaviour (mostly) of Smalltalk.

I can't resist but to moan about some features that I wish were in Java.   Actually, I could go on at length, but my most-wished for feature is the ability to return multiple values from functions, and my least desired non-feature (bug?) is the unfortunate rules for resolving (that is, prohibiting) member name collisions when implementing two or more interfaces.

Virtually every language I have used support some way to return multiple values from functions -- at least those languages that have the 'function' concept.  Lisp supports the concept directly.  In C, you can fake it by passing pointers to variables that receive the values.  In Java, there is no simple way to achieve this -- but there are work-arounds.  I see quite a few people have a function which returns an array of values (the old pre-Common Lisp trick).  Simulate the C trick by passing in single elements arrays to receive the values.  Still others declare a class whose sole purpose is to hold the return values.  All of these gimmicks require dynamic allocation of storage to perform the value return.  With language support, value return could be performed on the stack.  Of course, compilers are getting smarter all the time -- maybe a good Java compiler could detect the case and optimize.   Now, if we could only get rid of the large per-class overhead in Java...

I won't get in to the debate about whether Java should have allowed proper multiple-inheritence or not (oops, just did), but there is an annoying restriction in Java when it comes to implementing multiple interfaces.  If two interfaces declare a member with the same name, it is flagged as an error!  I would rather that in such an event the programmer would be forced to explicitly disambiguate the conflicting members by prefixing them with their class names.  This exact strategy is actually used for similar purposes in the Java 1.1 inner class features.  Of course, the implications now are significant.  Not only would the compilers have to handle this case, but (I believe), the VMs as well.

Of course, I can pile on many, many, more requests, like multi-methods, templates, better namespace management, and on and on, but you can't have everything.  Or you can, but then it gets stuck in the ANSI and ISO committees for years and years and years.

For all my moaning, Java is definitely a 'fun' language to use.  It feels very comfortable to me, reminiscent of the old MacPascal days...

Thoughts on C

C is a nice little language.  The syntax is, well, weird.  People often complain about the parentheses in Lisp, but at least parentheses have only one meaning.   In C, parentheses can mean grouping, casting, or function call -- and probably other things that don't leap to my mind immediately.  Most of the other symbols in the ASCII character set have meaning as well.

Syntax aside, I think that C pretty well encapsulates everything that a basic procedural language can do.  For the most part, it would be hard to improve, and remain procedural.  Having said that, when I was programming in C, I couldn't help but drool over some of the features available in other languages, especially C++ and Lisp.   Neither of these languages were readily available on the platforms that I was using at the time.  So, I resolved to add some of the juicier features to C as a library.   The CS module was the result.  I can't remember why I chose the name CS, but I think it stood for either 'control structures' or 'condition system'.  The principal goals of the library were to make resource management and error handling easier to do.  The two main features were resource owners, roughly analogous C++ destructors or auto_ptrs, and a condition system, strongly influenced by the Common Lisp condition system.  You can read the CS documentation for yourself, or browse the source: cs.h and cs.c.

Using the CS module, I found that I enjoyed programming in C much more because most of the headaches related to pointer management were handled for me.  Furthermore, I could do proper error handling without having to check the error return values of every function I called.  But, my enjoyment was short-lived because other, more interesting languages, soon became available to me.

Error-handling has always been a pet peeve of mine.  Prior to the CS module, I used a simpler set of macros to aid in error detection and reporting.  The macros were defined in trace.h and I have included a sample program to show how the macros were used.  Note particularly lines like this:

C("Parse the supplied block length.")

This is an 'executable comment'.  The macro would tuck the comment away somewhere so that when an unrecoverable error occurred, it was possible to get a meaningful error message -- meaningful, at least, the someone with ready access to the source code.   When such an error occurred, the system would display the most recent executable comment from each stack frame.  I found the resulting error messages to be extremely helpful when troubleshooting failure modes in software, whether those modes were due to a bug in the software, transient system conditions, or user error.  For example:

An unforeseen error has occurred in this program.

main (153) Perform the operation.
atp_read_files (0) Scan the files on the tape.
atp_scan (0) Position the tape device.
atp_position (93) Position the tape forward the required number of tape marks.
Numeric info = 22
Possible cause: Invalid argument

Reading this traceback, one might guess that the program was trying to scan beyond the end of the last tape mark.  Or not.

Thoughts on LISP

Lisp is probably the closest thing to my ideal language, of those that I have actually used.  Note that I said 'closest thing to' and not 'is'.  Of course, the concept of 'ideal language' is flawed, because it immediately begs the question of what it is that you are trying to do in the first place.  But, I feel most comfortable programming in Lisp and my productivity is the highest in that language.

It is hard to pick my favourite feature of Lisp.  It might be one of:

  • The compiler is extensible.  I can easily develop my own language tailored to the problem at hand -- so long as that language looks Lispy!
  • The interactive programming environment allows one to build complex applications incrementally.  It is common to leave the application under development running for a whole programming session.  Changes can be incrementally applied to the running application.
  • The list and symbol data types are nice, syntactically lightweight, data structure for lots of purposes that one might use strings for in other languages -- but much more convenient.

But, alas, these features come at a cost.  Here are some things that I do not like about Lisp:

  • The run-time overheads are large.  A 'Hello, World' program might have a 2 megabyte footprint and a 10 to 20 second start-up time.  I suppose I should ignore such trivial issues as memory and disk usage these days, but old habits die hard.
  • The development and run-time environments are hopelessly entangled.  It is difficult to completely jettison the development scaffolding from the final shipping product.  This comes back to the 'overhead' issue.  Apple tried to fix this one in Dylan.
  • The Common Lisp standard says that all declarations (except SPECIAL) can be ignored by a given Lisp implementation.  Most implementations ignore my favourite declarations -- the 'strong typing' ones.

My journey with Lisp began in earnest when I attended a class in University, namely Computer Science 312:  Theoretical Computer Science.  The whole course was taught using Lisp.  I was a little bewildered by the material in the course, but something about Lisp caught my eye.  Later, I was casting about for a project to undertake with my new Lisa computer.  I decided to implement a Lisp interpreter.   Well, actually I acquired a Lisp interpreter written in Pascal from the Internet.   Regrettably, I cannot recall whose it was.  I played with that interpreter for a while, but I found it lacking in some areas that interested me, so I tweaked it a bit and sent my changes back to the author -- who was pleased to see that someone was using his work.  My next try was David Betz' XLISP.  This was written in C, a language I did not know at the time.  I translated the interpreter into Pascal, which went remarkably smoothly.  In fact, most of the translation could be done using global search-and-replace in an editor.  Finally, using what I had learnt in these two Lisp implementations, I was ready to dive into one of my own.  The result was Minilisp, which bears a close family resemblence to XLISP.

Professionally, my employer's main product needed an embedded interpreter for scripting.  My first attempt was an assembly language-like interpreter, which we quickly outgrew.  I then built a simple procedural compiler for that assembly language.  Again, it was just too difficult to write any scripts of note.  The product was written in FORTRAN, so I didn't really relish writing a Lisp interpreter -- even though that was the 'right' answer.  In end, I decided that the effort would be worth it and, after much study of John Allen's excellent Anatomy of Lisp, I produced a SterneLisp.  We were quite satisfied with the capability  that this scripting language gave us, so the successor product was designed with a Lisp scripting language in mind.  The last interpreter that I wrote was SMALL, written in C.  I had grand plans for a follow-on interpreter and compiler (to C), but by then quality Lisp implementations became available on the platforms that my company used, and the need diminished.   Ironically, our experience with Lisp for scripting was so positive, that a commercial Lisp compiler was used as the primary development language for all of the company's products ever since.  That is, until Java came along...



What is OOP?

OOP stands for Object-Oriented Programming.

OK, what is Object-Oriented Programming?

Who knows?  Not me.  There are lots of theories.  Here are some:

  • Some programmers think that OOP means Smalltalk, i.e. Our Only Programming-language.
  • Some programmers think that OOP means Hypercard or its successful sibling, Visual Basic.
  • Some programmers think that OOP means that constructors must be stored in tree structures.
  • Some programmers think that OOP means that systems should be built using only unary operators.
  • Some programmers think that OOP is a fancy word for 'subroutine'.
  • Some salesmen think that OOP is shorthand for 'our company employees programmers'.

:-) For my part, all I can say is OOP usually involves an object system.

What is an object system?

An object system is a database which stores closures.  Each closure in the database has a key which consists of a signature and zero or more objects.  The object system has operations which support the adding new closures to the database, recovering closures given a key, and removing closures from the database.

What is a closure?

A closure is a function with no free variables.  More often than not, closures in object-oriented programming systems are called 'methods'.  I have purposely avoid using the term method to avoid conjuring up any pre-conceived notions about issues such as method lookup.

What is a function?

Let's not get in to that.  I don't mean anything mathematically precise by this.   In particular, I do not wish to imply anything about the presence or absence of side-effects or even determinism.  I could just have easily said procedure or subroutine.  I will take the notion of function as self-evident.

What is a signature?

All functions accept parameters of certain data types and return values of certain types.  They also have certain set of semantics.   Collectively, the types and semantics are called the 'signature' of a function.   It is an unsolved problem in computer science to find a way to express the semantics of a function in some concise way.  As a result, most programming systems are content to summarize the semantics of a function by giving it a name.  Thus, the signature of a function is reduced to its name and data types.

What is a free variable in a function?

A free variable in a function is a reference to an object that is not defined in the function, e.g. the function

int getNextValue()
    x = x + 1;
    return x;

has references the variable x, whose definition is elsewhere.  Note that, in this context, any parameters to the function are not considered to be 'free variables' since the function cannot be invoked without specifying values for those parameters.

But programmers often write functions with free variables - how do they become closures?

It is the task of the object system to convert functions to closures.  This is done by supplying values for each of the functions free variables.  There are a many ways to do this.  For example, here are some programming languages and their strategies:

Language In... Free variables can be bound to...
C all functions global variables
Java all methods other class members
Pascal all functions global variables
nested functions variables in enclosing blocks
C++ all functions global variables
all member functions other class members
Smalltalk all methods object or class variables, global/pool variables
blocks variables in enclosing blocks or methods
LISP all functions global variables, or "special" variables in the call stack
nested functions variables in enclosing blocks
generic functions object or class slots

It is in this way that you can view an object system as a storage system which, when given a reference to an object and the signature of a function, returns an appropriate closure.  In languages such as C, there is only one object -- the implicit 'global' object.  Languages with an object system allow (or demand that) the programmer supply an explicit object.  Some object systems (e.g. the Common Lisp Object System, CLOS), even allow the programmer to specify more than one object when looking up closures.  However, CLOS and similar systems cannot be properly called object-oriented, but rather something like closure-oriented or method-oriented.  In passing, I will note that my view is that OOP is an intermediate stage on the way to the more general closure-oriented programming.

The interesting part of an object system is its closure look-up mechanism.  The fun begins when a closure key is sought in the database and is not found.  In the procedural languages (e.g. C, FORTRAN), a compile-time, link-time, or run-time error is signalled.  Other languages have more recovery mechanisms, for example:

Language Other places to look for closures (methods)
Simula an object's class and superclasses
Beta a pattern's subpatterns (i.e an object's class and subclasses)
C++ functions generated from templates
Lisp lots of places, including user-defined ones

What is a data type?

A data type is an arbitrary collection of function signatures.  If you detect a certain circularity between the definitions of signature and data type, then you have put your finger on another unsolved problem in computer science.  Fortunately, the circularity does not appear to cause difficulties in practice.  The difficulty is usually resolved by having certain built-in data types that have special properties and That Is Just The Way It Is.

Note that if an object is viewed as an arbitrary collection of closures then an object is of a given data type if for every signature in the data type the object has a closure with a matching signature.

Some programming languages, the strongly-typed ones, check the data types of objects as early as possible (e.g. compile-time).  To do this, they typically constrain the 'arbitrary collection of signatures' somewhat.  For example, in Java the signatures must all belong to a single class (or its superclasses or superinterfaces).  Other languages, the weakly-typed ones,  place no such restrictions and defer type checking to a very late stage (e.g. run-time).  For example, in Smalltalk a data type is called a 'protocol'.  There is no formal language support for protocols but any object can potentially support any protocol.  This yields significant flexibility in exchange for more onerous testing requirements.

What is an object?

An object is an arbitrary identifier used as part of a closure-key in an object system.   Therefore, one can roughly view an object a collection of closures.  I say 'roughly', because some object systems permit zero objects or more than one object to be used in a key.

If one looks 'under the hood' of an object system, one might find that the term 'object' has a much more concrete meaning.  For example, in C++ an object is a block of storage allocated specifically for holding the variables associated with a set of closures and a pointer to a jump table for the code blocks for those closures.

How do objects get created?

By far, the most common techniques employed by object systems are to delegate object creation to a class or prototype.

What is a class?

A 'class' is a kind of object which creates other objects.  Usually, a class object is handled specially by the object system in question.  User-defined classes often leverage the built-in class functionality of an object system, but sometimes they are designed from scratch and then called 'factories' to distinguish them from the built-in variety of class.  In general, a class is an object with three closures:  one which creates an object, one which locates a closure for an object given a signature, and one that destroys an object which was created by the first closure.

Most of the details of a class are private to the object system's implementation.   For example, the class will arrange for any necessary storage to be allocated for the object and for that storage to be released when the object's life is over.   Beyond, creation and destruction, there are not many more operations that are common to all object systems.  Some object systems allow classes to be grouped into hierarchies and to automatically delegate certain functions to classes which appear higher in the hierarchy.  Other object systems delegate functions to classes which appear lower in the hierarchy.  Still other object systems dispense with the concept of hierarchy and permit arbitrary delegation.

What is a prototype?

A 'prototype' is an object which can clone itself.  Some object systems, such as those in the languages Self and Javascript, rely on cloning as the normal way to create objects.  A single object is created and then has its structure modified procedurally.  Then that object is duplicated as many times as needed.


The Story So Far...

The Muse has spoken and compelled me to write down my history -- at least from the standpoint of computing. If you can tolerate the self-indulgence that this implies, I hope that you will find a tidbit or two to make the effort worth it.

It Begins

I can make an arguable case that my interest in computers stems from too much T.V. as a kid -- particularly such wholesome shows as Doctor Who, Fireball XL5, and Stingray. Whatever the cause, high-tech gizmos, particularly computers, have fascinated me for as long as I can remember.

In my first year at school, I can recall filling the inside covers of all of my notebooks with hand drawn pictures of spaceship control panels, and spending time pressing the buttons and pulling the levers instead of learning the subtleties of telling time or solving equations more complicated than 1+1+2=?. (That 2 would always throw me -- I was okay so long as we confined the discussion to 1s).

My computer reality stopped being virtual when I was around 12 or 13. My mother brought home this wonderful device called CARDIAC. This ingenious little package contained a book which described machine-language programming (1973-style). It also contained -- a computer! Granted, the computer was made of cardboard and relied on an external power and logic source (me). But it was a fully-fledged computer with something like 32 bytes of RAM, a CPU with a dozen or so op-codes, an accumulator, a program counter, input and output tapes, and other assorted goodies. I could write machine code programs and hand execute them. It even had an assembly language, but I had to hand-translate the assembly code into machine code. The manual had a program that played the game of NIM. NIM is played with a number of sticks with players taking turns picking up one, two, or three of the sticks. A player cannot pick up the same number of sticks as his opponent just did. The player who takes the last stick loses. I was amazed that one could write a program that did such a complicated thing as play this game. I was further amazed that CARDIAC could play a better game of NIM than I. Even though I understood all of the individual instructions of the program, I never quite made the mental leap to understand the whole.

Around the same time as CARDIAC, I began watching a weekly telecourse made by Boeing Corporation which taught the BASIC programming language. Now here was something I could sink my teeth into! Alas, CARDIAC did not have a BASIC interpreter and, even if it did, I would probably still be hand executing that first program to this day. My solution was simple: the local university and technical college both ran open houses twice a year. The computer science departments would allow mere mortals such as myself to not only approach but actually touch teletypes attached to mysterious, distant computers. And guess what: these computers spoke BASIC! My first BASIC program ever was almost certainly:

20 GOTO 10

The whole concept of a computer-generated random number fascinated me. How could a computer compute a random number? Here was a concept that was well beyond anything I could grasp. Now I had a printout with a few hundred random numbers on it to help me contemplate this strange problem. (It didn't help.)

And so it became a regular ritual for me to go to these open houses and pester the poor attendants to let me have much more than my fair share of time at the teletype. One such attendant stood and fumed for over an hour while I printed out the entire listing for the 'empire' game that he was otherwise showing off to attendees. Another time, I went to a demonstration which had two teletypes connected to each other, rather than to a computer. I immediately set up camp on the one which was in a corner away from the main area. That whole afternoon, I simulated being the computer to many astonished visitors -- and to the great amusement of the attendant. This was a trick that I would play many times in the following years, especially to newbies at university. I actually had one fellow talking to his terminal and scouring the room looking for television cameras. It was actually more believable for him that he was talking to one of HAL's cousins than to the guy a couple of seats behind him. Call me cruel...

As my familiarity with BASIC grew, another development occurred which gave me access to computers which understood it. Companies started bringing a new class of computers to market -- personal computers. Furthermore, a shop opened here in Calgary that actually sold these things! A friend and I would hang out at this place, talking the proprietor out of lots of glossy brochures even though he knew there was no sale to be had. I would drool over the specifications of such powerhouses as Altairs, IMSAIs, and Polymorphics. All of these were upscale versions of my CARDIAC. They implied machine language programming, usually through a front panel. At the time, I thought this was cool. It is a good thing that I did not have enough money to find out if it was.

Eventually, I got a computer that actually ran on electricity. It was a TI-59 programmable calculator. This state of the art piece of equipment set me back my life savings up to that point -- around U$350. But it was a dream machine! It had something like 1000 memory locations which could be divided between program and data. And it could store programs that I had written on a small magnetic card!

An Account of my Own

My big break came when one of more assertive members of our high school nerd clique suggested that we approach a friendly teacher to see if he could swing some arrangement with the University of Calgary granting us computer access. Amazingly enough, he could. Before I knew it, I found myself going to the University every night after school to write FOCAL programs on a PDP-8 running the TSS-8 operating system. Now here was a truly awesome piece of equipment, with capabilities well beyond anything I had ever dreamed of. It even had a hard disk. Of course, there was not enough space on the hard disk to store our little programs. The scratch space on the disk was wiped clean every night so we had to be sure to write our programs onto paper tape before we went home. We envied the university students who were actually permitted to store their programs on magnetic tape.

FOCAL is a very simple language, similar in scope to BASIC. I recall that one of the features of FOCAL was that you could abbreviate all of the keywords to a single letter -- which we all did since we could neither type nor program well enough to worry about such issues as readability. I reproduced the random number program and quickly moved on to more sophisticated fare such as printing out prime numbers. The largest program that I wrote in FOCAL was a rip-off of the board game Stock Ticker. A few people that I knew became addicted to the game and spent far too much time hunched over a teletype playing it.

At this time my mother worked at the university and, as an employee, was entitled to an account on the university's CDC computer. I soon assumed ownership of that account. The CDC was impressive. I had seemingly endless permanent disk space. The CDC understood BASIC, my language of choice. There were a few high speed Decwriter terminals (300 baud). And the CDC ran my prime number program orders of magnitude faster than the PDP-8.

I spent a large fraction of my evenings through high school in the CDC terminal room. Most of that time was spent writing increasingly complex programs in BASIC. Most of those programs were games of one type or another. BASIC was beginning to frustrate me more and more. The CDC's dialect of BASIC was restricted to variable names consisting of a single letter optionally followed by an integer. As my programs grew in sophistication, this restriction became intolerable. Many other languages were available on the CDC, including PASCAL and FORTRAN. A friend of mine was a strong advocate of PASCAL, but I found the manual to be difficult reading -- especially all that talk of pointers. FORTRAN, on the other hand, seemed like 'BASIC done right'.

In BASIC I had been working on a two-dimensional variant of the classic lunar lander program. It was on this project that I found that I was quickly running out of meaningful variable names. But in FORTRAN, I could use names like FUEL, THRUST, ANGLE, XVELOC, and YVELOC. Furthermore, I could give names to my subroutines -- no more GOSUB 7000. And pass parameters to subroutines! And I did not need to give every line a number! FORTRAN was like a dream language. I could not imagine how any other could top it.

The lunar lander program, SHUTTLE, was the first computer game I wrote that I really liked. It enjoyed modest popularity among the CDC's users. Reportedly, 80-odd copies of it were found scattered across the computer's disks. Found by whom, you say? The University's computing administration took a dislike to games after a friend of mine ported one of the endless variants of 'Star Trek' to the CDC. Rumour has it that copies of 'Klingon', as he called it, filled an entire disk pack. At that time, a disk pack represented virtually limitless storage to most users. Rumour further has it that the administration wrote a program that deleted any file with the word 'Klingon' in it but the program was lost when run because it deleted itself!

By this time, our high school computer club was growing in size and was receiving more assistance from the University. Back on the TSS-8, one professor lectured us on voice synthesis. He had developed a text-to-speech facility and tried to explain the theory behind it. I am sure that most of what he said went over our heads, but we did pay close attention to the special syntax required to generate sounds. After all, who could resist the urge to have a computer say such profound statements as 'Live Long and Prosper' or 'I Grok Spock'?

Later, another professor introduced us to some other computer languages. We were able to play with some languages which broke the procedural mold of BASIC. One thing about BASIC that I liked that FORTRAN did not do well was string handling. But SNOBOL left BASIC completely in the dust. Not only did string variables in SNOBOL behave 'as God intended', but pattern matching was a primitive in the language. Unfortunately, the SNOBOL interpreter was quite slow and, in any event, the language was a little too radical for my procedural brain.

Another language we were introduced to was SIMULA. For me, learning SIMULA was when the lights came on about records (aka structures, user-defined data types, etc.) At first it was a bit of a stretch: "But why wouldn't you just use a set of parallel arrays?", said the BASIC programmer -- a question that I would not repeat five years and 100,000 lines of FORTRAN later. You can only call subroutines with 37 array arguments so many times! SIMULA also had that mysterious pointer type again. I almost understood it this time, but it seemed strange to use a linked list when a perfectly good (read, 'easy') array would do. When all you have is a hammer, every problem looks like a nail...

At the time, I thought I had a really good handle on the facilities of SIMULA. Little did I know, there was a whole world waiting under there that I didn't even dream of: object-oriented programming. Alas, that would have to wait a while (and for about 100,000 lines of FORTRAN).

My 'Klingon' friend also became enamoured with APL. He was a pure mathematician, and I think that the primitives of APL, not to mention the character set, matched the symbology that he saw when he closed his eyes. For my part, I thought it was cool to be able to write a program that nobody else would ever be able to read. But other than that, the language held little appeal for me.

There were soon other advances in my computing environment. Strange new paperless terminals began to appear in the terminal room. I had no concern for saving trees but the CRT terminals could display characters at 4800 baud. Suddenly, I felt a certain inadequacy in my typing speed. Before, I wasn't that much slower than a teletype. Okay, okay, I could not type at 11 characters per second, but those teletypes just seemed to be terribly slow. But the CRTs were blindingly fast. Now, my typing was a significant bottleneck in the programming process. I quickly added a typing class to my high school curriculum. If any class that I took in high school has paid huge dividends, that was it.

I might have thought that 4800 baud CRT terminals were the apex of technology, but the reality of computer-related change began to sink in rather rapidly. Soon, the University acquired 9600 baud terminals. The speed in itself was nice, but the truly remarkable capability was cursor-control. By sending some rather arcane strings to the terminal, you could put the cursor anywhere on the screen. Anywhere! The applications were endless, but I could only think of one: video games! In junior high school, I had read an article in Time magazine about a game called 'Life'. The article concentrated on how this rather silly program had captivated full-grown university students, but in a sidebar recounted the rules. I recall whipping out my chessboard and manually playing a few generations. But now, with cursor control, the computer could do it for me. In all, I spent far too much time programming variations on the Life theme, looking for ways to speed the computation and display of generations.

A Computer of my Own

When 1977 rolled around, I noticed that the computer store that I still hung out at from time to time began to get in a new class of personal computers. These machines were not programmed from front panels, but had keyboards, displays, tape drives, and even floppy-disk drives.

Uh-oh. Have you noticed how serious an effect surfing can have on people's attention spans? The muse is abandoning me...

Last updated 1998/12/01. To be continued...


  1. The Muse? Which Muse? The Muses were the nine daughters of Zeus and Mnemosyne. They were originally the godesses of memory, but soon acquired individual areas of responsibility:
    • Calliope - epic or heroic poetry
    • Clio - historical and heroic poetry
    • Euterpe - music, joy, and pleasure
    • Thalia - comedy and pastoral poetry
    • Melpomene - tragedy
    • Terpsichore - dancing and dramatic poetry
    • Erato - lustful poetry
    • Polyhymnia - singing and lyric poetry
    • Urania - astrology

    It is left as an exercise to the reader to identify the Muse doing the moving.


I did some thinking about the shape of our product in C++.  I wrote a header file with all of the principle classes.  As usual, I began to worry more and more about the ownership of the objects which represent models, queries, and compiled queries.  The thought struck me:  what about using Java to implement SQL generation?  Java is pretty stable on the Win32 platform.  Microsoft has committed to delivering the new VJ6 in September -- VJ6 can create both EXE and DLL com servers.

Java has these advantages:

  • It is garbage collected -- no ownership issues.
  • It has excellent COM support on Win32.
  • It is potentially cross-platform (e.g. to meet one of our customers's requirements, or to plug into Oracle's Java framework).
  • It is 'hot', for marketing purposes.

Here are some disadvantages:

  • There is a run-time component, namely the VM.

Here are some apparent disadvantages, with rebuttals:

  • Java is young (read 'flakey').  To implement SQL generation, we will not have to access the rapidly changing portions of Java (e.g. AWT, JFC, etc.)  Java, the language, is solid on the Win32 platform.
  • Java is slow.  Query generation is not compute intensive.  Even if it were, JIT technology brings Java execution to within a factor of 2-3 to C++ for even compute intensive operations.


I worked on the LISP->ActiveX scripting bridge.  I discovered that CT:DEFCSTRUCT will accept the :UNION keyword (as documented on ACL page 1-3-9), but the keyword is apparently ignored.  All members are allocated at different offsets.

An Allegro CG bug:

; The following form demonstrates a problem with the TRACK-BAR control. It
; creates a track-bar and attempts to set the direction to :DOWN. When the
; dialog is opened, the direction is reset to :UP. This is because the
; CG:DEVICE-OPEN method for a TRACE-BAR-PANE receives an option list
; which has the stream options in front of the widget options. The
; stream option :DIRECTION :IO is shadowing the widget option :DIRECTION :DOWN.
(let ((item
      :widget 'cg-util:track-bar 
      :box (cg:make-box 78 58 124 233) 
      :direction :down 
      :orientation :vertical 
      :range (list 0 100)
      :value 0
   (print (slot-value item 'pc::direction))
   (cg:open-dialog (list item) 'cg:dialog cg:*screen* :pop-up-p nil)
   (print (slot-value item 'pc::direction))

Blog Archive