Saturday, September 27, 2003

Agile Taguchi

When I think about it, I can see that Agile methods are aiming for a software equivalent of the Taguchi Method from product engineering. As I, Cringely says:

Taguchi's objective is robust design, which means building a product, system, or process that works well even in the presence of degrading influences. That means products that deliver value without breaking and services that are enduring while being as simple as possible. Taguchi first determines the control factors that go into designing a product, their interdependencies, then generates an orthogonal array specifying the number of experiments required to find the optimal solution.

If the last paragraph reads like Esperanto to you, maybe that explains why mainly eggheads have been attracted to Taguchi. The short version is that however they work, the Taguchi Methods can take a project with thousands, even millions of combinations of variables, and quickly reduce it to a couple dozen simple experiments that can be run simultaneously and will determine the cheapest way to achieve a goal. Instead of considering one variable at a time, Taguchi is able to test many variables at once, which is why the number of tests can be so small. It's a bloody miracle. Taguchi not only shows the right way to do something, it also tells you what the cost in dollars will be of doing it the wrong way.

Unfortunately, no one yet knows how to generate such an array for a software product. (Or, perhaps, it is just me that doesn't know how to do this.) You can make a feature array, but software is much more than a blob of features. But anyone able to apply the Taguchi Method to software would produce the greatest software ever—ever. And become richer than Bill Gates in the process.

Drive an SUV today

I'm reading a debate on if Java is an SUV of computer languages because there are too many ways to do things (it is not orthogonal enough). If Java is an SUV, then what does that make C++—an aircraft carrier? Of course, Python is a sleek racing machine in comparison.

Monday, September 22, 2003

Copyright notice

All code published on this blog is Copyright (C) B. K. Oxley (binkley) <binkley@alumni.rice.edu> effective the date of publication under the terms of the GPL version 2 unless otherwise noted.

Live from Chicago! Iterators, generators

Java has it wrong. The iterators in the Java Collections Framework are not actually iterators: they are generators. The real culprit is next() which does two things at once. It advances the iterator and then fetches the value therefrom. This is the generator model.

Contrast with iterators from the STL. Because they model a pointer, they have a separate advance and fetch operation implemented with operator++()/operator++(int) and operator*(). You may freely advanced an STL iterator without fetching the contents; and you may fetch and refetch the contents without needing to adjust the position of the iterator. Of course STL iterators do have the wart that they lack any hasNext() equivalent. Instead you have to carry around a second iterator to compare against to see when you've reached the end.

Why is this? It is because Java is paradigm-poor language while C++ is a paradigm-rich one. Java supports object-oriented programming and that is the end of the tale. C++ supports object-oriented programming, but also generic programming. STL iterators are definitely a generic idiom, not an object-oriented one. But Java has to fit an object-oriented shoe onto an iterator foot, so they compromise by using generators instead, objects which produce a new value upon request.

Incidentally, this is why remove() is so weird and has to be optional. Optional methods to an interface are a sign of design mismatch. There should instead be a Generator base interface with just hasNext() and next(), and a CollectionGenerator which extends Generator and adds advance() and get(). Implementors of CollectionGenerator simply write next() to call advance() and then return get(). To modify the underlying collection, extend CollectionGenerator further and add remove().

Thursday, September 18, 2003

ListIterator and List equivalent

A ListIterator is equivalent to the List interface. To demonstrate this, I'm writing a IteratorList class which implements the List interface over an underlying ListIterator; it's actually quite simple. More fun with iterators! Here it is (note, not tested—I just wanted to sketch it out to see what it'd look like):

/*
 * IteratorList.java
 * Copyright 2003 (C) B. K. Oxley (binkley)
 * <binkley@alumni.rice.edu>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 * Created on June 4, 2003.
 */

package hm.binkley.util;

import java.lang.reflect.Array;
import java.util.AbstractList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * <code>IteratorList</code> implements <code>List</code> from an
 * underlying <code>ListIterator</code>.
 *
 * @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a>
 * @version 1.0
 */
public class IteratorList extends AbstractList {
    /** The underlying list iterator. */
    private final ListIterator it;

    /**
     * Constructs a <code>IteratorList</code> code from an underyling
     * <code>ListIterator</code> object.
     *
     * @param it the list iterator
     */
    public IteratorList(ListIterator it) {
	this.it = it;
    }

    /**
     * Resets the underlying list iterator back to its starting state.
     */
    private void reset() {
	while (it.hasPrevious())
	    it.previous();
    }

    /**
     * Positions the underlying iterator before <var>index</var>.  The
     * caller needs to then call {@link #next()} as required.
     *
     * @param index the index
     * @throws IndexOutOfBoundsException if <var>index</var> is out of
     * range
     */
    private void scrollTo(int index) {
	if (index < 0)
	    throw new IndexOutOfBoundsException();

	// Ensure we call one extra next for the index itself
	while (index-- > 0)
	    if (it.hasNext())
		it.next();
	    else
		throw new IndexOutOfBoundsException();
    }

    /** {@inheritDoc} */
    public int size() {
	int n = 0;

	for ( ; it.hasNext(); ++n)
	    it.next();

	reset();

	return n;
    }

    /** {@inheritDoc} */
    public Object get(int index) {
	try {
	    scrollTo(index);

	    if (it.hasNext())
		return it.next();
	    else
		throw new IndexOutOfBoundsException();
	}

	finally {
	    reset();
	}
    }

    /** {@inheritDoc} */
    public Object set(int index, Object element) {
	try {
	    scrollTo(index);

	    if (it.hasNext()) {
		Object old = it.next();
		it.set(element);
		return old;
	    }

	    else
		throw new IndexOutOfBoundsException();
	}

	finally {
	    reset();
	}
    }

    /** {@inheritDoc} */
    public void add(int index, Object element) {
	try {
	    scrollTo(index);

	    if (it.hasNext()) {
		it.next();
		it.add(element);
	    }

	    else
		throw new IndexOutOfBoundsException();
	}

	finally {
	    reset();
	}
    }

    /** {@inheritDoc} */
    public Object remove(int index) {
	try {
	    scrollTo(index);

	    if (it.hasNext()) {
		Object old = it.next();
		it.remove();
		return old;
	    }

	    else
		throw new IndexOutOfBoundsException();
	}

	finally {
	    reset();
	}
    }
}

Wednesday, September 17, 2003

Iterators

I've become fascinated by iterators, those small bits of code which turn out an object one at a time. For example, Python has generator comprehensions while Java has iterators and C++ likewise.

Presently I'm adding to my list of Java iterator adaptors, objects which wrap an underlying iterator to produce one with modified behavior. Two excellent examples are FilterIterator which wraps a ListIterator [1] and produces only elements matching a criteria, and ReverseIterator which also wraps a ListIterator to produce the underlying elements in reverse order. I also coded ListIterator versions of each which are bidirectional.

I still have a lot of work, however. C++'s STL is still way ahead of Java's collection classes. I am thinking of putting my work up on SourceForge or some other similar place (perhaps something more Java-specific) under the GPL but have let laziness get the better of me so far. Laziness, Impatience, Hubris [pdf]. What could be better?

[1] FilterIterator wraps a ListIterator rather than an Iterator for a good reason. To properly filter, one needs lookahead which implies the ability to back up the underlying iterator if lookahead failed, hence one needs a reversible iterator with previous(). FilterIterator doesn't just produce the right output, it makes the underlying Iterator behave as if it contained only the filtered elements.

Extending BASH

I started yesterday writing a new builting command for BASH, the Bourne-again Shell. It's called eset and it works the same as in 4DOS making it easy for you to edit environment variables. In addition, eset edits aliases and shell functions. All this is possible because BASH makes it easy for you to write new extensions and add them to the shell:

    $ make eset
    ... output from make ...
    $ enable -f ./eset eset # load builtin into the shell
    $ eset
    eset [-aef] var
    $ eset PATH
    PATH=/bin:/usr/bin:.

If you are interested in trying it out, please write me.

UPDATE: Apologies, but after several moves and change of servers, I have lost the source.

Tuesday, September 16, 2003

Is extends evil?

Alan Holub argues that the extends keyword is evil. Is he right?

I think the root of the evil is not implementation inheritance per se but single inheritance. With non-diamond multiple inheritance, inherit specific interface implementations to make a compound object and an is-a relationship rather than use interface forwarding and a has-a relationship. This is more efficient and much easier to maintain: no forwarding code to write and test. Even better would be generic multiple inheritance (template base classes in C++) so that a consumer of the code can specify which implementation to inherit for a particular interface.

In contrast, single inheritance makes it very difficult as you must upfront decide which interfaces a superclass implements. Changes in that decision require changing the interfaces and implementations in both the superclass and subclass. This is a disaster for maintainability and comprehension.

Checkstyle

I've always been a stickler for good programming style. It's one reason I often prefer Emacs over IDEs when writing code, especially when fixing existing code: Emac's formatting facilities are peerless. But there's more than one way to skin a cat, the saying goes.

Checkstyle is an automated style checker for Java including the hooks for an Ant task. By style, I don't just mean code formatting, I mean all the rest: javadoc comments, naming conventions, overlarge files, etc. Checkstyle handles these, producing reports suitable for further consumption.

Right now I'm changing some of my Collections extensions to use checkstyle in the build process. I'm updating build.xml to include a check target which checks the style of my Java sources, outputs problems to stdout so Emacs can parse and step through the errors, and writes an XML report to the docs directory for inclusion in the code metrics.

Spiffy.

Monday, September 15, 2003

Goto, come-from

Ah, the joys of structureless programming...

A Linguistic Contribution of GOTO-less Programming

By R. Lawrence Clark*

From DATAMATION, December, 1973


Nearly six years after publication of Dijkstra's now-famous letter[1], the subject of GOTO-less programming still stirs considerable controversy. Dijkstra and his supporters claim that the GOTO statement leads to difficulty in debugging, modifying, understanding and proving programs. GOTO advocates argues that this statement, used correctly, need not lead to problems, and that it provides a natural straightforward solution to common programming procedures.

Numerous solutions have been advanced in an attempt to resolve this debate. Nevertheless, despite the efforts of some of the foremost computer scientists, the battle continues to rage.

The author has developed a new language construct on which, he believes, both the pro- and the anti-GOTO factions can agree. This construct is called the COME FROM statement. Although usage of the COME FROM statement is independent of the linguistic environment, its use will be illustrated within the FORTRAN language.


box 1

Unconditional COME FROM statement:

     General Form
     COME FROM xxxxx
     Where: xxxxx is the number of an executable statement in the same
     program unit.

     This statement causes control to be transferred to the next
     statement (the statement immediately following the COME FROM upon
     completion of the designated statement.

     Example:
               10 J=1
               11 COME FROM 20
               12 WRITE (6,40) J STOP
               13 COME FROM 10
               20 J=J+2
               40 FORMAT (14)
     

Explanation:

In this example, J is set to 1 by statement 10. Statement 13 then causes control to be passed to statement 20, which sets J to 3. Statement 11 then causes control to be passed to statement 12, which writes the current value of J. The STOP statement then terminates the program.


box 2

Conditional COME FROM statement:

     General Form
     IF (cond) COME FROM xxxxx
     Where: cond is any logical expression.
     xxxxx is the number of an executable statement in the same
     program unit.

     This statement causes control to be transferred to the next
     statement whenever the condition cond is true and the designated
     statement has just been completed.

     Example:
               I = 1
               IF (I .LT. 10) COME FROM 50
               I = I+1
       50 WRITE (6,60) I
                 STOP
       60          FORMAT (14)
     

Explanation:

The COME FROM takes effect only while I is less than 10. Thus when I is equal to 10, the program continues past statement 50 and terminates. This is equivalent to the now-obsolete formulations:

               I = 1
       30          I = I+1
               WRITE (6,60) I
               IF (I .LT. 10) GO TO 30
               STOP
       60          FORMAT (14)
     or
               DO 50 I = 2, 10
       50          WRITE (6,60) i
               STOP
       60          FORMAT (14)
     

Note how much cleaner is the intent of the code containing the COME FROM construct.


box 3:

Computed COME FROM statement

     General Form
     COME FROM (x1, x2, x3....,xn), i
     Where: Each x is the number of an executable statement in the
     same program unit.
               i is an integer variable.

This statement causes control to be transferred to the next statement whenever any of the following conditions holds:

               * statement x1 has just been executed and i is equal to 1
               * statement x2 has just been executed and i is equal to 2
               * statement x3 has just been executed and i is equal to 3
               * statement xn has just been executed and i is equal to n

If, when statement xj is executed, i has any value other than j, this statement has no effect.

Example:

               DO 200 INDEX=1,10
       10          X=1.
       20          X=X*2.
       30          X=X*3.
       40          X=X*4.
       50          X=X*5.
       60          X=X*6.
       70          X=X*7.
       80          X=X*8.
       90          X=X*9.
       100         X=X*10.
               COME FROM (10,20,30,40,50,60,70,80,90,100),INDEX
               WRITE (6,500) INDEX,X
       200          CONTINUE
               STOP
       500          FORMAT (14,2X,F12.0)
     

Example:

This program illustrates the power of the computed COME FROM by providing a compact algorithm for computing factorials. On the first iteration (INDEX=1), as soon as statement 10 has been executed, control passes to the WRITE statement. As a more general case, consider the fifth iteration: X is set to 1, and the multiplied by 2., 3., 4. and 5. before control passes to the WRITE statement.


box 4:

Assign and assigned COME FROM statements

     General Form
               ASSIGN xxxxx TO m
                 *
                 *
                 *
               COME FROM m, (x1,x2,x3,...,xn)
               Where: xxxxx is the number of an executable
               statement. It must be one of the numbers x1,x2,x3...,xn
                         Each xx if the number of an executable
                         statement in the same program unit.
                         m is an integer variable which is assigned
                         one of the statement numbers x1,x2,x3,...,xn.

The assigned COME FROM causes control to be transferred to the next statement upon completion of the statement whose number is currently assigned to m. This provides a convenient means of passing control to a common point from a variety of points in the program unit. The actual point from which control is to be passed can be selected under program control.

Example:

               DO 60 I=6,32
       20          X=I*6+14
               IF (X-20.) 10, 30, 50,
       10          ASSIGN 40 TO JUMP
       30          Y=2*X**2.-17.4
               COME FROM JUMP, (40,20,30)
               ASSIGN 30 TO JUMP
               X=X*Y-X**2
       40          ASSIGN 40 TO JUMP
               IF (Y-X) 20, 60, 50
       50          ASSIGN 20 TO JUMP
       60           CONTINUE

Explanation:

This example is self-explanatory.

The author feels that the COME FROM will prove an invaluable contribution to the field of computer science. It is confidently predicted that this solution will be implemented in all future programming languages, and will be retrofitted into existing languages. Although it is clear that the COME FROM statement fulfills most of the requirements of the advocates of GOTO-less programming, it remains for the practitioners of automatic programming to evaluate just how much this construct contributes to the development of automatic proofs of program correctness. Having at last put to rest to GOTO controversy, we now may enter the era of the COME FROM conundrum.

* The author is indebted to G.F. Groner and N.A. Palley for a valuable discussion which took place in New Haven, Conn.

[1] E. W. Dijkstra, "GOTO Statement Considered Harmful," Letter of the Editor, Communications of the ACM, March 1968, pp. 147-148.


Mr. Clark is a programmer/analyst in the computation center of the Rand Corp. He has been active in the development of user-oriented, interactive computer systems, especailly graphics systems. He has a BS in mathematics from Pennsylvania State Univ.

Friday, September 12, 2003

Why Java sucks more than C++ does

No, this isn't a language rant; I just wanted a catchy title.

I've been writing various containers, adaptors, iterators and algorithms for Java and I'm growing tired of some of the obstacles. The Collections Framework gets a solid B but no higher. This is because while Java is an excellent language for object-oriented programming, it is very poor for generic programming. In particular, Java lacks support for generics and mixins and the generics proposals for Java 1.5 only partly addresses these deficiencies. (See the NextGen project for something more in the right direction.) In a very fundamental way, Java is a single paradigm programming language. In contrast, C++ strives to be a multi-paradigm language. A quick comparison:

  C++ Java
Structured Excellent Good
Object-oriented Excellent Excellent
Generic Good None
Funtional Fair None

What does all this mean?

Structured programming is ubquitous now days, and C++ and Java are both intellectual heirs to ALGOL and other early structured-programming languages. They have syntax-driven control structures such as if ... else and while to remove the need for the much dreaded goto. But I fault Java for lacking goto for certain kinds of effecient exception handling within a method and for making Duff's device illegal. How could they?

Object-oriented programming we all know and love. The problem even here is that Java requires OOP even when you don't need it. But it does have OOP in spades.

Generic programming is parameterization by type permitting strong typing of untyped language constructs. The classic example is List which is a list container of Foo objects. C++'s weakness is it's over-strong type system which prevents true virtual constructors and the like. Java simply lacks the facility all together.

Functional programming is programing to the Lambda Calculus. C++ supports this with functors, objects supporting function call syntax, but still lacks truly first-class function objects (although the proposed <functional> is closer than before).

On the gripping hand, there is no VM for C++ to run my compiled object code everywhere without recompilation, and Java's package system is very excellent; namespaces are a compiler symbol table hack, not a fully integrated run-time feature.

As you can see from this list, writing generic containers, adaptors, iterators and algorithms is tricky with Java. The lack of good generics really blows. A particular example: I'm been writing and rewriting a Stack interface. Because of Java's single-inheritance, I am unable to make a really good adaptor with it. How do you tack it onto an existing List implementation in a really smart way? If your implementation is a RandomAccess container (read ArrayList), then you want to push objects onto the end of the list since adding to the front is so expensive; if it is not a RandomAccess container (read LinkedList) then you want to push objects onto the front of the list since accessing the last element is so expensive. In C++ I can handle this easily with template specialization and mixins (multiple inheritance), but these are foreign to Java.

Perhaps in Java 1.6 things will be easier.

Thursday, September 11, 2003

Job!

After more than 5 months without work I found myself in the enviable position of having two offers at the same time, one with ThoughtWorks of XP fame and the other with ORIGIN in Austin, makers of Ultima Online. What a choice! I decided to accept the position with ThoughtWorks; orientation begins on the 23rd. Yah!

Wednesday, September 10, 2003

Blogger and Konqueror

Blogger now seems to work with Konqueror when you compose posts and manage your blog. Fantastic! I tire of starting up Mozilla just to blog. I like Mozilla just fine, but I don't like having to run several different browsers to work.

Sunday, September 07, 2003

Two great sites

Martin Fowler, Chief Scientist at ThoughtWorks where I am interviewing tomorrow (my first chance to see Chicago!), has two great sites: Martin Fowler's Bliki, an interesting cross between a blog and a wiki, and Refactoring Home Page, a site devoted to refactoring (just consider this small example, seemingly trivial but subtle and insightful, like a good koan). I stumbled across them while looking up UML information. Presently I'm going through Gang of Four to refresh myself and wanted more information on the diagram styles used in the book.

I've also noticed that the way I read texts has changed because of the Internet. Growing up and in college, I'd read text straight through in a linear fashion. Now I find myself treating them like web pages and jumping around to follow my train of thought rather than the author's. And I have no compunction against setting down the text and switching to another one that continues the thread of my thinking. The World Wide Web is truly a new, marvelous thing.

About my interview tomorrow: Wish me a good day!

Thursday, September 04, 2003

The Unix Guide to Defenestration

I haven't read this book in a while but its lessons remain: large, clunky, closed systems always lose out to nimbler, cleaner, open ones. For a practical example, I'll let you guess from the book title which is which in referring to two well-known operating systems.

Tuesday, September 02, 2003

A vision paper from my EBS days

Because of a conversation with a recruiter in Dallas about an interesting embedded Linux project, I looked through some old files and found a vision paper I wrote during the good times at Enron Broadband Services, The Enron Media Lab at Rice University. As the technology discussed has passed its heyday and one of the companies no longer exists, I'll reproduce it here to give an idea of the sort of cool projects that were hot at Enron. Note the dated obsession with stock price—this was key to getting internal support for the project. This paper is also a good example of how to handle endnotes in HTML. (I apologize for the layout; the default stylesheet Blogspot provides me is fine for regular posting, but looks poor with a quoted HTML document such as here.)

The Enron Media Lab at Rice University

  1. About the Enron Media Lab
  2. Motivation
  3. How It Really Works

About the Enron Media Lab

The Enron Media Lab will be a state-of-the-art facility for researching and developing both fundamental and practical techniques to control end-to-end quality in IP/optical networks for high bandwidth multimedia applications. Housed at Rice University, and funded in part by Enron, one of the main goals is to provide a physical environment to commercialize the best in university research.

Models for the Enron Media Lab include the famed MIT Media Lab and Lucent Bell Labs Innovations™ (formerly just "Bell Labs"). The idea is twofold: to foster great research in an open environment and transfer that wealth into success in the marketplace, and to raise Enron's image as a technology leader and member of the New Economy by association with Rice and support for research.

Motivation

First Day Jitters

When I entered Rice as a transfer in 1987, I took my mother on a walk about campus. It was a hot day in August, typical for Houston, and most of the time we spent trying to stay in the shade. At every building, we'd step out into the sun for a moment to get a good look and try to figure out what the building was for. We had the standard map of campus with us, but all that was good for was finding the names of buildings. When we wanted to know something about the building, it's history, or the classes taught there, the map was useless.

But this will soon change.

Nokia™ will build a high-speed wireless network[1] throughout campus and provide 3rd-generation phones to all the faculty, staff and students. And with all that bandwidth, Rice will need something to fill it with. In a year or two, when a freshman enters Rice and takes her parents walking about campus, the experience should be rather different than mine.

Using her 3rd-generation cell phone complete with a small, high-resolution color screen[2], she points the phone at a building and asks out loud, "What's that building?". The phone asks here some questions to identify the building clearly, drawing on the Enron Media Lab's systems integration. She continues her conversation, "What classes do they have in there?" The phone tells her. "Could you show me what that class is like?" At this point, the phone plays an excerpt from one of the lectures held in the building, using the Enron Media Lab's distance learning system. Her parents marvel at their daughter's decision to attend Rice.

How does it work?

Nokia™ and other cell phone companies provide the high-speed wireless network. Enron Broadband Services provides the media services and technologies to run multimedia on broadband networks, applications like 3rd-generation video cell phones, high-quality interactive audio-visuals and distance learning. And the Enron Media Lab provides the research that forms the basis for these services and technologies. The Enron Media Lab finds answers to questions like:

  • How can we integrate systems such as wireless networks, video-on-demand, and interactive and live multimedia?
  • How can we store large multimedia efficiently and quickly send it to the consumer?
  • How can we switch broadband from supply to demand, timely and efficiently?

A Great Day for Enron, A Great Day for Rice

While walking about campus and thinking about the Enron Media Lab, it occurred to me that there was so much available at Rice that was locked away unless you were present at just the right place, just the right time. When Willie's statue was turned around[3], I was there, but anyone else now would hear only second-hand stories.

But this will soon change.

Enron Broadband Services will deploy a high-speed multimedia bonanza, and everything from live speeches, classroom lectures and discussions, music school concerts and special events will be available as they happen to anyone who is interested, no matter where they are or what device they use. And they will be available for anyone to reexperience days, months or years later.

Sitting in his dorm room, a senior electrical engineer watches Ken Lay hand over a check for $10 million to Rice for the business school. He's watching from his PC, receiving the broadcast from the Enron Media Lab's experimental live broadcast system using Rice's high-speed network, and can pause, rewind, and catch up to the speeche as it happens. And some weeks later, he reviews the event on his PDA as he walks about campus, using the Enron Media Lab's experimental video-on-demand system, while preparing to go downtown for an interview at Enron.

How does it work?

Again, Enron Broadband Services provides the media services and technologies to run multimedia on broadband networks, applications like live broadcast, video conferencing and video-on-demand. And again the Enron Media Lab provides the research that forms the basis for these services and technologies. The steps are clear:

  • Without the Enron Media Lab to provide the fundamental research for multimedia and broadband, Enron does not have the technologies for applications and systems.
  • Without Enron Broadband Services and other Enron companies to provide the deployment for multimedia and broadband, vendors like Nokia™ do not have the applications and systems for their broadband networks.

Finally, the Lab

In a year or so, Fortune™ or Forbes™ Magazine send a reporter to write up on the Enron Media Lab. What further proof can there be that Enron has completed its movement from Old Economy to New Economy? He walks around, sees the routers, the computers, the video demonstrations, the rapid provisioning tools, the quality-of-service testbeds. That day Enron stock closes at 122-5/8. In the week following the publishing online of the article, Enron stock closes at 134-1/4. Just ask yourself why.

How It Really Works

The physical Enron Media Lab is a main facility provided by Rice University (presumably in Duncan Hall, where Computer Science and Electrical Engineering are located), with smaller satellite locations around campus for testing and prototype deployment. It constains Cisco core and edge routers, IP and optical measurement equipment of various sorts, Sun workstations and servers for testing, deployment and monitoring, and high-speed Ethernet and optical fiber cables and links. Enron's corporate logo will be prominent.

The intangible Enron Media Lab is the ideas people take with them after visiting: a high-technology company for the New Economy supporting great things, and working to do even greater things. That idea comes from the researchers in the lab who:

  • Take advantage of the structure provided by the Enron Media Lab, and move research from the lab to the field
  • Experiment with multimedia technologies, such as streaming and video-on-demand, using advanced bandwidth management equipment and the high-speed network connecting the students and the faculty
  • Demonstrate and deploy the reality of rapid provisioning and gigabit routing in the lab, and then in the field to satellites throughout campus

When you tour the Enron Media Lab, the things you see first are the physical: the structure, the equipment, the staff, the "blinking lights"[4]. Surounding you are various advanced traditional and optical routers, workstations and network monitoring tools. And you can't help but see Enron's corporate logo, or see the prominent words, Enron Media Lab.

While you are there, you see real working demonstrations and test deployments of IP QoS and platinum VPN services, rapid provisioning and resource reservation, dynamic web caching, multimedia streaming and video-on-demand, and distance learning. You can reexperience lectures, plays and performances from Rice University and it's sister campus in Bremen.

When you finish the tour, the things you remember most are the intangible: the brilliance of Rice, and the vision and vigor of Enron.


[1] 3rd-generation cell phone networks should run at 384kbs out doors and 2Mbs indoors. Typically, VHS-quality video at TV resolutions requires 1.7Mbs.

[2]Erricson has some nice pictures of what some 3rd-generation cell phones will be like. Think PalmPilot™ rather than portable handset.

[3]Students at Rice really did rotate William Marsh Rice's 2000-lb. statue 180°. Now that isn't something you see every day.

[4]It is important not to underestimate the imporance of a physical demonstration of high technology in helping people understand how things work, and why it benefits them.

Great Kernighan quote

From a Rik van Riel post on LKM:

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. - Brian W. Kernighan

Proxied data members

There's a neat trick I've used for a while when writing C++ code: proxied data members. The idea is straight-forward. The user of your class can write normal-looking access to data member, but behind the scenes your class calls accessor member functions on the user's behalf. I was unable to find a similar technique in Boost but it is nothing new. Proxied data members relies on a helper class which curries an object pointer and member function pointers, applying them as needed via assignment and conversion operators.

The simplest form for a read-only data member is:

#include <iostream>

using namespace std;

template<class P, class T>
class read_only {
  typedef T (P::*read_t) ( ) const;

  P &parent;
  read_t read;

// protected:
public: // no friend template parameters
  read_only (P &parent, read_t read) : parent (parent), read (read) { }

public:
  operator T ( ) const { return (parent.*read) ( ); }
};

class bob_t {
  int i;

  int read_i ( ) const { return i; }

public:
  read_only<bob_t, int> roi;

  bob_t ( ) : i (42), roi (*this, &bob_t::read_i) { }
};

int 
main ( )
{
  bob_t bob;

  // bob.roi = 24; // doesn't compile
  int i = bob.roi;

  cout << i << endl;
}

There are a lot of details which this example glosses over including returning a const reference instead of a copy, handling other types of functions besides member functions (use Boost.Function) and access to the constructor of read_only<P, T>. Ideally, the constructor would be private and I could declare friend P;, but that isn't legal C++.

The idiom for a write-only data member is similar.