{"head":{"title":"Sjoerd Visscher's weblog","link":{"@attributes":{"rel":"meta","type":"application\/rdf+xml","title":"FOAF","href":"https:\/\/w3future.com\/people\/sjoerd_visscher\/foaf.rdf"}}},"body":{"section":[{"@attributes":{"id":"content"},"h":"Sjoerd Visscher's weblog","p":"Pondering those web technologies that may change the future of the world wide web.","section":[{"@attributes":{"id":"note"},"p":{"@attributes":{"id":"alternates","class":"buttons"},"l":[{"@attributes":{"href":"https:\/\/w3future.com\/weblog\/index.xml?notransform","rel":"alternate","type":"application\/xml","title":"See this web page with XHTML 2.0 technology."},"span":"Try"},{"@attributes":{"href":"view-source:https:\/\/w3future.com\/weblog\/index.xml?notransform","title":"View the XHTML 2.0 source of this page."},"span":"Src"},{"@attributes":{"href":"https:\/\/w3future.com\/tools\/xr.pl?xr=https:\/\/w3future.com\/xr\/w3f.xml&xml=https:\/\/w3future.com\/weblog\/index.xml%3Fnotransform","rel":"meta","type":"application\/rdf+xml","title":"RDF metadata"},"span":"RDF"}]}},{"h":{"a":"Monday, June 16, 2008"},"a":{"@attributes":{"name":"a300"}},"section":{"@attributes":{"id":"a300"},"h":{"@attributes":{"id":"AlgebraicDataTypesinJavaScript"},"a":"Algebraic Data Types in JavaScript"},"p":["Since the weblog system for this site broke down, and I have to manually update all pages, not much is happening here.\n    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.\n    ,\n    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\n    ."]}},{"h":{"a":"Tuesday, February 28, 2006"},"a":{"@attributes":{"name":"a299"}},"section":{"@attributes":{"id":"a299"},"h":{"@attributes":{"id":"tailCallEliminationInJavascript"},"a":"Tail call elimination in Javascript"},"p":["Via  I read about a . Of course I immediately wondered if it was possible in JavaScript, and it is:","It improves somewhat on the Python example. It allows mutual recursion and recursive methods:","Note the \u2018decorator style\u2019 in Javascript, simply a method call on the function."],"pre":["Function.prototype.tailCallOptimized = function()\n{\n  var g = this;\n  return function()\n  {\n    for (var caller = arguments.callee.caller; caller; caller = caller.caller)\n      if (caller == arguments.callee)\n        throw {tailCallArgs: arguments, tailCallThis: this};\n\n    var args = arguments;\n    var me   = this;\n    while (true)\n    {\n      try\n      {\n        return g.apply(me, args);\n      }\n      catch(e)\n      {\n        if (!e.tailCallArgs)\n          throw e;\n\n        args = e.tailCallArgs;\n        me   = e.tailCallThis;\n      }\n    }\n  };\n}","Number.prototype.isEven = function()\n{\n  return this == 0 ? true  : (this - 1).isOdd();\n}\n.tailCallOptimized();\n\nNumber.prototype.isOdd = function()\n{\n  return this == 0 ? false : (this - 1).isEven();\n};\n\nalert((10001).isEven() ? \"even\" : \"odd\");"]}},{"h":{"a":"Wednesday, December 21, 2005"},"a":{"@attributes":{"name":"a298"}},"section":{"@attributes":{"id":"a298"},"h":{"@attributes":{"id":"technoratiClaim"},"a":"Technorati claim"},"p":{"a":"Technorati Profile"}}},{"h":{"a":"Thursday, October 20, 2005"},"a":{"@attributes":{"name":"a297"}},"section":{"@attributes":{"id":"a297"},"h":{"@attributes":{"id":"leakFreeJavascriptClosures"},"a":"Leak Free Javascript Closures"},"p":["If you're confused about how closures in JavaScript cause memory leaks in Internet Explorer, this is for you: . Then, without leakage, you can write code like this:","Also if you want to do something like this: , and you find out that inside the method  is not , you can now do this:  to fix it."],"pre":"function attach()\n{\n  var element = document.getElementById(\"my-element\");\n  element.attachEvent(\"onclick\", function()\n    {\n      alert(\"Clicked: \" + this.innerHTML);\n    }.closure(element));\n}"}},{"h":{"a":"Sunday, August 14, 2005"},"a":[{"@attributes":{"name":"a296"}},{"@attributes":{"name":"a295"}}],"section":[{"@attributes":{"id":"a296"},"h":{"@attributes":{"id":"noMoreAccesskeys"},"a":"No more accesskeys"},"p":"I had accesskeys for the tabs at the top of this site, but  reminded me that this was very annoying, mainly because  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."},{"@attributes":{"id":"a295"},"h":{"@attributes":{"id":"howToUseBaseUris"},"a":"How to use base URIs."},"p":["If you're wondering what a base URI is for, you'll always end up being directed to , but you won't find much.  just says: \u201cThe term \"relative\" implies that a \"base URI\" exists against which the relative reference is applied.\u201d. But that there's more to it becomes apparent when  come into play. One example is 's . Here is part of it:","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  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 , 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 . Here , the author of RFC 3986, says: \u201c[...] a person is deliberately abusing the base URI by assigning it an unrelated URI for the purpose of creating an\nartificial shorthand notation for external references.\u201d 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:  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]  of base URI abuse in Atom.","To recap:","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 , 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."],"blockquote":{"pre":"<feed xmlns='http:\/\/www.w3.org\/2005\/Atom'\n      xml:base='http:\/\/www.tbray.org\/ongoing\/'\n      xml:lang='en-us'>\n <title>ongoing<\/title>\n <link href='' \/>"},"ul":{"li":["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."]}}]},{"h":{"a":"Sunday, July 17, 2005"},"a":{"@attributes":{"name":"a294"}},"section":{"@attributes":{"id":"a294"},"h":{"@attributes":{"id":"atom10FeedAvailable"},"a":"Atom 1.0 feed available"},"p":"I've updated my Radio Userland Atom code to produce version 1.0.   is created with  from the Atom feed."}},{"h":{"a":"Saturday, June 18, 2005"},"a":{"@attributes":{"name":"a293"}},"section":{"@attributes":{"id":"a293"},"h":{"@attributes":{"id":"iLiveInBelgium"},"a":"I live in Belgium"},"p":"At least, , and Google is always right."}},{"h":{"a":"Wednesday, June 01, 2005"},"a":{"@attributes":{"name":"a292"}},"section":{"@attributes":{"id":"a292"},"h":{"@attributes":{"id":"beingFilmedBy3CamerasAtOnce"},"a":"Being filmed by 3 cameras at once!"},"p":["Sometimes it's really interesting to live in the centre of . Today we had a referendum for ratification of the . I had to vote in the . 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.  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."]}}]},{"@attributes":{"id":"navigation"}},{"@attributes":{"id":"sidebar"}}]}}