OpenLaszlo software development position open 2

Posted by Oliver on April 11, 2005

Laszlo Systems has a position open for a senior software architect to work on the OpenLaszlo client runtime. This is a paid position, and you would be working on an open source project. You’ll be working on the bright green box below, but if you qualify, you get to choose your color. :-)

You should be a great software designer, able to navigate complex systems and big architectures, but with wizard-level performance optimization skillz too.

Your idea of a dream job should be writing code that does near-impossible things, and shipping it, and then seeing it used to build products that you can show your friends. But you should also enjoy working with other smart people, bouncing ideas off of them, learning from them, and teaching them. In fact, you should be willing to mentor and lead the efforts of open source contributors, and you should have the leadership and communication skills to do so.

You should enjoy initiative, innovation, and excitement. You’ll be working on the core technology of an emerging technology company. This is an important, visible position, that will change the future of the web.

You should enjoy building complicated things, and making them look simple. You should be excited about working on systems that look like this on the inside:
but look as simple as this to developers:

<canvas>
  <button onclick="animate('x', 100, 1000)">Click me!</button>
</canvas>

and can be used to build things that look like this to your mom:

You don’t need to know Smalltalk, Lisp, Dylan, JavaScript, Python, or Ruby — and you won’t be using any of them except JavaScript — but if you’ve tried dynamic languages before and hated them, you probably don’t want this job either. Conversely, if you’ve never profiled an application or made an educated performance-based decision about whether to use integers or floats, recursion or iteration, or DTO or parameter lists, you should probably look elsewhere too.

You should live in one of America’s Bay Areas (San Francisco or Boston).

You can read more about this position here and here. Send your resume to resumes@laszlosystems.com.

Wasting Time with Laszlo 1

Posted by Oliver on April 03, 2005

Last month, Geert Bevin wrote an article called wasting time with Laszlo. Since then, he’s wasted even more time with Laszlo. Bla-bla List is Bevin’s fully functional clone of Ta-da lists, re-implemented in Java and RIFE.

Of course, while the bad thing about web application programming is that you’re dealing with two different platforms (even if one of them is just DHTML), the good thing is that you can choose them independently. I’m planning to use Laszlo on the client with PHP and Rails on the server, now that serverless deployment makes that possible.

Site_”Ta-da lists”:http://www.tadalist.com/_”Bla-bla list”:http://blablalist.com/
Server languageRubyJava
Server frameworkRailsRIFE
Client platformDHTMLLaszlo

Update

In OpenLaszlo 3.0b2, two weeks later, Bevin updates his original list of criticisms to take into account the 3.0b2 release. Recommended reading for anyone evaluating RIA platforms.

PyCon 2005

Posted by Oliver on April 02, 2005

The slides from my PyCon 2005 talk about Jython and the OpenLaszlo compiler are online (PDF). I’ve corrected some dates and minor typos: 3K+1.5K does not equal 6K, as I realized once I was standing at a podium with a large slide that displayed my math skills behind me, and a large number of technically sophisticated smart people in front of me.

Some illustrations from the talk:

KRANK dataflow

Dataflow for implementation of the KRANK feature for startup time optimization:

Script compiler dataflow

Dataflow for the OpenLaszlo ECMAScript compiler:

(The PDF shows what the data looks like at some of these stages.)

Serverless deployment

Deployment diagrams with (top), and without (bottom), the OpenLaszlo server. Deploying with the server requires a J2EE servlet container (Tomcat, JBOSS, Weblogic, Websphere, etc.). Serverless deployment works with Apache and consumer-price ISPs (such as the one that hosts this website).

Deployment with OpenLaszlo Server

Serverless Deployment

(Caveat: the server also handles caching, GIF transcoding, RPC, and the persistent connection, as this animation illustrates. The diagram above just shows the initial download.)

Laszlo Mail 4

Posted by Oliver on March 08, 2005

Last week Laszlo announced its web mail application. Later this year Earthlink will deploy a branded version of this application.

*Update: Laszlo Systems is hosting open registration for Laszlo Mail here.*

Laszlo Mail is being built on top of Release 3.0 of the OpenLaszlo platform.

Congratulations to everyone involved in writing this application, and to the people who have been worked on the platform extensions that make it possible to write applications like this in Laszlo. Writing good client applications is hard work.

Here’s where I plan to use the thing:

Right now, when I’m using someone else’s computer (still happens — the beasties don’t fit in my pocket yet), I have a choice between (1) setting up an IMAP client, or (2) using an HTML webmail interface. These days I always opt for the webmail client, and GMail actually makes it bearable.

But…

I use folders to organize my email. I use a variant of GTD, with folders for projects, context-sensitive items (tickles for future dates, agendas for future meetings), reference material, and archives. GMail just doesn’t play well with folders. Sure, I can make folders in GMail, but my GMail folders don’t respect any organization I’ve created in IMAP. And I’m a drag-and-drop guy — it’s just too hard to move messages between folders with GMail, which is why I don’t use it as my main mail client in the first place.

So right now, I’m stuck with a bifurcated mail experience. The desktop clients (Thunderbird on the PC and Linux, Apple Mail on the Mac) have the UI features I need; GMail (and before that SquirrelMail) have the ubiquity.

That’s what I’m looking to Laszlo Mail to fix. I want to be able to walk up to any computer in the world, catch up on my mail, easily move it to the right folders, and go back to my desktop machine and see messages where I put them.

Some of you do everything on your Blackberry or iPaq. You don’t need the thing. Some of you keep everything in one big Inbox. You can probably get by with GMail. For me, I’m just counting the days…

Ruby and Laszlo 3

Posted by Oliver on March 08, 2005

I first heard of Ruby at the second Lightweight Languages Workshop 2, where Matz and I were both speakers. This was first public disclosure of the then-proprietary Laszlo platform language. I’m afraid I was more worried about preparing my talk then listening to Matz at the time!

Since then, a number of different people have expressed interest in both Laszlo and Ruby. I figured I had finally better take a look at it.

I understand what the fuss is about. Ruby is one of the rare languages with a readable embedded syntax for metaprogramming, it’s well designed, and it has a mature library for web programming. What this translates to in practice is that you can program in a language with “keywords” (really just functions) suitable to the task at hand.

Compare the two class definitions below:

class Person < Object
  attr_reader :name
  attr :location
end
class Person < ActiveRecord::Base
  has_one :name
  has_many :address
end

The first definition uses the core language syntax to define a Person class that contains a getter for name, and both getters and setters for location. The second uses Rails to define a Person Active Record that has one name record and many address records. (It uses the Foreign Key and Association Table patterns, respectively.) The cool thing is that attr and has_one look the same to the library user. Ruby allows the library developer to grow a language. This lets the library user write in a concise domain-specific language that embeds Ruby.

What does this mean in practice? During my last vacation it took about five lazy vacation days with Ruby on Rails to implement a fairly sophisticated 40-page web application with five models, two metamodels, CRUD, cookies, image upload, and login. (I’ll write more about the application itself, if I find a few free weekends to harden it for public use.) For comparison, it took me about the same amount of time during my previous vacation to write a much simpler ten-page PHP web application that had only one model. And I already knew a little bit of PHP, whereas I was learning Ruby and Rails from scratch.

Now, what does this have to do with Laszlo? Laszlo certainly doesn’t have any metaprogramming facilities. It has states, constraints, and data binding, which extend the reach of declarative programming beyond static layouts. (Yeah, yeah, I should write about this too; in the meantime there’s docs and examples here and here.) I suspect that some of the people who “get” how to use metaprogramming in Ruby also get how to do declarative programming with the Laszlo features. But I also think a large part of what Laszlo brings to the table is simply that it allows you to use conventional OO techniques in client-side browser programming. For example,

<canvas layout="axis: y">
  <view width="10" height="10" bgcolor="red">
    <view x="1" y="1" width="8" height="8"/>
  </view>
  <view width="20" height="20" bgcolor="red">
    <view x="1" y="1" width="18" height="18"/>
  </view>
  <view width="30" height="30" bgcolor="red">
    <view x="1" y="1" width="28" height="28"/>
  </view>
</canvas>

DRYs out to:

<canvas layout="axis: y">
  <class name="box" width="${this.size}" height="${this.size}" bgcolor="red">
    <attribute name="size" value="10"/>
    <view x="1" y="1" width="${parent.width-2}" height="${parent.height-2}"/>
  </view>
  <box/>
  <box size="20"/>
  <box size="30"/>
</canvas>

This (OOP) is old hat in the server-side world — just like MOP is old hat to Smalltalk and Common Lisp developers — but it’s relatively new in the world of zero-install client-side platforms. So I think the analogy between Ruby on the server, and Laszlo on the (much more resource-constrained) client, is that each of them advances advances the reach of non-academic programming:

Update: Now that I’ve done more Ruby and DHTML programming, I can see that the diagram above gives OpenLaszlo short shrift. Although OpenLaszlo is lower level that Ruby with respect to code generation and a MOP, the use of databinding and constraints makes it higher level in a different set of ways.

Laszlo’s Boston Office 1

Posted by Oliver on March 07, 2005

Laszlo’s main office is in a spiffy office building in San Mateo.

But Boston Product Development (basically, the OpenLaszlo development team) works out of a cafe.

Espresso Royale Cafe

This puts us in good company. (And we get better coffee, too.)

Henry posted some photos he took last week. Here’s one; click on the image for more.

Oliver, Amy, Tucker, and Henry

IDE4Laszlo 2

Posted by Oliver on November 18, 2004

Last month, Laszlo Systems released the Laszlo platform as Open Source. The intent was to to remove the bottleneck in the virtuous cycle of software development.

Today IBM alphaWorks released IDE for Laszlo. This is an Eclipse-based IDE for creating, editing, debugging, and testing applications written in Laszlo.

Eclipse is an impressive platform, and the IDE for Laszlo is an impressive effort. This page demonstrates many of its features, with screenshots for each. (It was written in LZX, using IDE4Laszlo.) Kudos to the developers!

From http://alphaworks.ibm.com/tech/ide4laszlo :

IDE for Laszlo is a technology preview of an Eclipse-based development environment for creating, editing, debugging, and testing applications based on the LZX declarative mark-up language.

Laszlo is based on LZX, which is an XML and JavaScript description language similar in spirit to XUL (XML User interface Language) and XAML (”Longhorn” mark-up language by Microsoft®). The Laszlo Platform is an open-source platform for the development and delivery of Rich Internet applications (see http://www.openlaszlo.org for more information) where the LZX XML mark-up is used to create the user interfaces.

The IDE consists of a set of plug-ins that allow creation and testing of Laszlo applications, all within the Eclipse platform. These applications can then be deployed and run on a Web server. IDE for Laszlo also provides a rich editing environment for the LZX mark-up language. Its editing features include XML- and script-based content assistance, XML syntax highlighting, and XML code formatting.

In addition, IDE for Laszlo allows the developer to preview the resulting application without deployment, within the Eclipse environment. It supports markers for reflecting compilation and syntactical errors. When development is complete, the applications created can then be deployed and run.

Unqualified Imports for XML

Posted by Oliver on August 04, 2004

An A Fresh Canvas I argued that there’s a human-factors advantage to allowing an XML document to contain names from multiple namespaces without requiring namespace prefixes on the elements from all but one of them. In What’s in a Namespace I looked at how namespaces and namespace imports work in programming languages, which generally allow both qualified imports (like XML Namespace) and unqualified imports as well.

I also said that I would demonstrate that unqualified imports could be added to XML in a well-defined way, if certain conditions were met. (The conditions are that the set of names in each namespace is known when the document is processed. This is the same condition that programming languages such as C++ and Java, that resolve the namespace of unqualified names at compile time, impose.) Here’s where I make good on that promise.

Running Example

The first example below is an LZX program. The second example is how the same program would look if XHTML and XInclude elements were qualified with their respective namespace prefixes. 1

Impliicit namespace qualifiers

<canvas xmlns="http://www.laszlosystems.com/2003/05/lzx">
  <include href="button.lzx"/>
  <button>Click <b>me</b></button>
</canvas>

Explicit namespace qualifiers

<canvas xmlns="http://www.laszlosystems.com/2003/05/lzx"
        xmlns:xhtml="http://www.w3.org/1999/xhtml"
        xmlns:xi="http://www.w3.org/2003/XInclude">
  <xi:include href="mytext.lzx"/>
  <mybutton>Click <xhtml:b>me</xhtml:b></mybutton>
</canvas>

In order to show that the first document can be disambiguated into the same infoset as the second example, it’s sufficient to show a way to transform the first document into the second document. I’ll use an XSLT stylesheet to do this.

1 I’ve played a switcheroo. Yesterday’s no-namespace LZX example didn’t even include the default namespace. I’ve added it today because the mechanism for defaulting the default namespace is completely different from the mechanism for qualifying prefix-free elements from other namespaces.

Defining the Name Map

In order to accomplish the transformation, we’ll need a map from unqualified names to qualified names. Here’s what the entries in the map look like:

_source_target
includexi:include
bxhtml:b
brxhtml:br
ixhtml:i
uxhtml:u
pxhtml:p

(where xi@ and @xhtml are the prefixes that correspond to the XInclude and XHTML namespaces.)

I’ll represent this map in an XML file as a flat list of (_key_, value) pairs, where each key or value is represented by an XML element whose namespace and name are the namespace and name of the key or value. This representation lets us use XML Namespaces to define the namespaces for the key and value.

The keys have odd number positions, and values have even number positions.

<?xml version="1.0" encoding="utf-8"?>
<map xmlns:lzx="http://www.laszlosystems.com/2003/05/lzx"
     xmlns:xhtml="http://www.w3.org/1999/xhtml"
     xmlns:xi="http://www.w3.org/2003/XInclude">
 
  <!-- includes -->
  <lzx:include/>
  <xi:include/>
 
  <!-- XHTML -->
  <lzx:b/>
  <xhtml:b/>
 
  ...
</map>

(Purists take note: This is a schema that has been optimized for readability, not processing. A schema that was optimized for processing would relate the corresponding keys and values hierarchicaly instead of positionally; for example, <entry><source><lzx:include/></source><target><xi:include/></target></entry> or <lzx:include><xi:include/></lzx:include>. I experimented with these formats while I was writing this post and found them so unreadable I decided it was worth the extra XSLT to process the more readable schema above.)

To transform a document that uses unqualified names — all names are in the default (LZX) namespace — into one that uses qualified names — XInclude names are in the XInclude namespace and XHTML names are in the XHTML namespace — it’s sufficient to look each tag name up in this map, and if it’s found, replace it by the value.

The Stylesheet

Here’s the stylesheet that uses the map above to transform the first example into the second example. It copies every item in the source document unchanged unless the name and namespace of the source element match the element at an odd-numbered position in the map. If it does, the name of the element is replaced by the name of the element at the even-numbered position in the map.

The stylesheet only performs the replacement if it’s unique. One might want it to signal an error if an element in the source document matched more than one key. This would match the semantics of Java, where multiple namespaces can be wildcard-imported, but a name that is present in more than one unqualified import must be qualified at its point of use. Alternatively, one could choose the last value, for Python semantics, or define a file that contains an ambiguous map (that is, a relation that isn’t a function) as an error, whether or not the ambiguous key is used, for Common Lisp semantics.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">
 
  <xsl:param name="map.file">qualify.xml</xsl:param>
 
  <xsl:template name="copy" match="/|@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
 
  <xsl:template match="*" priority="1">
    <xsl:variable name="name" select="local-name()"/>
    <xsl:variable name="ns" select="namespace-uri()"/>
    <xsl:variable name="value" select="document($map.file)/map/*[
                  (position() mod 2)=1 and
                  namespace-uri()=$ns and
                  local-name()=$name]/
                  following-sibling::*[1]"/>
    <xsl:choose>
      <xsl:when test="count($value)=1">
        <xsl:element name="{local-name($value)}"
                     namespace="{namespace-uri($value)}">
          <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="copy"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

Taking the Qualifiers Back Out

The same stylesheet can be used to remove the qualifiers, if it’s run on the inverse map. Here’s an auxiliary stylesheet that reverses a map file such as the one above. Here’s where we pay the price for the readable map file format. (We also paid it in the complex select expression that initializes value in the renaming stylesheet above.) This stylesheet contains a couple of extra lines, that aren’t needed for functionality, to copy the text and comments between entries and between keys and values in an entry, so that the result is readable.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">
 
  <xsl:template name="copy" match="/|@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()|text()"/>
    </xsl:copy>
  </xsl:template>
 
  <xsl:template match="/map">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:for-each select="*">
        <xsl:if test="(position() mod 2) = 1">
          <xsl:variable name="pos" select="position()"/>
          <!-- text, comments, and pi's that precede this pair -->
          <xsl:apply-templates select="../node()[count(preceding-sibling::*)+1=$pos and not(self::*)]"/>
          <!-- the second element becomes the first -->
          <xsl:apply-templates select="../*[position()=1+$pos]"/>
          <!-- text, commens, and pi's that interpolate the pair -->
          <xsl:apply-templates select="../node()[count(preceding-sibling::*)=$pos and not(self::*)]"/>
          <!-- the first element becomes the second -->
          <xsl:apply-templates select="."/>
        </xsl:if>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

When using this reverse map to remove namespace prefixes, an element that matches more than key should be ignored (in contrast to the possibilities for addin prefixes that were listed above). This is so that an element that needs an explicit namespace qualifier to disambiguate it, keeps this qualifier.

Extensibility

In the example above, the relation between the LZX, XInclude, and XHTML namespaces was baked into the processor (or whoever generates the name resolution map). An system designed for extensibility might allow per-document declarations, as the XML Include specification does. For example, a document that uses unqualified imports from XInclude and XHTML might begin with declarations to this effect:

<canvas xmlns="http://www.laszlosystems.com/2003/05/lzx">
  <import namespace="http://www.w3.org/2003/XInclude"/>
  <import namespace="http://www.w3.org/1999/xhtml"/>
  <xi:include href="mytext.lzx"/>
  <mybutton>Click <xhtml:b>me</xhtml:b></mybutton>
</canvas>

The namespace qualification stage of the processing pipeline would in this case be responsible for retrieving or constructing maps for the XInclude and XHTML namespaces.

Stepping Back

Unqualified imports solve one of the XML readability problems when XML is being used as a programming language. They let the author combine names from multiple namespaces without writing a prefix for each element, unless this is necessary to disambiguate the element’s name.

As with unqualified imports in conventional programming languages, unqualified imports in XML involve a tradeoff. In exchange for brevity, they introduce ambiguity — even if it’s a local ambiguity that downstream processing disambiguates in a well-specified manner. They complicate the rules for determining a name’s namespace — both for processing stages (which must be placed after the disambiguation step given in XSLT in this posting), and for humans looking to determine which qualified name a given tag name in the document source refers to.

Unqualified imports also give up some degree of forwards compatability. An XML document that uses XML Namespaces won’t break if one of the namespaces is extended with a name that matches a tag name that is used, unqualified, in the document. A document that uses unqualified imports may.

These tradeoffs — a more complicated qualification model, decreased chance of forwards compatability — are the same tradeoffs that the use of unqualified imports raises in programming languages. Unqualified imports aren’t always appropriate, but they would be good as a choice for XML programming just as they are in conventional programming — to be used when the context makes them appropriate.

In the design of LZX, we decided the context was appropriate for unqualified imports. The current implementation of LZX doesn’t actually use this system (you can’t actually use xi:include and xhtml:b, just include and @b@), but LZX is designed to be forwards-compatable with a system that does.

What’s in a Namespace?

Posted by Oliver on August 02, 2004

Last week I discussed the fact that “namespace hygiene” — the use of XML namespaces — would cause a simple Laszlo program such as this one:

<canvas>
  <include href="button.lzx"/>
  <button>Click <b>me</b></button>
</canvas>

to balloon to the following mixture of namespace declarations and namespace prefixes:

<canvas xmlns="http://www.laszlosystems.com/2003/05/lzx"
        xmlns:xhtml="http://www.w3.org/1999/xhtml"
        xmlns:xi="http://www.w3.org/2003/XInclude">
  <xi:include href="mytext.lzx"/>
  <mybutton>Click <xhtml:b>me</xhtml:b></mybutton>
</canvas>

This namespace explosion isn’t a problem for the server-side Java engineer or the XML-savvy processing pipeline plumber. XML is moving in this direction, and the preceding document isn’t overly heavy on punctuation compared to the typical XSLT source file, Jelly file, or JSP file that uses tag libraries.

It is a problem for a number of OO, GUI, and DHTML developers that should also be able to use LZX. The concepts associated with LZX aren’t that difficult, and don’t have anything to do with the hard problems in document integration that XML Namespaces are intended to resolve.

I also believe that the extra verbosity slows the speed of even expert developes, because it gets in the way of simple examples, in documentation and pedagogy, and exploratory programming and unit testing during development. I suspect that this is a contentious statement, because it comes down to a difference in development styles that is masquerading as a religious issue. I would like to discuss this later, but not today.

For now I’d like to assume there’s some merit to making programs that are written in XML look more like the first example above than the second one, and explore whether this can be done in a well-defined way.

Namespaces reviewed

A namespace is a map from names (string literals or “symbols”) to something else. The something else might be a variable, value cell, type, class, or just a longer name (which might name one of these). If a name can mean two different things in two different contexts, then namespaces are involved.

An example from the C programming language is the difference between struct names and variable names. A struct can be named date, and this is completely independent of whether a variable is also named date. An example from Java is the package. The java.lang.awt.List class is unrelated to the java.util.List interface, because one is in the java.awt package, and the other is in java.util.

Each interface and class in Java defines a namespace. Two classes A@ and @B, that are unrelated by class inheritance, can define a field named x@. @A.x is unrelated to B.x: the two fields can have different types and visibilities.

In fact, a Java class definition defines more than one namespace. One namespace is the namespace of fields of that class. Another is the namespace of class methods. A Java class A@ can therefore define both a _field_ named @A.year, and a method named A.year. This is in contrast to Python, where a method is a particular kind of attribute (the Python name for “field”) — fields and methods belong to the same namespace. (This also illustrates the difference between the space of names and the space of referents for those names. If B@ extends @A, then the year@s in @A.year and B.year are in different namespaces, but refer to the same method or field.)

Namespaces in programming languages solve two problems. One is the tendency to run out of meaningful identifiers within a package controlled by a single owner. The other is the problem of packages controlled by multiple owners. (”Owner” here simply means someone with authority to modify the names used within the package. If you’re able to modify all the source code you use, the second problem reduces to the first one.) Namespaces address these problems by doing away with the one-to-one correspondence between the spelling of the name and its referent. The correspondence between the name and the named entity is now a function of the context of the name, as well as its spelling.

Namespace selection

Given multiple namespaces, what rules are used to determine which namespace is used for a given occurrence of a name? There are two main methods of namespace selection, or name resolution.

First, the namespace may be a function of its syntactic type. For example, in Java, methods and fields are in different namespaces, as we saw above. In XML, tag names and attribute names are in different namespaces. Lisp dialects are famously divided into Lisp 1 and Lisp 2 dialects, depending on whether variables and functions share a namespace. This method of namespace resolution is used when there’s a small number of implicitly defined namespaces, as in the difference between methods and fields, or the namespaces that a class definition introduces.

The second method of namespace resolution is explicit: Each namespace has a name, and the program language has syntax for specifying the namespaces that are used in different contexts. Java and Python use the import statement for this. XML uses the xmlns and xmlns:* attributes.

(Note that if namespaces are named, as in the second method, there still has to be a way to resolve the referent of a namespace — there has to be a namespace of names, as it were. Often this bottoms out in a load path or other list of linked libraries. For example, the resolution of java.util.List into an interface is defined by the classes on the CLASSPATH.)

Programming languages that use import generally have two styles for specifying what is imported, and two styles for specifying how the imported name is named:

Literal and wildcard imports

Consider the difference between the following two Java statements:

import java.util.List;
import java.util.*;

The first line makes List available as a name for java.util.List. The second line does this too, but makes any other class and interface names in java.util available, without the preceding java.util., as well.

This corresponds to the distinction between the Python statements:

from java.util import List
from java.util import *

and also between the Haskell statements:

import Prelude
import Prelude {List}

The point of the multiple examples being that this is a pretty widely accepted design for namespaces, not just an accident of Java.

(Python differs from Java and Haskell in that (1) in Python, a namespace is a runtime object, and (2) import is defined to modify an existing namespace at runtime. Also in Python, like XML and unlike Java and Haskell, the scope of an import can be smaller than the entirety of a source file. These are three of many other differences among the way name lookup happens in different languages, that I’m ignoring here.)

Unqualified and qualified names

A qualifier is a string that is attached to the name (usually by prefixing it), at the point where the name is used. For instance, List is an unqualified name; java.util.List is a qualified name: it is the simple name List, prefixed by the string java.util. to indicate that it names the List interface in the java.util package.

Java always allows qualified names. java.util.List is valid as an interface name regardless of whether an import statement for java.util or java.util.List exists. The import statement, in Java, is only for the purpose of allowing unqualified names as well: in the presence of import java.util.List or import java.util.*, List and java.util.List are synonymous.

Python and Haskell require an import statement in order to use a name defined in a different code unit. Consider the difference between the Python statements:

import java.util.List
from java.util import List

The first introduces java.util.List (but not List). The second introduces List (but not java.util.List). It is perfectly legal to include both statements in a source file. In this case, List and java.util.List will refer to the same value.

Rounding out the example set, Haskell allows this same distinction:

import qualified Prelude
import qualified Prelude {List}

Note that the distinction between qualified and unqualified imports is orthogonal to the distinction literal and wildcard imports:

import java.util.List      # Qualified literal
from java.util import List # Unqualified literal
import java.util.*         # Qualified wildcard
from java.util import *    # Unqualified wildcard

Conflict resolution

What happens when both java.util.List and java.awt.List are imported? (As unqualified imports, otherwise there isn’t any problem.) There are a number of logical possibilities, but there are three that I’ve seen used:

  1. It’s a compile-time error, whether or not List is ever used. The Common Lisp package system used this. It was incredibly painful.
  1. It’s a compile-time error if List is used; otherwise it’s legal. C++ and Java use this policy. It seems to work well.
  1. One takes precedence. Python uses this policy. It sounds like it would be a potential source of errors, but it seems to work in practice.

Where does XML fit in

XML Namespaces allow both qualified and unqualified names. xmlns="http://www.w3.org/1999/xhtml" defines a namespace that is used by unqualified tag names such as h1@. @xmlns:xhtml="http://www.w3.org/1999/xhtml" defines a namespace that is used by names such as xhtml:h1 that are qualified by the prefix xhtml:.

XML is like Python in that a namespace must be declared to be used. In the absence of an xmlns or xmlns:xhtml attribute, it is impossible to use the h1@ tag from the @http://www.w3.org/1999/xhtml namespace. {http://www.w3.org/1999/xhtml}h1 is often used in XML written material to refer to this tag, but this is an abbreviation for h1@ or @xhtml:h1. In a context that contains an xmlns attribute. It’s not valid XML.

XML differs from the programming languages I discussed in one important way: In any given context, only names from one namespace may be used without qualification. Unlike Java, Python, Haskell, C++, Common Lisp, and every other language I know that has explicit namespaces at all, in XML, you can’t mix and match names from n different namespaces unless you prefix n-1 of them at each point that they’re used.

For example, In Java you can import both List from the java.util package and FastArrayList from the org.apache.commons.collections, and use both List and FastArrayList without qualifiers. (This is handy because FastArrayList implements the List interface.)

import java.util.List;
import org.apache.commons.collections.FastArrayList;
...
  List children = new FastArrayList();

In XML, you can choose one namespace or the other to use without qualification, but not both — even if the two namespaces don’t define any tags with the same names. This is the same as the conflict resolution rule I found unwieldy in Common Lisp, but worse — it’s not only an error if the two namespaces share a name, it’s an error just to import them both unqualified at all!

If Java did this, you would have to choose between writing:

List children = new FastArrayList();
java.util.List children = new org.apache.commons.collections.FastArrayList();
java.util.List children = new org.apache.commons.collections.FastArrayList();

I think there’s a reason that none of C++, Java, Python, and Haskell confines you to this choice.

Is there a way out?

In my next post I’ll propose a way to make XML look more like a programming language in its use of namespaces, discuss where it’s appropriate to do this (there are plenty of places XML Namespaces are used today where my proposal wouldn’t be appropriate), and give a proof of concept, in XSLT, that this can be done with a well-defined semantics.

A Fresh Canvas 1

Posted by Oliver on July 25, 2004

Dave Hyatt has been taking some heat for introducing new HTML tags into the set of tags supported by Apple’s Dashboard. Read the post that started it here. Eric Meyer and Tim Bray take issue with the proposal here and here, and Hyatt responds here.

As the author of an XML-based presentation language, this is an issue dear to my heart. Like Dashboard, LZX is intended for the creation of cinematic interfaces — HTML-embedded applications that are more interactive and have a design esthetic beyond what can be achieved with portable HTML+CSS. And like Dashboard, LZX applications leverage current browser technology.

(One difference between LZX and Dashboard is that LZX is for deploying applications into today’s browsers, so it’s compiled to the swf file format, instead of requiring a browser rev. This is at the level of implementation strategy; it’s not reflected in the language or API design.)

A major difference between LZX and the Dashboard extensions, at the language design level, is that LZX is an application of XML, not a dialect of HTML. This avoids some of the issues, such as how an LZX file should render when interpreted without extensions. However, as we shall see, the “tag import” issue is exactly the same, and LZX uses the same solution that Tim Bray objects to. Here are the issues, and here’s why.

Foreign Tags

The “foreign” tags that LZX currently supports are limited to three categories:

  • XHTML tags within a <text> tag or a tag that extends or contains it. For example, <button><b>click</b> me</button>.
  • The <include> tag from XInclude: <include href="tabsliders.lzx"/>
  • Domain-specific tags within an XML island: <dataset name="addressbook"><contacts>...</contacts></dataset>.

The presence of tags defined by a W3 standard — XHTML or XInclude — immediately raises the question of how to integrate them into an XML document in the LZX namespace. These tags are intended to have the same syntax (attributes and content) and semantics (processing and rendering effect) as the tags in those standards. Is there a way to indicate that the similarity between the LZX <b> tag and the XHTML <b> tag isn’t just in the spelling?

Namespaces

Integrating tags from multiple tag sets is exactly the issue that XML namespaces are designed to solve. In a language designed for W3 experts, the button example would be <canvas><button><b xmlns="http://www.w3.org/1999/xhtml">click</b> me</button><canvas> — or, perhaps more realistically, <canvas xmlns:xhtml="http://www.w3.org/1999/xhtml"><button><xhtml:b>click</xhtml:b> me</button><canvas>. (The latter avoids repeating the bulky namespace declaration at the root of each fragment that includes XHTML tags.)

Consider the second, more realistic example. There are two differences between this solution and the namespace-free solution that I listed. First, the namespace solution prefixes each XHTML tag name with “xhtml:“. Second, the namespace solution includes a namespace declaration on the document root element. The “header” for any LZX file that contained an XHTML tag would include a namespace declaration for xmlns:xhtml="http://www.w3.org/1999/xhtml".

There are two problems with this solution. One is that it raises the bar for learning LZX from the developer who understands XML, to require an understanding of XML namespaces as well. This may be fine if your developers are back-end XML processing gurus or server engineers who speak JSTL and Struts. It’s an artificial barrier for a number of OO and GUI developers with a background in Swing, JavaScript, or MFC.

The other problem is that even short programs are now long: there’s a bit of arcana (a difficult-to-remember URL and notation) that must be stuck at the beginning of every program. “Hello World” in LZX is <canvas><text>Hello World</text></canvas>; “Hello World” that fades out when you click on it is the single line of text below. Requiring namespace declarations doesn’t just add a couple of lines to each finished program or library file (where the tax is only a fraction of a percent); it adds to the expense of exploratory programming too, and it increases the cost of writing unit tests, which ought to be (able to be) short.

[FLASH]%http://boston.laszlosystems.com/lps-doc/goodbye.lzx?lzt=swf%,%500%,%020%[/FLASH]

<canvas>
  <text onclick="animate('opacity', 0, 1000)">Goodbye World</text>
</canvas>

The first problem is the “barrier to entry” that namespaces present to the newcomer. The second problem is the “barrier to file creation” that remains even for the expert, and that manifests itself as a barrier to exploration, and to unit testing.

Boilerplate

The namespace declaration and prefixes are boilerplate: they’re common to every LZX file, and therefore don’t add information about what distinguishes a specific LZX file from all others. The use of namespaces trades self-declaring semantics (useful for automated processing and tooling) against the kinds of communication characteristics useful to programming languages and human-oriented markup. This is a true tradeoff: there are advantages on both sides. It’s obviously the right tradeoff for a one-off document that represents the only convergence of a particular set of tag sets, or for a document whose processing is implemented by a modular set of tag handlers that are bound at runtime. For an XML application with a cohesive tag set — one that is more akin to a programming language — this tradeoff is arguably wrong.

Tools can address the boilerplate problem to a certain extent. My copy of emacs is set to insert boilerplate with the stroke of a key or if the file suffix is known, and to elide standard header text from the display of a file. I still find that I avoid the heavy-boilerplate languages. Emacs can’t help with the tutorials and reference materials, and the boilerplate-hiding tools are imperfect and difficult to configure. They also don’t help with all the “xhtml:“s stuck in the middle of a program.

Wholesale Importing

What we did instead is the same thing that Hyatt proposes : LZX defines a number of XHTML tags, and an include tag, that have the same meaning in LZX as they do in XHTML and XInclude. Tim Bray justly objects to Apple doing this:

Apple has invented a couple of hundred new elements, namely all the XHTML elements, only in the Apple namespace. Uh, I assume they’re defined to have exactly the same semantics as the XHTML versions? Seems kind of unwieldy.

Tomorrow (if I get enough sleep) take a fresh look at the design of XML namespaces in the light of the programming language features that influenced it, and explain how although what we did (and what Apple may be moving towards) is a kludge if viewed from the perspective of XML namespaces as they exist today, it can also be viewed as a prototype of a more XML namespaces as they could have been designed.

Next week I will take a fresh look at the design of XML namespaces the context of other program languages, and examine how they’re the same and how they differ. Following that I will examine how the Dashboard and LZX solutions are special cases of a general design that is useful with XML programming in general.