iGloo: Mixing in a Mixin

In OO, a “mixin” class is a class that’s intended to add a particular feature to any number of other classes via multiple inheritance. You wouldn’t generally subclass a mixin class by itself; it’s just something you add in where it’s needed.

TIP 257 supports mixins directly: for any class you can provide a list of the classes that it mixes in. The relationship isn’t the same as the superclass relationship, even if that’s how mixins are done in C++; it’s all about calling order. Here’s the difference: it’s all about the order of method chaining.

Suppose I have two classes, dog and bigdog, where bigdog is a subclass of dog. Further, both classes define a bark method:

oo::class create dog {
    ...
    method bark {} { return "Woof!"}
}

oo::class create bigdog {
    superclass dog
    ...
   method bark {} { return "WOOF!"}
} 

% bigdog create spot
::spot
% spot bark
WOOF!

What happens is that bigdog‘s bark simply replaces dog‘s bark in all bigdog objects. But suppose we wanted to use dog‘s bark; we just want to make it LOUDER. Using method chaining, we could define it this way:

oo::class create bigdog {
    superclass dog
    ...
   method bark {} { string upper [next] }
} 

The next command chains to the method of the same name in the parent class; you can pass any arguments you like. In this case, next calls dog‘s bark, which returns “Woof!”; bigdog upper cases it to “WOOF!” and returns it. Thus, the subclass can do some work, call the same method in the parent class, and then do some more work. We say that bigdog‘s bark wraps dog‘s bark.

With mixins, the order is the opposite. The main class gets all of the mixin class’s methods; and the mixed-in methods can chain to the main class’s methods. Suppose you wanted to print a trace of all method calls on a particular object. You could do that like this:

oo::class create dog_logger {
    method bark {} {
        puts "Entering bark."
        next
        puts "Exiting bark."
    }

    method wag {} {
        puts "Entering wag."
        next
        puts "Leaving wag."
    }
}

oo::class create dog {
    mixin dog_logger

    method bark {} { puts "Bark! Bark!" }
    method wag  {} { puts "Wag! Wag!" }
}

dog create spot
spot bark
spot wag

Running this script yields the following output:

Entering bark.
Bark! Bark!
Exiting bark.
Entering wag.
Wag! Wag!
Leaving wag.

Very interesting, and useful.

I do have some questions about mixins that aren’t answered in the TIP. The main one involves constructors and destructors. In my tests, the mixed-in class’s constructor never gets called; I imagine its destructor never gets called either. It would appear that if the mixin has any state that needs to be initialized, it must provide an initialization method which the main class needs to call explicitly, within its own constructor. I’m not at all sure whether I like this or not, but I think it’s probably workable. I do suspect that a class really has to be designed as a mixin if it’s to be used effectively as one.

Shadow of the Hegemon, by Orson Scott Card

This, the immediate sequel to Ender’s Shadow, continues the story of Bean and the other Battle School graduates in the world that follows after the end of the Formic War. In the former book, Bean has a vision of a world in turmoil as all of the political ambitions which were held in check by the need to present a united front are suddenly cut loose. In this book, the turmoil begins as all of Ender’s top commanders, his “jeesh”, are kidnapped as precious military resources. Bean manages to stay free, and sets out to free his comrades as the world situation spirals into war.

On the whole, this isn’t quite as good a book as Ender’s Shadow. Bean spends a lot more time reacting than acting (though to be fair he has to rely on adults to get anything done, and they usually have their own ideas). It isn’t nearly as moving, either. That said, it’s still quite an enjoyable ride, with plenty of action and intrigue, and of course it’s the second volume of a four volume set. Middle volumes are by their nature less interesting than either the first of the last volume in the set. Further, according to the afterword the material in this book and its successor were originally intended to be covered in a single volume. So all things consideredShadow of the Hegemon succeeds pretty well.

I’ll definitely be getting the third and fourth books in the series.

iGloo: Type Variables and Type Methods

In Snit, you define types; types then have instances. To use a canonical instance, you define a dog type, and then create dog objects. You can define methods and instance variables; and you can define type methods and type variables. Here’s an example:

% snit::type dog {
    typevariable count 0

    typemethod count {} { return $count }

    constructor {args} {
        ...
        # Increment the number of dogs
        incr count
        ....
    }

    destructor {
        # Decrement the number of dogs
        incr count -1
    }

    ...
}
::dog
% dog count
0
% dog spot
::spot
% dog fido
::fido
% dog count
2
%

Here we write a type that keeps track of how many instances it currently has. The point is that type variables are visible without declaration in instance code (e.g., constructor, destructor, and method bodies). In addition, type methods can be called by instance code via the $type command.

Supporting this under TIP 257 is tricky. In Snit, every instance belongs to exactly one type. There’s no ambiguity as to where an instance’s type variables and type methods reside: they reside in the instance’s type.

Under TIP 257, any object has immediate access to its own methods via the my command, and to its instance variables via the my variable command. It can discover its own namespace using namespace current or self namespace, and access its variables by fully qualified paths. The one thing the object doesn’t have easy access to is the class to which it belongs; and so it’s unclear how the object can unambiguously call methods of its class or access its class’s variables.

Just what does a TIP 257 object know about its class? It can retrieve a class name using the self class command; but according to the tip, this returns “the name of the class that defines the currently executing method.” Thus, if the currently executing method was defined by a superclass of the object’s class we get the superclass name rather than the actual class name. So self class is no help.

However, it appears that info object class does the right thing. So our object could call methods on its class in this way:

    [info object class [self]] methodName

Ugh. Sure, it works, but it’s ugly. Further, it means that the object can only access its class’s exported methods, although I can think of cases where an object might want to call some of its class’s unexported methods as well–methods that implement some private resource shared by all instances of the class.

I’ll note in passing that it’s possible to change an object’s class dynamically. (This makes my brain hurt!)

So what about class variables? The only handle we’ve got is the name of the class’s own private namespace. Given the name of that namespace, we can use the class’s my variable command to bring its variables into the current scope. In fact, we can then use the class’s my command to call any of its methods, exported or unexported. And if we were to alias the class’s my command into the object’s namespace as myclass, we’d be really set.

The problem is finding out the name of the class’s namespace, because you can only do that in the class’s own code. I think what iGloo would have to do is pass the fully-qualified name of the class’s my command into each object as it is created; the object can then alias it into its own namespace as myclass. But then, if the object is given a new class we’re in trouble.

Bottom line: In my opinion a myclass command, defined as above, makes a lot of sense. But I think it needs to be defined explicitly as a part of TIP 257; otherwise, it’s too hard to handle all of the edge cases (as when an object’s class is changed).

iGloo: Delayed Creation

One of the particular problems that’s been bugging me is the issue of creating megawidgets in iGloo. A megawidget, of course, is simply an object that acts and looks like a widget; and for an object to act like a widget, it has to have a real Tk widget at its core. The process goes something like this:

First, you decide what to call your widget, remembering that there are definite constraints on what a widget can be called. For the sake of argument we’ll create a widget called .text.

Next, you create a real Tk widget with that name, to serve as the hull of your megawidget:

text .text

Next, you rename the real widget something else:

rename .text _.text

Next, you create your own command called .text. This command should pass most of its subcommands to the hull (_.text), and define any new or modified subcommands it chooses.

proc .text {method args} {
    .
    .
    .
    _.text $method {expand} $args
    .
    .
    .
}

You’ve now got a megawidget, more or less. (As always, the devil is in the details.) I call this process of replacing the widget’s command with my own command hijacking the widget command.

The question is, how can one write a TIP 257 object that does this? It’s a little bit more involved, because you already have a command name when you enter the constructor. Consider the following code snippet, which is part of some code to create a read-only text (rotext) widget:

    constructor {args} {
        my variable hull

        # FIRST, rename [self] to something else, temporarily
        set self [self]
        rename [self] ::_temp$self

        # NEXT, create the Tk widget (remove the ::)
        text [namespace tail $self] {expand}$args

        # NEXT, rename the Tk widget
        set hull ::_$self
        rename $self $hull

        # NEXT, put self back
        rename ::_temp$self $self
    }

As you can see, you need to move your chosen window name out of the way, then create the Tk widget, then move it out of the way, and then put your own command back again. This code works, but it has two problems: first, it doesn’t allow you to hijack a previously existing widget, which is sometimes handy. And second, look what happens when you create your widget:

% rotext .text
::.text
%

Whoops! When you create a TIP 257 object, you get a fully-qualified command name! But when you create a Tk widget, you get back the window name. It’s true that .text and ::.text name the same command; but the first is a window name and the second isn’t.

The problem here is that by the time we enter the constructor the object has already been created. What we’d like is the chance to do a little work before the object is created. And the way you do that is by redefining the rotext class’s create method:

    self.method create {win args} {
        # FIRST, create a text widget with the desired name.
        # (We could also hijack a widget that had already been
        # created.)
        text $win

        # NEXT, rename it to something else.
        set hull ::_$win
        rename $win $hull

        # NEXT, create a new object with the original name, 
        # passing the new name to the constructor.  Note that
        # we add the "::" to make sure the command is created in
        # the global scope.
        next ::$win $hull {expand}$args

        # NEXT, return the bare window name
        return $win
    }

    constructor {theHull args} {
        my variable hull

        # FIRST, save the hull
        set hull $theHull

        # NEXT, pass the options to the hull
        $hull configure {expand}$args
    }

First, we use self.method to define a new create method for our class. We create a text widget, and rename it. Then we use the next command to invoke the superclass’s create method; this will create the object and call its constructor. We insert the Tk widget’s new name into the argument list. The constructor then grabs the Tk widget’s new name and saves it in the instance variable hull, and passes the widget’s options to it.

It remains to redefine the insert and delete methods, and forward the other methods to the real text widget. Here’s the complete example: rotext.tcl.

iGloo: The “mymethod” command

The Problem

It’s common for Snit objects to register callbacks with other objects. For example, a snit::widget might create a Tk button; when the button is pressed, the callback should call one of the widget’s methods. The naive way to do this in the widget’s constructor would be this:

$button configure -command [list $self ButtonPress]

Here, $self is the name of the widget, and so the widget’s ButtonPress method will be called whenever the $button is pressed by the user.

Now, this code will work fine–right up until the moment the programmer decides to rename the widget, as might happen if the programmer applies a snit::widgetadaptor to it. Consequently, Snit provides a way to build callback commands that will continue to call the correct Snit object even if the object’s name changes. The mechanism is the mymethod command:

$button configure -command [mymethod ButtonPress]

mymethod takes the method name, and any additional arguments the programmer cares to provide, and returns a command that’s insensitive to name changes. I won’t go into how the trick is done; it’s ugly (and, by the way, thanks to Andreas Kupries for getting it working right). The question is, what’s the easiest way to do this in the TIP 257 environment?

The “my” Command

In Snit, an object calls its methods via its $self variable, which contains the current name of the object. TIP 257 provides the my command instead. my can be thought of as an alias to the object’s command, an alias that’s always available and never changes its name. That’s not completely true, but it’s good enough for now. Now, every object has a Tcl namespace associated with it; and it happens that my appears as a command in that namespace. By fully qualifying my with its namespace, we gain a command that references the object, whose name won’t ever be changed, and that can be called from outside code. Thus, the following code would do the trick:

$button configure \
    -command [list [self namespace]::my ButtonPress]

We can wrap this in a proc, like so; this will work just fine provided that the proc is visible to the object’s code:

proc mymethod {args} {
    linsert $args 0 [uplevel 1 [list self namespace]]::my
}

And then, there are any number of ways we can make it visible. One slightly tacky method is to put it in the ::oo::Helpers namespace; this namespace is made visible (by namespace path) to all TIP 257 objects. (I call it slightly tacky because it effects all objects, and because the existence of the ::oo::Helpers namespace isn’t part of the TIP 257 spec, at least at the moment.)

A Bonus

There’s a bonus to using this method. In Snit, there’s no real distinction between private and public methods, i.e., methods defined for use solely by the object itself for its own internal processing, and methods that form part of the object’s public interface. TIP 257, however, has the notion of “exported” and “unexported” methods; the latter can only be called using the my command, and hence are reasonably private. But since mymethod as defined above makes use of my, this means that an object’s callbacks can call the object’s unexported, i.e., private methods–which is usually exactly what you want.

iGloo: A Different Kind of Snit

I recently was able to get a hold of a build of Donal Fellow’s Object-Oriented Programming extension for Tcl, familiarly known as “TIP 257“. I helped come up with the spec for TIP 257 last year, but just as no battle plan survives first contact with the enemy, so no software design spec survives implementation unchanged. Consequently I’ve been spending the last few days getting familiar with the revised spec.

The primary goal of TIP 257 is to provide a fast, minimal OOP implementation for the Tcl language which can be used directly and which can also serve as a foundation for significantly less minimal frameworks. One of those less minimal frameworks is my own Snit package, which is available as part of Tcllib. Currently, Snit is doesn’t depend on TIP 257; there are two reasons for making it do so, speed and functionality. Snit is highly optimized, but there are some things that are just slow. TIP 257 does considerably more in C, and consequently should be faster at these things. Second, as object systems go Snit provides the bare bones; for example, it doesn’t allow inheritance (which would be seriously nice to have on occasion). Snit-on-257 might really be Snit-on-steroids.

Now, I’m confident that I can build a Snit-workalike on top of Donal’s API (after all, I can build it without Donal’s API). But there are a number of questions whose answers I need to discover. What compromises and workarounds am I going to have to make to duplicate Snit’s precise syntax and semantics? If I end up with something that has no additional speed and no additional features, there’s no point in it. If I aim at something Snit-like but not precisely identical, can I do significantly better? Are there holes in 257 where a little more functionality would be a really big help? Are there aspects of 257 that cause me serious problems?

To answer these questions, I’m embarking on a project called iGloo, a name I came up with a couple of years ago when Snit was gaining in popularity and I had begun to wish I’d called it something else. If I decide that it’s worth doing a perfect clone of Snit on top of 257, iGloo might just be a research project. If I decide that perfect compatibility with Snit is too constraining, iGloo might go on to be Snit’s replacement. Either way, it should be fun.

The 50 Most Significant SF&F Books

Michael came across this list of the 50 most significant SF&F books of the last 50 years at this website here; apparently the list came from somewhere else, though it’s not clear to me where. The books are listed in order; I’ve bold-faced the ones I’ve read, and added some comments. I’ve put “+++” by the ones I’ve read multiple times, “—” by the ones I’ve read but didn’t much like, and “000” by the ones I’ve read that I can’t remember anything about. As you’ll see, I’ve read 40 of the 50, and at least tried to read most of the others.

  1. +++ The Lord of the Rings, J.R.R. Tolkien.
  2. +++ The Foundation Trilogy, Isaac Asimov.
  3. +++ Dune, Frank Herbert.
  4. +++ Stranger in a Strange Land, Robert A. Heinlein.
  5. +++ A Wizard of Earthsea, Ursula K. Le Guin.
  6. Neuromancer, William Gibson. I started this one, and hated it,
    and never finished it. This almost never happens.
  7. +++ Childhood’s End, Arthur C. Clarke.
  8. Do Androids Dream of Electric Sheep?, Philip K. Dick. I’ve
    read a little of Dick’s work, and didn’t like it, so I never tried
    this one.
  9. The Mists of Avalon, Marion Zimmer Bradley. I’ve read a fair
    amount of Bradley’s “Darkover” series; I’m not sure why I’ve never
    read this one. It seems to be targetted more at women than men, though.
  10. Fahrenheit 451, Ray Bradbury.
  11. +++ The Book of the New Sun, Gene Wolfe.
  12. +++ A Canticle for Leibowitz, Walter M. Miller, Jr..
  13. The Caves of Steel, Isaac Asimov.
  14. Children of the Atom, Wilmar Shiras Never heard of this one.
  15. +++ Cities in Flight, James Blish.
  16. +++ The Colour of Magic, Terry Pratchett. Though this is hardly the best of the series.
  17. Dangerous Visions, edited by Harlan Ellison.
  18. Deathbird Stories, Harlan Ellison.
  19. +++ The Demolished Man, Alfred Bester.
  20. Dhalgren, Samuel R. Delany. Couldn’t get through this one, either.
  21. +++ Dragonflight, Anne McCaffrey.
  22. Ender’s Game, Orson Scott Card. The short story is better.
  23. +++ The First Chronicles of Thomas Covenant the Unbeliever, Stephen R. Donaldson.
  24. 000 The Forever War, Joe Haldeman.
  25. Gateway, Frederik Pohl. I’ve never read anything by Pohl that
    I cordially liked.
  26. +++ Harry Potter and the Philosopher’s Stone, J.K. Rowling.
  27. +++ The Hitchhiker’s Guide to the Galaxy, Douglas Adams.
  28. I Am Legend, Richard Matheson.
  29. — Interview with the Vampire, Anne Rice.
  30. +++ The Left Hand of Darkness, Ursula K. Le Guin.
  31. Little, Big, John Crowley. I’ve tried to re-read this several times, and never gotten very far. Interesting, but I don’t think I ever really understood what was going on.
  32. +++ Lord of Light, Roger Zelazny.
  33. The Man in the High Castle, Philip K. Dick. See above.
  34. Mission of Gravity, Hal Clement.
  35. More Than Human, Theodore Sturgeon. I don’t remember whether
    I’ve read this one or not.
  36. +++ The Rediscovery of Man, Cordwainer Smith.
  37. On the Beach, Nevil Shute. Oddly, I’ve not read this one; I
    tried it when I was far too young, and didn’t like it. I ought to
    give it another try.
  38. +++ Rendezvous with Rama, Arthur C. Clarke.
  39. +++ Ringworld, Larry Niven.
  40. 000 Rogue Moon, Algis Budrys.
  41. +++ The Silmarillion, J.R.R. Tolkien.
  42. 000 Slaughterhouse-5, Kurt Vonnegut.
  43. Snow Crash, Neal Stephenson.
  44. +++ Stand on Zanzibar, John Brunner.
  45. The Stars My Destination, Alfred Bester.
  46. +++ Starship Troopers, Robert A. Heinlein.
  47. +++ Stormbringer, Michael Moorcock.
  48. — The Sword of Shannara, Terry Brooks.
  49. Timescape, Gregory Benford. Like Pohl, Benford does nothing
    for me.
  50. — To Your Scattered Bodies Go, Philip Jose Farmer.

Something Rotten, by Jasper Fforde

This is the latest of Fforde’s very funny “Thursday Next” series, which also includes The Eyre Affair, Lost in a Good Book, and The Well of Lost Plots. In this book, Thursday returns to the Real World after an absence of two-and-a-half years. She’s got Hamlet, Prince of Denmark in tow; it seems that he and Ophelia have had a falling out, and Ophelia needs a little space. Meanwhile, page-runner Yorrick Kaine is trying to take over England with the help of the Goliath Corporation, and Thursday’s time-hopping father needs her help to prevent the resulting world cataclysm. In short, it’s a typical Thursday Next book.

The first of the series was outstanding; the second was also quite good; the third had its problems; and this one does too. In particular, it starts slowly–say that again, even more slowly–so slowly that it took me several weeks to get through it. The ending was OK, and I’m curious to see what comes next; but action-wise, this book is clearly the low point in the series to date.

Fun With Perspective

Ted the Test Lead has impressed on me that it’s very hard to take good architectural pictures with a standard camera (unless you buy a really expensive perspective-correcting lens). Here’s an example of what he’s talking about.

20061018-165655.jpg

I took this picture from across the street. Note that the left-hand side of the building and the flag pole are both vertical in this picture, as they should be….but the rest of the building looks remarkably funny.