Layers of Confusion

I missed a Plus post by Ian Hickson back from August but I saw it today through the magic of the twitters. It contains quite a lot to quibble about, but I want to home in on something he wrote in the comments in response to Will Sargent, RE: one of my posts on layering in the platform:

…I don’t really share his vision. I think JS is an important part of the Web, but I don’t see it as any more core to the Web than CSS, HTML, the DOM APIs, HTTP, etc. Most of the proposals I’ve seen to take JS and build a platform on it tend to fall down on #3, #4, and #5. In particular, I think fundamentally #3 and #4 basically force the platform to have a declarative part (the declarative XAML part of .NET is how it managed to address #4, for instance, and the declarative design of XHTML2 and RDF are how they manage to address #3). That doesn’t have to mean that the code part is a secondary part, though. I think the Web has reached a point where you can think of the DOM as the core, with JS and the HTML syntax layered atop that (much like how in .NET there’s objects that can be represented in XAML or generated from C#), which puts the JS part on par with the HTML part in terms of importance to the platform.

This is either me not articulating my “vision” clearly, Hixie mis-understanding my point(s), or some combination thereof. So I’ll try again in 4 paragraphs:

I make no claims about the relative importance of HTML, CSS, JS, DOM or any of the rest. It honestly feels silly to talk about the platform that way. I argue something very, very different: HTML, DOM, and (to a lesser extent) CSS should all conceptually bottom out at JS. I’m not saying “go write a browser in JS”…that’s also non-sequitur. JS must, of course, appeal in turn to C/C++ so a “browser written in JS” would need privileged APIs provided by C/C++ or something lower level.

What I’m saying is something very direct: there’s no other ubiquitous programming language for the web. JS is the only game in town. As a result, when we describe imperative behavior in prose (as the HTML5 spec does) that behavior could, in theory, be implemented in JS (or some sub/super-set). Since HTML, DOM, and CSS aren’t Turing-complete, they naturally belong at a “higher level” in the web platform stack.

Now, all of this sounds dangerously academic and perhaps nuts…but consider that we have to expose APIs for nearly all of this stuff. Whenever we add something to HTML, CSS, etc., it always comes with some sort of API. Now, that could be a good API, or it could be an obtuse turn around the parser after some terrible string concatenation.

I’m claiming that you get better APIs when you design your imperative explanation of the declarative stuff — which you MUST do for specs to be sane — in JS. This means designing new APIs to help you accomplish the task at hand as you go. Doing it that way ends you up with the types, APIs, and security boundaries you’re going to need in the end anyway. Doing it the other way, patching crap onto the side later without explaining how the declarative stuff “works”, just leads to the pain and constant need for case-by-case revision that we see in today’s web APIs.

That’s the whole argument in 4 ‘grafs. It’s subtle, but I hope not terribly controversial. Importantly, nothing about it demands giving up on any of Hixie’s 5 arguments. He can keep ‘em all and still get a well-layered platform. We’ve got enough examples of doing it wrong under our belt to see how painful the badly-layered web is today. We can end this insanity — not by claiming that any part of the platform is “more important” — by explaining the platform in layers, higher levels in terms of the lower levels.

6 Comments

  1. Posted November 23, 2012 at 6:22 pm | Permalink

    Minor correction: HTML+CSS3 is indeed Turing Complete. Here is an implementation of Rule 110:

  2. Posted November 23, 2012 at 6:23 pm | Permalink

    The link in the last comment was stripped:

    http://eli.fox-epste.in/rule110-full.html

  3. Posted November 26, 2012 at 7:20 am | Permalink

    Wow, that’s immensely clever. The sibling + universal selector trick for the wrap-around is amazing.

    Not sure it defeats the argument per say, but I’ll need to keep it in mind in future.

  4. Posted November 26, 2012 at 5:49 pm | Permalink

    I think Ian himself does not understand that HTML is not “just HTML” anymore. CSS and HTML are extremely limited. Browser vendors cannot implement all features that millions (yes, this is not a typo) of developers demand.

    Only Javascript can satisfy the hunger for new features for them. But Javascript cannot do much without APIs, and so: +1 to your article.

    @michael, that’s a good illustration – programming in css is harder and clunkier, than programming in assembler. Today people want augmented reality, and browsers/specs give them rounded corners and hgroup tag.

    WebRTC, WebComponents, JS DOM Bindings and better cache/storage mechanisms. This will open a new chapter in Web’s timeline.

  5. Boris
    Posted December 3, 2012 at 11:04 pm | Permalink

    There’s a fundamental assumption here that the declarative stuff must then proceed to be specified in an imperative manner. But that’s simply not true. Large parts of CSS are instead specified in terms of a constraint model.

    Now obviously you can do an imperative implementation of a constraint model, but doing that with a specification overconstrains (pun intended) your implementation strategies, because back-solving from an imperative description to a constraint model without introducing bugs is rocket science.

    In fact, I’d go so far as to say that constraint-model descriptions are vastly superior to imperative ones when they’re possible: they lend themselves more to parallel algorithms, they allow a variety of implementation strategies, and they’re often much easier to understand.

    Now of course for things like DOM tree manipulation, where there really is a lot of imperative stuff going on your suggestion makes sense. But even there, things like “update layout state” are really more described in terms of constraints, not explicit imperative algorithms.

  6. Posted December 6, 2012 at 3:45 am | Permalink

    Hey Boris,

    I’m intimately familiar with the ways that CSS is constraint based and not necessarily imperative, see:

    http://infrequently.org/12/cassowary-js-refactor/demos/css/canvas-renderer.html

    https://github.com/slightlyoff/cassowary-js-refactor

    It’s not possible to use simple solvers for CSS without multi-step to accommodate line layout as you need to solve and constrain in multiple dimensions simultaneously, but I digress.

    Back to the main issue: I’m not suggesting that we need to describe CSS as an imperative system — my (as yet unsuccessful) work with constraint solvers is expressly designed to give the WG a tool they can use to stop muddling around in the pseudo-imperative end of the pool and instead prototype features in the constraints directly.

    I am instead suggesting that the areas in which we expose APIs, we need to act as though whatever implementation is “down there” has been written in JS. For declarative features with no API, this is a no-op, but we both know that situation doesn’t last forever. The implementation might, indeed, bottom out at a constraint solver! That’s great, and doesn’t change what I’m advocating for.

One Trackback

  1. By Reforming the W3C TAG | Infrequently Noted on December 7, 2012 at 5:29 am

    [...] drone on and on and on about layering because explaining each bit of the platform in terms of the one below it relieves [...]