Archive for the 'JavaScript' Category

Programming Language in a Web Page: The Conundrum

Tuesday, May 20th, 2008

When is it appropriate to implement a programming language to run in a web page?

I’ve been contemplating this lately as the number of programming-language-in-web-page projects (henceforth referred to as PLIAWPs) has multiplied. I really enjoy language implementations, especially in a language like JavaScript where doing so can be exceedingly concise. So I certainly understand the motivation for writing your own PLIAWP. But is it useful?

On the down side, PLIAWP implementations carry heavy baggage with them:

  • They don’t integrate into native JavaScript debugging facilities. You have to create your own facilities instead. This is the most often overlooked aspect of creating your own language. Writing a parser and interpreter are only the beginning. In order to use your PLIAWP, developers will need error messages with meaningful line numbers, stack traces, syntax-aware editing, graphical debuggers, etc. These are must have features if you want your PLIAWP to achieve anything better that esoteric status.
  • Performance is going to take a hit. If you write an interpreter, you’re looking at an order-of-magnitude slowdown, minimum. If you compile to JavaScript, you’ll do a bit better. But JavaScript’s string-handling facilities vis-a-vis parsing aren’t speedy. Plus, for any language meaningfully different from JavaScript, there’ll be a performance tax trying to fit your language’s runtime into the JavaScript runtime.
  • JavaScript is already a powerful language. What does your language do that JavaScript can’t? Is it really worth forcing developers to learn a new syntax or runtime while giving up the comfort of their existing developer tools?

But it’s not all bad. There are definitely some plusses to building a PLIAWP:

  • It’s fun.
  • It expands the shared knowledge of what’s possible on the web, pushing the limits of what we know how to do.
  • It’s incredibly educational.
  • Did I mention that it’s fun?

But I didn’t mention useful, now did I.

So when does a PLIAWP emerge graduate from interesting to useful? There’s no easy formula, but here’s a few standards I’m sticking to these days:

  1. The PLIAWP must be significantly different from JavaScript. (Think Java versus Haskell different.) While nice syntax has its appeal, that’s not enough to justify the overhead of a full language implementation.
  2. A program written in the PLIAWP must not be trivially convertible into a JavaScript program. (A different way of stating the above point.)
  3. The PLIAWP must solve a specific problem that JavaScript doesn’t solve easily. (If the term “Domain-Specific Language” is coming to mind right now, that’s no coincidence.)
  4. The PLIAWP must be developer-friendly, or at least clearly on the path to developer friendliness.

A while back I built my very own PLIAWP, plus a few similar experiments since. With a couple years reflection since that time, I find it interesting to consider which PLIAWPs meet my standard of usefulness and which fail. GWT passes, generic Ruby/Python/LISP/whatever retreads fail. John Resig’s fabulous processing.js almost passes (more on that in a second), Narrative JavaScript fails.

That’s right, my own pet project fails my own standard. I started Narrative JavaScript with the intent to build something useful. In the end, it turned out esoteric. It addressed in part each of the above benchmarks, but not strongly enough to warrant the effort required for adopting my little PLIAWP. I’ve since learned new programming techniques to mitigate the problem I set out to solve, such that the burden of the developer-unfriendly PLIAWP world makes Narrative JavaScript untenable for real-world projects.

Does that mean I regret building it? Absolute not! I learned a *ton* about programming, computers, and computation from my failed experiment. And I had fun in the process. It was absolutely worth it, and I hope to try again someday when the demands of fatherhood and a successful startup subside enough to give me a little breathing room. Language implementation is a thrill.

So it was with great joy that I watched John launch his processing.js project. He is a budding (if not already great) master at work, unleashing creativity meshed with engineering know-how. It’s truly great stuff, a pleasure to watch. As stated above, I’m not sure the PLIAWP meets my usefulness standard, but I don’t think that matters. I don’t want to rain on this parade. In time, he and others may realize that processing.js would be better off as a highly-tuned JavaScript API than an in-page DSL. But why hurry to that point. Let’s explore this world a bit longer, push the limits a bit further.

Beyond DOM

Sunday, January 6th, 2008

The title of this article is (of course) referring to the browser DOM. Don’t get me wrong, the DOM abstraction was a great invention. IE4 was incredibly innovative, the progenitor of Ajax as we know it today.

But as the Ajax evolution continues on, I keep waiting for a “killer” UI platform that nudges us back toward the simplicity of HTML markup. Remember that? Back in the early days of the web you wrote server-side “scripts” that generated markup on-the-fly. Some people naively thought that manually generating HTML with C/Perl/whatever was OK. Others realized that you could incorporate read-only processing instructions in the markup, rather than markup in your application code, and thus was born tools like Velocity, TAL, and other such templating systems. It wasn’t hard to see the value of these tools, how much better than the alternative, how much easier than stateful programming.

Eventually the abstractors barged in, tried to change HTML to XML, tried to change templating to XSL. And they had…mixed…success.

And meanwhile we got sick of having to go back to the server and regenerate pages every time our customers did something interesting. We wanted small, nay miniscule, updates that allow us to do more with less. And thus Ajax was born.

But what a diversion! What happened to that simple markup we used to write? The server-side frameworks didn’t have enough time to sort out their differences, to evolve to the right level of simplicity. Yet we’ve already moved on. The clarity of execution flow in generating a web page? Gone. The simplicity of learning curve? Absent.

Am I the only one who yearns to circle back?

Here’s the problem as I see it: the UI I’ve coded, what you see on the screen, is a reflection (some would call it a transformation) of the data sitting in memory in my JavaScript objects. So why is it that every time the data changes I have to go twiddle something in the DOM? Shouldn’t that just happen automagically?

Why should I have to wrap my head around two UI representations, the markup and the DOM? Markup is easy to read but captures a small sliver of the UI gestalt. The DOM captures everything else, but sits in memory. Can’t it all just be markup, so that I don’t have to spend so much time visualizing data structures whose only representation is either in code or in Firebug?

The DOM is hot property, a cool kid these days. So it won’t surprise me if this plea falls on deaf ears. But I believe that the world could use UI that is described rather than commanded, stateless rather than iterative, that puts the V back in MVC.

I can’t help but feel we’re moving inexorably in the wrong direction, bit-by-bit, and no one is noticing.

And so I sit waiting patiently, occasionally scheming…

Generators and Erlang Processes

Friday, December 21st, 2007

I’ve always thought that there’s a convenient symmetry between generators and Erlang-style processes. So it’s neat to see that Alex Graveley has been exploring Erlang-style “concurrency” in JavaScript by piggy-backing off my generator based “threading” library.

I sometimes wonder what it would take to expand JavaScript generators to become truly concurrent. Maybe something as simple as a “start” method on a generator object:

function myConcurrent(param) {
  yield wasteTime(param);
}

let gen = myConcurrent(someValue);
gen.start();
let result = wasteMoreTime();
result += gen.next();
gen.close();

where start() causes the generator to begin execution concurrently, and next() or send() act like a thread join.

It’s such a small but powerful extension. It seems appealing up-front, but the devil is in the details. What’s the memory model? Much of Erlang’s appeal stems from its shared-nothing semantics. How would you replicate that with JS generators? Enforce pass-by-value? If next() and send() join, then how exactly do we get the Erlang-style message passing going?

Or maybe there’s no enforcement of shared nothing and caveat emptor? But then you need synchronization for shared objects. Blech.

An interesting thought experiment. To be clear, there’s no talk of anything like this (AFAIK) amongst the JavaScript language designers. Just a random Friday daydream.

The Case for ES4

Thursday, November 29th, 2007

Brendan has written up an extensive, detailed post making his case for the need for ES4.  It’s a good read.  I think he makes a strong case.

I fear that it may be too nuanced to be consumed and condensed into “sound bytes” appropriate for the political firestorm that is underway. This is not “light” reading.

In other words, it takes time for the gestalt of ES4 to sink in.  If you read the post and find it not to your liking, put it away and come back later. Write some JS code, think about the difficulties you’re facing.  Perhaps some “aha!” moments will ensue. For me, the essence of ES4 didn’t kick in for a long time — several months.  Your mileage may vary.

The Story Behind ES4

Thursday, November 1st, 2007

Doug misspeaks, Brendan responds forcefully, Chris weighs in, Brendan lashes out some more, and Dion naively asks, “can’t we all just get along?”

*sigh*

Ok, here’s what happened according to the record:

  • ES4 design starts in October of 2005
  • Doug (Yahoo) joins the discussion in June of 2006, is worried about Microsoft’s support
  • Pratap (Microsoft) goes on record in July of 2006 saying that ES4 will be in IE after version 7
  • Design continues unabated
  • Doug and Pratap registers concern about the size of the spec in March of 2007
  • An ES 3.1 proposal is made in April of 2007, but work stalls
  • A few weeks ago, Doug states that TG1 is “split” on ES4 at the The Ajax Experience conference (a statement that’s not necessarily accurate)
  • Some interpret his remarks as saying there’s a secret coalition between Adobe and Microsoft to force ES4 through and co-opt the standards process
  • Acrimony erupts

What really happened, near as I can tell (warning, speculation ahead):

  • Pratap wasn’t in close communication with his developers and superiors internally at Microsoft early on in the process. Once he finally got feedback internally, he found out that they didn’t like it. Stuck between a rock and a hard place, he tried to work out a compromise resolution in “ES 3.1″, but people further up the chain at Microsoft caught wind of what’s going on in ES4 and put on the brakes. Microsoft went into radio silence until everything spilled out onto the web.
  • Brendan sees what’s coming, and knows it’s not good. If Microsoft has put the brakes on ES4, it means they’re going to split off and go in they’re own direction. He’s concerned because it puts the future of web application development in jeopardy. This is looking all-to-familiar to him, so he responds with vigor to try and “rally the troops” to fight an unfair turn against several years of dedicated, hard work. His responses are clearly filled with heartfelt passion.
  • Chris’s job is as much political as it is technical. And he’s reeeally good at it. His job is to make sure that Microsoft has a valid stance in the eyes of web developers, even when opposing viewpoints are valid. It’s his job. He may truly believe everything he’s saying; then again, he could be putting up cover for a deeper strategy internally at Microsoft. We can’t know, because he gets paid well to speak well, and he’s good at it.

My thoughts:

  • On purely technical grounds, ES4 is an excellent proposal. It is well-engineered, precise, and balanced. (It is also extremely nuanced, which makes it hard to judge at-a-glance. This is not “a new Java.”)
  • Brendan’s passion is coming off as wild-eyed fanatacism. This is turning lots of people off. Is this a political, personal, or technical battle to him? It’s hard to tell from the tone of his comments. Now, where’s that middle ground again?
  • Chris Wilson is smooth. He’s got a silky smooth voice, and gosh darn it if I don’t just want to be his friend, even if I don’t trust him.
  • Chris wants: stability, interoperability, security, and functionality, in that order. Yet after repeated requests to provide specific, detailed, technical reasons why ES4 doesn’t address all four of those priorities (which it does, IMHO), no answer. I have yet to see a single detailed explanation of how ES4 would “break the web.” Not from Chris, Doug, or anyone else at Microsoft. Would love to see such discussion, truly. Send me links if you know of any.
  • Abject fear is not constructive criticism, and it’s not a strategy. There has got to be discussion about the flaws of this proposal that goes deeper than “I’m afraid of it.”

And if you think there’s some safe “middle ground,” I can only say: I doubt it. Language design (or at least, *good* language design) takes a long time, and Microsoft hasn’t even started drafting their ideas yet. Even if they truly believe that what they’re doing is the right thing for the web, by forking now they’re damning the web to stalled evolution and non-interoperability for at least the next 5 years, probably longer. (It’ll take 1-2 years to get the forked version out the door, another 1-2 years before any convergence between browsers can happen, and another 1-2 years before there’s significant market share for interoperable code. And that’s best-case.)

So think about that before weighing in against ES4. Do you want the status quo for the next 5+ years? I sure don’t.

In parting I’ll point out: no design will be liked by every developer, and that’s precisely the problem here. Not everyone can get what they think is best in this case. But, without support from all vendors, *no one* will get what they think is best. All vendors participated without reservation in the ES4 design until March of 2007. And even after reservations were spoken, no active participation to resolve the outstanding issues has occurred since. Given that, it hardly seems fair to say that ES4 is attempting to do something that will “break the web.” Quite the opposite.

Ajax is…Dead?

Thursday, October 4th, 2007

One of Joel’s recent posts has been tumbling around in the back of my head. His observations are, as always, excellent. But unlike his usual posts, the conclusions drawn in this one mystify me. I see his point, but it feels…crazy.

One important truth he reveals is that software projects need not run optimally on today’s hardware; Moore’s law and the passage of time guarantee that when your product hits its prime market share, the hardware will be capable of supporting it.

Apply this maxim to development platforms, flip things around a bit, and we get this:

Any software development platform incapable of fully utilizing its hardware will surely fail.

This is true because there will always be some other platform that is capable of soaking up all that power, and that platform is going to have whiz-bang features that everyone’s gotta have right now that can’t be done in the old-fashioned turtle-speed platform.

Java is a great example. For those of us who used it back in the mid-90’s when it was brand new, it was slooooow. It was hard to believe that this was a “real” development platform. But it had some great features that outweighed the perf issues. And 10 years later, after 5 or so revs of Moore’s law and some nice optimization, Java is king. (Or at least queen.)

Case study #2: Ajax. Remember Ajax back in 2000? Yeah, I do too. If there’s a lesson to be learned from Java and Ajax, it’s this: your development platform should aim to run on tomorrow’s hardware. Worried that RoR is too CPU intensive? Relax, Moore’s Law will take care of it.

But…

Moore’s law isn’t quite the same as it used to be, now is it? As you might have heard (sarcasm), the multi-core world is coming, and a few people are a bit riled up about it.

Back to Joel and Ajax. Ajax depends on JavaScript, and JavaScript — as currently spec’d and implemented in browsers — is a single-core beast. The new version — supercharged kitchen-sink-of-features, still in its final spec’ing stages — will probably appear in the wild sometime late 2008. And what’s the new version doing to integrate well into the new multi-core world?

Well, nothing really. And it’s too late to change that.

So now we’re looking at version 3 of JavaScript before multi-core deficiencies will be addressed. Meanwhile it’s at least a few years before version 2 is established enough for Ajax apps and frameworks to depend on its features. Lather, rinse, repeat, it’s another couple years after that before theoretical multi-core Ajax apps are viable.

Repeat: the performance of Ajax apps will remain little-changed for the at least the next 3 to 5 years, unable to utilize multi-core processing power. (Same thing applies to Flash too, you’ll notice.) By that time, current processors will likely have 16+ cores. That’s a whopping amount of processing power lying dormant.

Do you think 5 years enough time for someone to build a platform that contains all the benefits of Ajax, plus some new great stuff, that lets developers soak up all the processing power in those extra cores, and deploy it to 90%+ of machines out there? Do you think maybe some of the big players have efforts in this space already underway? (hint: Gears is a start.) It’s just a question of who and how soon.

So what does this mean for Ajax? For one thing, it means that Ajax — as it currently exists is — will have to evolve for the long term. One of the major browser vendors is going to have break ranks and extend the browser platform to go multi-core (it won’t happen in lock-step — design-by-standards-committee is too slow and will inevitably lead to a back-stab). Either that or something new will emerge. (Or more likely, many new things will emerge.)

Get ready to brush up your skills…

Threading in JavaScript 1.7

Wednesday, February 7th, 2007

Amongst the many new features contained in Firefox 2 you’ll find JavaScript 1.7 support, a small but significant language enhancement that includes python style generators.

A generator allows you to suspend a function’s execution and resume it at a later time. While typically used for advanced looping constructs, a generator can also be flipped inside-out and used as a rudimentary coroutine.

At first glance, this may not look very impressive, especially since generators are unable to yield across multiple frames in the callstack. However, with the help of a technique called trampolining generators can be used to write code in a style similar to threaded programming.

The way trampolining works is that a scheduler object (written in JavaScript) manages the execution of a series of generators, cobbling together a stack-like execution. Here’s how it works: The scheduler sets the starting generator as the base “frame” in the call stack. The scheduler then calls next() on the generator to obtain a yield value. If the yielded value is itself a generator, the scheduler pushes this new generator on the stack and calls next() on it, again obtaining a yield value. This continues until the top generator yields a non-generator value. This value could be a special directive to the scheduler (for example, a SUSPEND value that tells the scheduler to freeze execution of the “stack” of generators we’ve piled up). If not, the scheduler treats it as a return value. The scheduler then pops and closes the now complete generator and sends the return value back into the next generator in the stack.

Sound confusing? It’s a mind-bender — I had to read a trampolining description and its sample code a few times before I understood how it works.

The coding style when trampolining is a little awkward. You need to yield any function call that will suspend execution of the stack. Here’s a contrived example:

  function myThreadedCall() {
     while (!ready) {
       yield sleep(100);
     }
     yield waitForInput();
     if ((yield post(getInput())) != null ) {
       yield animateUI();
     }
   }

In this way, using generators to trampoline is a very explicit form of concurrency. It’s verbose (unlike, say, Lua-style coroutines), but that verbosity has the upside of execution clarity — it’s much easier to see on visual inspection where race conditions can occur.

(Those of you with sharp eyes will notice that the technique described here is not true threading, but fancy coroutines. That’s the underlying implementation; to the programmer using this technique, it looks a lot like threading.)

No discussion like this would be complete without a pointless example, and this post is no exception. Check out this example (only works in Firefox 2), along with the example source and the threading library.

The use of generators and trampoling isn’t a panacea for concurrency in JavaScript. The technique renders code essentially “stackless” as far as the JavaScript interpreter is concerned, which means that you won’t get a meaningful stack trace if an error occurs. Thus debugging can be a bit painful.

However, it’s worth noting that the trampolining Thread.js is a slim 4K (uncompressed). And there’s no pre-compilation, no parsing, no AST manipulation, and no code generation. Simple. That’s the benefit of native language features.

All in all, I wish JavaScript had a more directly supported concurrency mechanism. I raised the topic on the ES4/JavaScript 2 discussion list, but in the end it was decided that the inability to yield through native C stack frames at the implementation level made it infeasible for some embeddings (such as cell phones and other devices). We’ll see what happens in later versions. (Brendan Eich has hinted that JS3 will be ready for multicore desktops.)