Monday, October 1, 2007

XML: A Retarded Innovation

"XML is a prime example of retarded innovation; it makes the life of the low-level plumbing infrastructure easier by putting the burden on the actual users by letting them parse the data themselves by having them write an abstract syntax tree, introducing an alien data model (Infoset) and an overly complicated and verbose type system (XSD) neither of which blends in very well with the paradigm that programmers use to write their actual code. "

-Erik Meijer and Peter Drayton

In public tonight, I laughed audibly at this quote from Meijer and Drayton's draft paper Static Typing Where Possible, Dynamic Typing When Needed: The End of the Cold War Between Programming Languages. This is a spot-on criticism of XML expressed in a single sentence (try to ignore the semi-colon and run-on sentence in the second clause). The paper isn't actually about XML though. It is a guide to features that static typing affords and features that dynamic typing affords, and discusses when to use which.

The authors surprised me by dispelling two common myths about dynamic languages: that they enable lazy evaluation and enable higher-order functions.

The lazy evaluation myth is the thought that loose typing makes it easier to create complex applications by gluing together small components. The common example is the power of Unix shell programs. Because all programs take a simple byte stream as input and output, it is possible to chain any number of Unix programs together and create a meaningful result. It would not be possible to pipe commands together if the byte stream contained complex types (think serialized Java objects) because each program would need to know the format of the objects. So what is the myth? Unix shell programs are powerful, and the input/output of the programs doesn't contain type information... Well, the real power of Unix scripts isn't their input and output format, it is the fact that they produce lazy streams of bytes. The example of ls | more is powerful because the more program doesn't wait until the ls application is finished to begin doing work. If this were the case then the entire output of ls would need to be stored in memory somewhere (performance drain), and the more program would not start displaying until after the entire command had finished (liveness issue). So the real power in Unix programs is the lazy streams, where data is passed to programs as it is available rather than when the batch is finished. In fact, the lack of type information in the stream is a drawback because it limits what the program can do with the data. Lazy evaluation is the power behind lazy lists, Unix pipes, and asynchronous messaging systems.

Hey, and there is one more reason why XML is so rotten: XML cannot be validated until the entire XML document has been read. This means that any operation on XML data should wait until the entire stream is created and parsed, thus ruling out lazy evaluation.

The power to be had from lazy evaluation has nothing to do with dynamic typing... possibly the opposite. Since the .NET CLR and the Java JVM are so similar at the execution level, it would be possible to define a common, and more advanced, data language that provides more power than simple byte streams. But XML ain't that common format!

The other myth explored is the idea that dynamic languages have better support for higher -order functions than static languages. The ability to dynamically eval strings as programs is powerful, and the ease at which it can be done in dynamic languages is striking. It is exciting the first time you pass an algorithm around as a parameter, or store one as a variable without having to resort to the strategy pattern. But a string isn't a function, a string is a data format. And passing a string into a function to be eval'd isn't a higher-order function, it is a substitute for it. Not only is this often unnecessary, but it is also dangerous. The SQL injection attack is an example of untrusted source that relies on eval and strings to work.

The truth is, any language that can dynamically load code can perform runtime code generation to create a higher-order function. In Java, it can be done with dynamic class loaders or native DLLs, and without having to use Strings and an eval method.

Exploring these two myths wasn't even the main point of the article, so if you're at all interested then go check it out. It is definitely in draft form, but it is good reading nonetheless.

1 comment:

Andrey Skvortsov said...

@author:XML cannot be validated until the entire XML document has been read.
Wrong,look at xmlvalidatingreader.