Thursday, December 03, 2009

Dot Plan from 1995

Before the inter-twitter-facebook-blogweb, or whatever you kids call it, there was Finger. Finger was cool because only geeks knew about it. You'd post your status to your .plan file and people anywhere in the world could type "finger" to see it.

It was like blogging, but with an even slimmer chance of having an audience. Great stuff.

Anyway, I was rooting around my old account at csh tonight and found this my .plan:

class CS2


feature -- Global variables

student: STUDENT
clean: INTEGER is unique
warped: INTEGER is unique

feature -- Main program

brain_washing is
student.mind := clean
student.mind = warped or world.end_of
loop "EIFFEL is Good%N" ) "Don't worry that your executables " ) "are usually over 20,000 times larger " ) "than the source code.%N" )
if student.resists then
end -- loop
end -- brain_washing

end -- CS2

Clearly, this is an important digital artifact to preserve.

By posting it here, I feel I have played an important role in format migration for future generations. Thank you.

Friday, September 04, 2009

An extra cent?

It often happens that my flight price goes up while I'm in the process of booking. I thought it was pretty shady the first few times it happened. Now I just accept it and move on. But I thought this one was a little bizarre today:

I can't help but wonder if Peter Gibbons is behind this in some way.

Monday, August 31, 2009

Discovery of *content* metadata on the web

A thought experiment...

I recently read an entertaining old article on various things people have been shoving into http response headers. Some for utility (X-XRDS-Location), and some for fun (slashdot's random X-Fry and X-Bender quotes). One site actually put a bunch of DC.title, DC.etc headers in their responses. Not that anyone's looking for them there, but *just* in case...

This got me thinking (again) about ways to provide richer metadata, especially RDF, about resources on the web. We have RDFa now, which is a big step forward, but there are a couple key problems we still don't have worked out:
ISSUE 1: How do we discover publisher-sanctioned resource descriptions for arbitrary resources on the web? (e.g., non-XHTML)
I think the http Link: response header is the right way forward on this: An isDescribedBy link, pointing to a resource whose representation encodes an RDF graph describing this resource.
ISSUE 2: Given that a resource and the content of a representation of that resource are distinct things, how do we make statements about the latter on the web?
This one deserves more explanation.

If I access, and my browser uses content negotiation to request the image/jpeg representation, and gets it, I want to be able to discover this kind of info:

@prefix    : <http://dear.lazyweb/please/write/this/ontology/>
@prefix xsd: <>

# The file is a JPEG and here's some basic info about it

_:myFile a :OctetStream;
:name "Picture1.jpg";
:mediaType "image/jpeg";
:format <info:pronom/fmt/42>
:length 105124;
:md5sum "7846df5ced300e9543a267a856c4ab6e";
:sha1sum "e3b5112b24e793f41fc5b843a505a83a80aaf776";
:created "2009-08-31T10:12.342Z"^^xsd:dateTime;
:modified "2009-08-31T16:28.921Z"^^xsd:dateTime;
:renditionOf <>

# The file is one of any number of renditions of a picture

dc:title "Best Picture Ever";
dc:description "This is a picture of my cat, Lucky"
dc:creator "Bob Dobbs".
What would be cool is if my browser knew about the http Link response header, and the metadata was just a click away, in an RDFa document.

The trick would be for user-agents to be able to associate the particular rendition I got by GETting the resource with the appropriate resource in this graph. Notice it's a bNode in the example above. It might have a URI, it might not; but the URI of the rendition isn't known by the user-agent when it retrieves this graph....and the relation expressed by the http Link header is to be interpreted as "(the resource identified by this URI) isDescribedBy (the graph resource over there)"

So, absent some additional information, in the general case, the user-agent is going to have to do the association via some distinctive property matching: Did the response of the original GET request on the picture include a Content-MD5 header? If so, that's a good clue. Hmmm.

Monday, May 04, 2009

That's Classy

Here's a simple program to report on Java .class versions. I'm sure some variant of this has been written a thousand times, but Google wouldn't give me what I wanted right away, so here it is again :)

The program takes one argument: a path to a .class file, .jar file, or directory containing a mixture of both, and produces a report of each class file's major .class format version (50 for Java 6, 49 for Java 5, and so on). Handy if you want to track down those new fangled classes and avoid the dreaded java.lang.UnsupportedClassVersionError

import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

public abstract class ThatsClassy {

static void classyFile(File file) throws Exception {
if (file.isDirectory())
for (File child: file.listFiles())
else if (file.getName().endsWith(".jar"))
else if (file.getName().endsWith(".class"))
classyClass(file.getPath(), new FileInputStream(file), true);

static void classyJar(File jarFile) throws Exception {
JarInputStream jarStream = new JarInputStream(new FileInputStream(jarFile));
JarEntry entry = jarStream.getNextJarEntry();
while (entry != null) {
if (entry.getName().endsWith(".class"))
classyClass(jarFile.getName() + "#" + entry.getName(), jarStream, false);
entry = jarStream.getNextJarEntry();

static void classyClass(String id, InputStream in, boolean close) throws Exception {
int majorClassVersion =;
if (close) in.close();
System.out.println(id + " " + majorClassVersion);

public static void main(String[] args) throws Exception {
classyFile(new File(args[0]));

Monday, February 16, 2009

dev8D Tweet Cloud

Wordle: Dev8D Tweets Here's my abbreviated trip report: dev8D was a big success -- any conference that gets developers together and avoids long monologues is a winner in my book. As a side note, I think twitter works pretty well as a backchannel. I noticed at least one person created a separate account to avoid spamming their regular followers. Not a bad idea.