Pondering those web technologies that may change the future of the world wide web.
Since the weblog system for this site broke down, and I have to manually update all pages, not much is happening here. I hope however that some people are still subscribed. If you are reading this then you are probably one of them.
The reason I am posting again is that I have written a bit of JavaScript 1.8 recently. John Resig was right, the new expression closures syntax did tickle me. Functional code looks so much nicer!
The code is a library to work with algebraic data types, which takes some explaining, so read more here.
Via LtU I read about a tail call optimization decorator. Of course I immediately wondered if it was possible in JavaScript, and it is:
Function.prototype.tailCallOptimized = function() { var g = this; return function() { for (var caller = arguments.callee.caller; caller; caller = caller.caller) if (caller == arguments.callee) throw {tailCallArgs: arguments, tailCallThis: this}; var args = arguments; var me = this; while (true) { try { return g.apply(me, args); } catch(e) { if (!e.tailCallArgs) throw e; args = e.tailCallArgs; me = e.tailCallThis; } } }; }
It improves somewhat on the Python example. It allows mutual recursion and recursive methods:
Number.prototype.isEven = function() { return this == 0 ? true : (this - 1).isOdd(); } .tailCallOptimized(); Number.prototype.isOdd = function() { return this == 0 ? false : (this - 1).isEven(); }; alert((10001).isEven() ? "even" : "odd");
Note the ‘decorator style’ in Javascript, simply a method call on the function.
If you're confused about how closures in JavaScript cause memory leaks in Internet Explorer, this is for you: Leak Free Javascript Closures. Then, without leakage, you can write code like this:
function attach() { var element = document.getElementById("my-element"); element.attachEvent("onclick", function() { alert("Clicked: " + this.innerHTML); }.closure(element)); }
Also if you want to do something like this: setTimeout(obj.method, 1000)
, and you find out that inside the method this
is not obj
, you can now do this: setTimeout(obj.method.closure(obj), 1000)
to fix it.
I had accesskeys for the tabs at the top of this site, but Mark Wubben reminded me that this was very annoying, mainly because alt-d was one of them (the shortcut to focus the address bar). This makes me think that using accesskeys in webpages is not a very good idea, because you never know what the favorite shortcut keys of your visitor are.
If you're wondering what a base URI is for, you'll always end up being directed to RFC 3986, but you won't find much. Section 5.1 just says: “The term "relative" implies that a "base URI" exists against which the relative reference is applied.”. But that there's more to it becomes apparent when same-document references come into play. One example is Tim Bray's atom feed. Here is part of it:
<feed xmlns='http://www.w3.org/2005/Atom' xml:base='http://www.tbray.org/ongoing/' xml:lang='en-us'> <title>ongoing</title> <link href='' />
As the base URI is already "http://www.tbray.org/ongoing/", the link to Tim's homepage can be the empty URI. However, according to RFC 3986, this is a same-document reference. It still references the correct URI, so usually you won't notice. But there are cases where this goes wrong, f.e. the XPath 2.0 expression fn:doc(/feed/link/@href)
will get you the current atom document, not the document at http://www.tbray.org/ongoing/. What's worse, you can't fix this by changing the link to <link href='http://www.tbray.org/ongoing/' />
, as the link is still the same as the base URI, so it still is a same-document reference.
So it seems you can't just use any base URI, but only the original URI of the content. Final proof comes from a discussion on the W3C URI mailing list. Here Roy T. Fielding, the author of RFC 3986, says: “[...] a person is deliberately abusing the base URI by assigning it an unrelated URI for the purpose of creating an artificial shorthand notation for external references.” Good to know!
I find it really odd that Roy calls something an abuse, which by most web developers is considered to be the only purpose of a base URI! And that he has added nothing to the new RFC 3986 to make this clear in any way. So we will have to do this ourselves. Spread the word: Stop the abuse of base URIs! I also hope Tim Bray will fix his atom file, as his feed is used as an example by many, so this abuse might spread to a lot of atom files.
[Update] Here's another example of base URI abuse in Atom.
To recap:
- Only use the actual URI of the document as its base URI, or the original URI if the document is moved. (This might actually be a good practice, with the same purpose as the self link in Atom.)
- If you use xml:base, add an xml:base attribute on content that is included from another document. (This happens automatically if you use XInclude.)
- Don't use the base URI for anything else.
Finally I'd like to share a trick to set the base URI for escaped HTML in RSS and Atom: add a BASE element to the beginning of the HTML content. This will work for most aggregators that run in a browser, like Bloglines, or use a browser component to display HTML, like most e-mail client based aggregators. Having multiple BASE elements in one HTML document, while not valid, works fine in most browsers. Aggregators can use this trick themselves as well.
I've updated my Radio Userland Atom code to produce version 1.0. You can find the feed here. My RSS 0.91 feed is created with a simple XSLT transformation from the Atom feed.
At least, that is what Google shows me, and Google is always right.
Sometimes it's really interesting to live in the centre of the administrative capital of the Netherlands. Today we had a referendum for ratification of the Treaty establishing a Constitution for Europe. I had to vote in the city hall. As this is close to the parliament buildings a lot of camera crews had chosen the city hall to film some voters, including me. So I ended up on Dutch national television. Here are some screenshots of that. There were more cameras than voters while I was there!
By the way, I voted in favor of the treaty, but it got rejected by a large majority.