Apr 01

CoffeeScript, Whitespace, and Coffee

JavaScript, Tech 2 Comments »

I enjoy learning new languages. I am not on the yearly diet as the Pragmatic folks would desire, but when I can…. I enjoy expanding my mind as I have definitely experienced the fact that learning a new language makes me program differently in all of my other languages.

Clojure and Scala are interesting to me in the land of Java, but that isn’t where I have been spending time (until recently). I have been very much enjoying Jeremy Ashkenas’s CoffeeScript. What’s not to like? Jeremy has managed to create a language that cleans up many of the issues in JavaScript, and codifies much of the Good Parts into source form. Ruby is my favorite language, and this gets really close to my ideal mental model.

When talking to Brendan Eich about the language, he very much appreciates it, and also the fact that it maps nicely to the JavaScript model (versus something like GWT and Java mapping on top of JavaScript say).

In some ways it feels bizarre to write in a high level language which gets converted to another high level language. One thing that has been enjoyable though is learning this language. The killer features for me are:

  • Jeremy takes care of things like documentation. The main site is the best introduction and documentation for any language.
  • Source code as byte code. I don’t enjoy reading byte code. I do enjoy reading JavaScript code (a language I know well) though. It is fantastic to be able to play with a new language and instantly be able to see the JavaScript output, whether it be small things via the inline site, or via -w / cake watch.

Try CoffeeScript

One feature that I am not a huge fan of is the pythonic importance on significant whitespace. Notice the image above, and how the ordering of elements made a difference to the output.

It is very cool that Firefox is going to “natively” support loading up CoffeeScript, and I think that someone needs to create Coffee and do to Java what CoffeeScript has done to JavaScript.

You could argue that this has already been done….. Groovy? Oh and thanks to the great work of Charles, Tom, Ola, and friends…. I can even use JRuby over there…..

Jan 20

JavaScript Harmony: The JS Train Is Moving

JavaScript, Tech 1 Comment »

harmony

Brendan Eich just spelled out the Harmony of his dreams. A state of the union from the language creator timed for when the ECMA TC39 group gathers to hopefully move the ball forward.

This post made me very happy indeed. Over the years I have gotten to the place where I actually really like JavaScript. There are other languages that I may prefer, but I am at peace with JavaScript and its frustrations.

Variable hoisting and this.foo all over? Crazy, but I am fine.

var self = this; or .bind(this)? Whatever.

Module system is tied to script tags? Worked around.

I was right there with ES4 back in the day, hoping to see a bunch of improvements finally getting in to more than Firefox’s type=”". Then the wheels on the bus came off. There were great additions / changes / clarifications, but the typing and namespaces/programing units/packages features? It went just too far.

JavaScript put its tail between its legs and we had to cheer for the small wins of bind() and create(). Fortunately there were huge wins at the VM level. Modern VMs are fantastic, and paved the way for server side JavaScript with Node…. after all of these years.

We need more. There is a responsibility to backwards compatibility that is always brought up. That is important, but there is also a responsibility to moving the Web stack forward. JavaScript has become the glue and power tool of the Web. In theory you can use that type=”" to do more, but getting all of the browsers to implement a language isn’t going to really happen, so we are stuck with JavaScript for good and ill, for the foreseeable future. Let’s make it great.

So, this is why I am so excited to see Brendan talking about how to do just that. There are some classic lines in his post:

You can do anything with function in JS, but you shouldn’t have to — it over-taxes JS programmers and VM implementors to learn and optimize all the idiomatic patterns. Too much like writing with only one-syllable words.

I agree with Doug that tail calls would be a win, especially with evented code. The # function syntax allows us to give tail calls a boost and save you seven (14 total: function + return_ – #) keystrokes.

Why not bind this to the same value as in the code enclosing the hash-func? Doing so will greatly reduce the need for var self=this or Function.prototype.bind, especially with the Array extras. It’s great that ES5 added bind as a standard method, but why should you have to call it all over the place? If Harmony does not address this issue, I will count that a failure.

A hot-button issue with ES5: Object.freeze. Whose side are you on, Batman’s or Mr. Freeze’s? Simplistic to say the least, since even in one’s own small-world codebase, making some things immutable protects against mistakes. Never mind single- and multi-threaded data sharing and other upside.

The simple modules proposal, along with its module loaders adjunct, is the likely Harmony module system solution. Note that there is no left-hand side example written in current JS below — you’d need a preprocessor, not part of the language.

Closing Remarks

This is a long post. If you made it this far and take away anything, I hope it is Guy’s “Growing a Language” meta-point. JS will be around for a very long time, and it has a chance to evolve until its users can replace TC39 as stewards of its growth. The promised land would be macros, for syntactic abstraction and extensibility. I am not holding my breath, but even without macros, the Harmony-of-my-dreams sketched here would be enough for me.

We aim to do more than dream. Narcissus is coming along nicely since it moved to github and got a shot in the arm from our excellent Mozilla Research interns last summer. We are prototyping Harmony in Narcissus (invoked via njs -H), so you can run it as an alternate <script> engine via the Zaphod Firefox add-on.

@andreasgal has a JS code generator for Narcissus in the works, which promises huge speedups compared to the old metacircular interpreter I wrote for fun in 2004. With good performance, we can actually do some usability studies of Harmony proposals, and avoid Harmony-of-our-nightmares: untested, hard-to-use committee designs.

A code-generating Narcissus has other advantages than performance. Migrating code into Harmony, what with the removal of the global object as top scope (never mind the other changes I’m proposing — here’s another one: let’s fix typeof), needs automated checking and even code rewriting. DoctorJS uses a static analysis built on top of Narcissus, which could be used to find flaws, not just migration changes. Self-hosted parsing, JS-to-JS code generation, and powerful static analysis come together to make a pretty handy Harmonizer tool. So we’re going to build that, too.

More on Narcissus and Zaphod as they develop. When the time is right, we will need users — lots of them. As always, your comments are welcome.

I am sure some programmers will feel like they just read Crock’s good parts and finally get JS…. and now it will change? I remember the days where my() seemed so foreign as I put on Perl5 (and it took me a bit to really grok my vs. local [and we have var vs. let now]). There are so many times where I dislike change, but then in time the changes become habit and I wonder how I lived on the other side.

It is time to re-tool.

I am finding that I really enjoy CoffeeScript. I find it fun to use. I am happy when using it. If core JavaScript can give me much of that, I will be very happy indeed.

I may disagree with some of the TC39 decisions, but I just hope that they make a big push to do bold things at this time. The time is now, and it is great to see signs of hope:

Good news everyone! typeof null == ‘null’ might actually happen.

Dec 02

Native apps are always better than Web apps; Psst, the new way has an escape chute

HTML, JavaScript, Mobile, Open Web, Tech, UI / UX, iPhone 3 Comments »

When we talk about the mobile Web being a good candidate to be a unifying platform for mobile and beyond, we often get nay-sayers telling us that there is no chance of this happening.

Their claims often chanted include:

  • Cross platform never works (case in point: Swing)
  • You can’t create a great experience without going native (and Apple raised the bar on the experience!)

There is some validity to some of this, but I also wanted to discuss the other side too.

Cross Platform Did Work

Swing gets bashed because a) it didn’t take off, and b) people always saw Swing apps as ugly and great examples of the uncanny valley. That team worked tirelessly for many years to try to get the look and feels to be as exacting to their hosts as possible. A pixel off here and there…. and it felt wrong.

It turns out that this probably wasn’t the right approach, and either a) Use SWT to use the real OS components or b) create a great looking l&f that is different to any one host, but natural and fantastic to use. Ben, Jasper Potts, and others fought for such a look and feel in Nimbus but a lot of time had gone by.

We have all seen many platforms on top of hosts that don’t feel right and don’t look good. That doesn’t mean that cross platform can’t work. Flash is an example that is very much cross platform and that community very much went the “every app will have its own UI”…. probably TOO far in the other direction ;)

In fact, the Web itself is a fantastic cross platform success. We have argued that if it wasn’t for the massive Web revolution, would non-Microsoft vendors (read: Mac OS X) be in the situation there are now? Or would they have followed in the wake of Atari, Amiga and BeOS? When the Web happened, suddenly the interesting actions that people wanted to do on a computer were dominated by the global scale of the Web (Google, Amazon, Yahoo!, eBay, etc). The Microsoft Office lock-in was gone (aside: it also DID help a lot that Microsoft gave Apple money, got Office over there, and solutions like VMWare enabled those few Windows apps that you still wanted to come with you).

The Web was a great cross platform success, even though its rich capabilities in the areas of graphics were laughable…. as I mentioned in an earlier post:

Apple - old and new

When you look back at many of the earlier designs of the top website brands, they are comical by todays standards. However, at this same time, technology such as WPF was being touted on the desktop. Why would people visit Web sites when they could experience amazing native Windows and Macintosh experiences?

So, I don’t think you can discount the Web on the merits of “cross platform can’t win” as it already did win once, and at a time when the capability gap was much wider than we now have with HTML5.

Compare this native app to their Web site!

delta-casestudy1

I teased about the Delta mobile Web application before. If you compare their iPhone application to what you get if you go through a mobile browser, the difference is huge.

But, is the reason they are so different due to capability? I think not. I think the reason is much more about structure, legacy, politics, and history reasons.

I remember seeing an early viewing of an Adobe AIR eBay client. The thing was so rich, so much better than the awful eBay site in almost every way. It made you want to cry looking at the website afterwards. Why or why would eBay have this fantastic client and not spend time on the website where all their customers were! It wasn’t that they were baffoons, it was because they had no legacy in this new world!

The designers had free rein with a blank sheet of paper. They had core concepts and some design language, but total creative freedom. Compare that to the website. If they changed the color one hex value users would go nuts! Every time Facebook changes their site there is a massive campaign to change it back for the first 2 weeks.

They also didn’t have to run the gauntlet of the massive codebase that had been built over years to make any of these changes. And the QA. Ugh.

In fact, an entirely new team could be formed to do this work.

This is exactly what I am seeing in mobile. In many companies, if there is a mobile group, they are just that…. a very separate group. In a non-mobile-thinking company they are like the old “Mac” group in a Windows heavy shop that hangs in the corner and is very different.

Other companies are still getting into the world of mobile and realizing that usage patterns are going in that direction. They are bringing in consultants to help out. They are forming new crack teams to take on the challenge. They are realizing that they need to re-think the entire experience, and hopefully realizing that they need to create software as-a-whole in a very different manner.

The bar on the quality of experiences on some of the mobile platforms is very high indeed (and very low on others!) which has the (great) effect of pushing the bar forward.

Will this leave the Web versions behind? Maybe in the short term. Kinda like how the old Twitter website was simple compared to Tweetie and other clients, but #newtwitter is much richer and borrows some of the concepts where they make sense.

I am definitely seeing people swing back to their web experiences. As multiple platforms foster in touch and cross device, they are starting to feel the increasing tax of building totally different applications across the fragmentation, and then trying to keep them in sync once the 1.0 is complete. Outsourcing the 1.0 is one thing, but the syncing part is hard.

Back to Delta. You will notice that the screenshots on the web side get increasingly poor as you go deeper into the experience. Contrast that with the iPhone version above that is always at a high quality. It is time for them to go back to the web side and sync up.

In fact, just before a recent talk, we coded up some of the simple transitions and feel just so show how easy it is to get some of this stuff working via the mobile Web. You can see the simple example here.

In our Palm Developer Day keynote we shared some of the high level pieces on how to put this all together, the major piece being that you have to really re-think the way that you architect your applications (think: Gmail not server generated HTML, Backbone.js, and more).

Here are some of the slides:

delta-casestudy2

delta-casestudy3

delta-casestudy4

delta-casestudy5

aside: Dave Balmer goes into some depth in his Rockstar apps with HTML5 talks.

Of course, it isn’t all hunky dory. There are still edge cases on getting things performing just right using the Web on the various devices. You have to think “cross platform” again. It may have been nice to ignore that and hack on a native application for awhile. But, would you rather be porting between proprietary SDKs and languages all day long? Or re-use as much of your code as possible.

And, if for some valid reason you really DO need a bit of native for something, you can break out of jail and do just that. The escape chute is waiting for you.

We have a long way to go on giving developers better access to native capabilities and tools to make building the next generation of apps more of a breeze, but it is doable right now (another aside: webOS kinda proves that right now as the native apps ARE Web apps!)

I will finish with the interesting take from Venture Beat the other day on how
the iPhone app is the Flash homepage of 2010. They say:

In the late 1990s, it was common for companies to spend $50,000 to $150,000 for a Flash homepage that looked like a beautiful brochure. However, they soon learned that Flash was cumbersome, slow to load, expensive to build, and hard to update, and moved on to HTML. Now only specialized, high-end sites are Flash only.
The exact same thing has replayed itself on the iPhone. Companies have paid $50,000, $100,000, and more for an iPhone app. Now they have to keep the iPhone app in sync with their regular web site, and have to add additional native apps, each at a high price point, due to the hypergrowth of Android and newly viable platforms like Windows Phone 7

Oct 21

“What is just as important is what isn’t in the system”; Apple, Java, and the Mac App Store

Apple, JavaScript, Tech 2 Comments »

opticaldrive

As always, I am an incredibly torn individual after yet another Stevenote and recent Apple news. Apple is incredibly proud not just about what they manage to put into their products, but what they manage to keep out of them. Steve mentioned this again as he discussed the innards of the new Macbook Air products. The other example that comes to mind is their remote, which is laughable when placed next to TV remotes.

We have been opining for a long time about the obvious merge of iOS and OS X. For awhile people would argue about which side would win out, where “win out” means having the most DNA in the future. With Lion, we got just a glimpse on the next round of evolution. The first iOS DNA to get in is that of the app store (pre-Lion even), some look and feel (did you see the toolbar icons on the top of the Mac App Store app?), and the developer features around auto-save, resume where you left off, etc. Having OSX and iOS merge makes total sense to me. As much as I like the Mac, it is a workstation operating system. It was only when I gave my Mum an iPad that I felt like she felt safe and not scared of her computing environment. When I put on a certain consumer hat, I am so looking forward to the Mac App Store. Finally an install and discovery process that makes sense for my Mum. The Mac has arguably the easiest system, but even with DMG’s the process goes wrong every time:

“Wait, you have to double click on the DMG which will mount a drive. No…. don’t launch the app from within there you need to drag it out. No…. don’t drag it to the desktop, you have to put it in the Applications folder”

You can certainly argue that the controlled experience that we are about to get on the Mac will be good for consumers in a large number of ways. Apple is getting ~20% market share at this point, so they may be able to head the virus war at the pass by controlling the apps. And we can see what they have in mind with this control by looking at the review guidelines for the store Here are some of the functional guidelines:

  • Apps that crash, exhibit bugs or do not perform as advertised by the developer will be rejected, as will be apps that are “beta”, “demo”, “trial”, or “test” versions. Apps that use non-public APIs or include undocumented or hidden features inconsistent with the description of the app will be rejected.
  • Apps that duplicate apps already in the App Store may be rejected, particularly if there are many of them. Apps that are not very useful or do not provide any lasting entertainment value may be rejected. Apps that are primarily marketing materials or advertisements will be rejected. Apps that are intended to provide trick or fake functionality that are not clearly marked as such will be rejected.
  • Apps that encourage excessive consumption of alcohol or illegal substances, or encourage minors to consume alcohol or smoke cigarettes, will be rejected. Apps that provide incorrect diagnostic or other inaccurate device data will be rejected. Developers ’spamming’ the App Store with many versions of similar apps will be removed from the Mac Developer Program.
  • Apps must be packaged and submitted using Apple’s packaging technologies included in Xcode – no third party installers allowed. Apps must be self-contained, single application installation bundles, and cannot install code or resources in shared locations. Apps that download or install additional code or resources to add functionality or change their primary purpose will be rejected.
  • Apps that download other standalone apps will be rejected. Apps that install kexts (kernel extensions) will be rejected. Apps that require license keys or implement their own copy protection will be rejected. Apps that present a license screen at launch will be rejected. Apps may not use update mechanisms outside of the App Store.
  • Apps must contain all language support in a single app bundle (single binary multiple language). Apps that spawn processes that continue to run after a user has quit the app without user consent will be rejected. Apps that use deprecated or optionally installed technologies (e.g., Java, [PowerPC code requiring] Rosetta) will be rejected.
  • Apps that do not run on the currently shipping OS will be rejected. Apps that are set to auto-launch or to have other code automatically run at startup or login without user consent will be rejected. Apps that request escalation to root privileges or use setuid attributes will be rejected.
  • Apps that add their icons to the Dock or leave short cuts on the user desktop will be rejected. Apps that do not use the appropriate Mac OS X APIs for modifying user data stored by other apps (e.g bookmarks, Address Book or Calendar entries) will be rejected. Apps that do not comply with the Mac OS X File System documentation will be rejected.

Wow, if we are both writing an application that does “the same thing” right now and I get it in the store before you, there is a chance yours could be blocked? I know that they are probably putting this in place to stop a million fart apps, but wow!

No way to handle beta apps and the like? Most of the apps that I run are actually beta (Chrome dev channel, Evernote beta, etc). At this point I would expect you to say “No one is forcing you to use the Mac App Store! You can buy and install apps just as you do now. Nothing has been taken away.” Absolutely, but it isn’t a huge leap to a see a future where this isn’t the case, and even in the meantime, it will be a pain to manage some apps via the store, and some outside of that process. It won’t be a great experience.

There is another way that the policies poke me. If we think back to when the iPhone came out with app support, they were actually more open than many of the alternatives. It was hell getting your apps provisioned on many of the platforms and the carriers had control. There is also a feeling of “hey, this is my phone, I really need someone testing things at my back as I can’t have my phone compromised in any way.” But on the desktop, even though these “devices” are all merging, it feels different. Feeling like the control is being taken from me feels weird. Do you feel that too?

alexjvm

Then we have Java. I actually wanted Sun to take over the OSX version of Java awhile ago, so it makes sense that the Apple team has deprecated its support. The Mac team was tiny and thus it wasn’t able to get much love, even though the engineers (we met them) were awesome. Now Oracle can hopefully step up and give us something great. This isn’t a great solution if you ship Swing apps (as my Mum won’t have Java installed, who knows if they will get anything that looks native etc), but fine if you are a Java developer who wants to develop on a Mac. I do wonder if any developers will reconsider Linux or even Windows as an alternative, and I am also thinking about what the Enterprise will think of this. For Apple, they have got rid of a support burden which didn’t bring them any great apps that they care about, and there is less of an attack surface area. Again, taking things out is good for Apple.

The much bigger news for Java fans is the fact that Java developers won’t be able to put their wares into the Mac App Store.

This may bolster the Web. Will the destiny pan out where it can be the unifying cross platform solution? For now, you can hopefully even write Cocoa apps using JavaScript, and of course the full Web stack is available. But what about the flip side?

beltznersafari

I know. Those Mozilla hippies over-reacting again right. This will never happen. Apple loves the Web. How much do they love the Web as they need it (a) because uses want it, b) because it gives them a foil to the restrictions “look, we support the standard Web!”) and is there a chance we will be misaligned in the future? They may not cut Safari off at the knees, but what about a softer approach of not investing in WebKit as much (thanks for open source here!) and not shipping great versions.

If you look forward a few years and see that on the App Store they are bringing in 30% of revenue from their native environment, suddenly successful Web apps are losing them direct money. Hmm.

I think it is natural and smart for us to think about what is happening in the industry, and it isn’t fair to be called out as “over reacting” when someone brings up a “what if?”. We need to think critically. History has shown us time after time that alignments change.

That being said, Apple is building terrific product, and they offer real value to consumers (versus pure business lock in on crappy product, which we have seen in the past!). They have made computing so much better for so many people. They are providing opportunity for developers. They push the entire industry which is in such an exciting time. I can’t wait to see what happens next.

Where do we go from here?

apt-buy

Sep 28

Chrome Speak To Site; Give any input the power to listen to you

JavaScript, Open Source, Tech, Web Browsing with tags: , , 3 Comments »

Paul Irish gave a fantastic updated State of HTML5 talk at JSConf.EU. It is packed full of demos, including sharks with freaking lazer beams!

At one point he showed off the WebKit support for <input speech> implementation that allows you to talk into an input area. You click on the microphone, speak in, and it will get translated for you with the results. I am not sure if you can tweak how the translation is done (choose a Nuance vs. Google vs. …. solution for example), but it definitely works well out of the box.

speak-to-site

I was surprised to see this already landed in my developer-channel Chrome, so I was incented to do something with it on the plane trip back from Berlin to New York City. Something simple would be to give the user the ability to enable speech on any input. I whipped up a Chrome extension using the context menu API, but was quickly surprised to see that there isn’t support in the API to get the DOM node that you are working on. Huh. Kinda crazy in fact.

Then the whizzkid antimatter came to the rescue with his cheeky little hack around the system. Here is how it plays out in the world of this extension:

The background page

First we enable the context menu on any “editable” element (vs. anywhere on the page, on any text, etc), and when clicked we fire off an event to the content script in the given tab:

<script>
chrome.contextMenus.create({
    title: "Turn on speech input",
    contexts: ["editable"],
    onclick: function(info, tab) {
        chrome.tabs.sendRequest(tab.id, 'letmespeak')
    }
});
</script>

Catching in a content script

A content script then does two things:

  • Listens for mousedown events to keep resetting the last element in focus
  • Catches the event, and turns on the speech attribute on the target DOM node
var last_target = null;
document.addEventListener('mousedown', function(event) {
    last_target = event.target;
}, true);
 
chrome.extension.onRequest.addListener(function(event) {
    last_target.setAttribute("speech", "on");
    last_target = null;
})

Wire-y wire-y

Of course, it all gets wired up in the manifest:

{
    "name": "Turn on Speech Input",
    "description": "Turns on the speech attribute, allows you to speak into an input",
    "version": "0.1",
    "permissions": ["contextMenus"],
    "minimum_chrome_version": "6",
    "background_page": "background.html",
    "content_scripts": [{
        "matches": ["<all_urls>"],
        "js": ["input-speech.js"]
    }]
}

This trivial extension is of course on GitHub (I want git-achivements after all! :).

A couple of things trouble me though:

  • The microphone icon should sit on the right of the input, however when dynamically tweaked like this it shows up on the left by mistake [BUG]
  • I have also played with extensions such as Google Scribe. Adding icons like this doesn’t scale. Having them show up all the time gets in my way. I think I want one ability to popup special powers like scribe completion, or speech-to-text, without it getting in my way
  • When services are built into standard elements like this, it feels like I want to have the ability to tweak how they work (with great defaults of course, as 99.9999% of the time they won’t be changed.

You?

Sep 26

Promote JS; Give newbies a chance :)

JavaScript, Tech No Comments »

javascript on search

Do a search for JavaScript and you find a painful set of returns. The worst offender is having Java results show up. Ouch. (Remember: Java is to JavaScript as Ham is to Hamster!).

Compare to a search for Java, or C#, or Ruby, (or ….).

Ouch. We need better. To begin with the pirates of JSConf (lead by the awesome Mr. Chris Williams!) have started a grass roots Operation SEO at Promote JS. Go there, and help the cause by doing embeds like the following:

JavaScript JS Documentation: JS String replace, JavaScript String replace, JS String .replace, JavaScript String .replace

If we can do half of the work to promote this as we have with the awesome VaporJS library, then we should be in a better place.

Step 2: Come up with a fantastic landing area for JavaScript.

Sep 11

CommonJS: Bridging client and server, and why JavaScript desperately needs first class modules

JavaScript, Tech 4 Comments »

millenium bridge

(function(require, exports) {
  "use strict";
  // ...
  exports.x = 21;
}).apply({}, typeof require === 'function' ? [require, exports] :
               [function(g){return function(id){return g[id];};}(this._modules = this._modules || {}),
                this._modules['example/foo'] = {}]);

Ouch. This is one of many variants of boilerplate hacks that folks are using to get CommonJS modules playing nicely with browsers. The CommonJS list has been sparked by the question of client vs. server, and how to deal with the two worlds.

First, “Mark Miller has posted a recommendation on the TC39 wiki for CommonJS module boilerplate that permits modules to be crafted for use as <script>”.

And, then we have Kris Zyp’s proposal for an asynchronous module definition “based on the ideas from Transport/C and recent changes discussed.”

There seem to by two high order bits:

What is the focus of CommonJS?

The project started as “ServerJS”, and many server side JS folks started discussions. However, then other browser JS lib folk got into the mix. Folks who deeply care about module systems for the client as well as the server.

There are varying degrees of interop here. On the one hand folks want to be able to have the work that “makes Foo a module” work in both contexts. But further down we run into issues like: how does legacy code work? Do you have to wrap it? How? And finally, the browser needs to be able to load code asynchronously whereas the server doesn’t have the same issue.

Node is taking off like wild fire. Should Ryan be stopping to think about the browser? Does he really care? Or is he more focused on making a great event driven server environment that uses JavaScript?

What common libraries should we be creating as part of the “SDK” of JavaScript so to speak?

How do we hack on support :/

When we get into the “how” it gets messy quick. Messy can be hand-waved away if you assume that everyone will be using build tools and the like, but a ground swell of comments have been about the developer ergonomics of working on projects. How is it to debug and write applications? Do you get the basics: correct line numbers, no need to run builds all the time, etc? And then there is the performance aspect of the final production code.

All of this has just shown me how desperately we need a first class concept of a module beyond the client-esque “script” and function wrappers. Could you imagine showing the apply() code from above to a Java programmer? “Erm, you can’t just import?”

ES4 tried to give us programming units, packages, and namespaces. How about ES.next giving us one simple system to get us out of this CommonJS mess?

Aug 31

Node is our turtle shell; Node.js now powers services on webOS

JavaScript, Mobile, Open Source, Palm, Tech, webOS with tags: 3 Comments »

ryannode

At our last Palm Developer Day, Ben and I discussed future APIs for webOS including “JavaScript services” as a way to write code that runs on the other side of the device service bus using JavaScript.

If you think about it, node delivers a services platform for the cloud, so is there a way that we could work together? We got together with Ryan Dahl of Node to try this out, and it turns out that node works fantastically well on a mobile device! Major kudos should go to the V8 team for creating a great VM and to Ryan for writing efficient code that scaled down from the cloud to the device.

Today we announce that node is part of webOS 2.0:

The popular Node.js runtime environment is built into webOS 2.0, which means that you can now develop not just webOS apps but also services in JavaScript. The active Node ecosystem is on hand to provide community support and a rapidly growing library of modules that you can use in your webOS services.

Besides powering the new Synergy APIs, JavaScript services strengthen webOS’s support for background processing and add new capabilities—like low-level networking, file system access, and binary data processing—to the web technology stack.

I am really excited about this move for us. The node community is top class. I get to see this time and time again, most recently over the weekend and this week as I judge the node knockout. There is magic in the air with Node. It feels like the Rails days. I remember being so happy to jump to Rails and get away from the heavy world of Enterprise Java. It was a breath of fresh air to not have to argue with folks about every piece of the stack. “What about JSF with HiveMind and Commons-Logging and ….” Argh! Too. Much. Choice. And, a logging abstraction above Log4J was hilarious :)

Node is low level, yet simple. It is more like Sinatra than Rails. The event-based opinions keep you in good stead, and with cloud solutions such as Heroku and no.de you have great deployment stories, unlike Rails back in the day.

If you check out the modules that are growing daily, and the fun real-time hacks from the knockout you will get a good feel for node.

It feels great to have webOS as the first mobile device that embeds node. With db8 we offer a JSON store than can sync to the cloud (e.g. sync with CouchDB). This stack is starting to look pretty great.

Aug 21

JavaScript! The Doctor Is In.

Bespin, JavaScript, Mozila, Open Source, Tech No Comments »

thedoctors

Dimitris Vardoulakis has created a Doctor. A Doctor for JavaScript that does static analysis on your code to tease out the type information and more.

This is fantastic work, and is something that we were dreaming of when we first planned Bespin. What if the cloud was constantly analyzing your code and returning type metadata back to the clients that were accessing it? That metadata can be used for tasks such as code completion and documentation.

Give it a try to see what comes out the other end. The samples show you a lot, such as polymorphism:

function id(x) { return x;}
id(42);
id('hello, doctor!');
 
// returns
id : function(<number | string>)<number | string>

and prototypes:

function Rectangle(w, h) {
    this.w = w;
    this.h = h;
}
Rectangle.prototype.area = function() {
    return this.w * this.h;
};
var a = (new Rectangle(2, 3)).area();
 
// returns
Rectangle : function(number, number) → any
area : function() → number

and exceptions:

function findLargest(a) {
    if (a.length === 0) throw new Error('empty array');
    var max = a[0];
    for (var i = 1, l = a.length; i < l; i++)
        if (a[i] > max)
            max = a[i];
    return max;
}
function foo() {
    var a = [1,2,3];
    try {
        return findLargest(a);
    } catch (e) {
        return e.message;
    }
}
foo();
 
// returns
findLargest : function(Array[number]) → number
foo : function()<number | string>

and callbacks:

function call(f, x) { return f(x); }
function add1(n) { return n + 1; }
function truncate(s) { return s.substring(0, s.length - 1); }
var n = call(add1, 41);
var s = call(truncate, 'abcd');
 
// returns
call : function(<function(number) → number | function(string) → string>, <number | string>)<number | string>
add1 : function(number) → number
truncate : function(string) → string

Mike Shaver talked about the great work that is coming in JS land right now for Moz…. and it is showing. Can’t wait to see both Firefox and Bespin gain from this all!

Jul 29

Capability based JavaScript loading; JS libraries catch up to GWT

Ajax, JavaScript, Tech with tags: 6 Comments »

ballandchain

Web developers have to walk around dragging a ball and chain. It is fantastic that we have a ridiculous install base (browsers, the Web runtimes) and a dynamic language in JavaScript.

The ball and chain though is the fact that we have to care so much about the payload of the application that we write. Less code means less bytes to download, and less for the JS runtime to load up.

This has bad consequences:

  • You are tempted to write hard to understand code
  • You have to balance functionality and code size much more than other environments
  • You end up getting tricky and come up with ways to dynamically load modules on demand
  • All of this time is time not spent on the app logic.

When you run into a problem like this in computer science what do you do? Build an abstraction!

GWT has done a great job here. It’s very nature requires a compilation step, and once you have to deal with that step…. you can do a lot at build time to change the above dynamics.

For example:

  • You can write nice explicit source code, and trust that the compiler will output optimized JS (which can look as ugly as sin for all anyone cares)
  • Your application can get faster with a new release of GWT, as the compiler gets better
  • A lot of advanced techniques such as code splitting, and deferred binding can be applied to allow logic to apply at build time as well as runtime.

Ignoring GWT, when you write a pure JS application for the Web, you are writing a cross platform application. Unlike clean portable C, you don’t have that compilation step to do clean up work for you on each platform, so you end up with a lot of runtime conditional logic.

You try to do object detection rather than user agent conditional, but still, you end up both downloading the code necessary to run in all environments, and you have the overhead of loading and executing that code.

Chances are you are smart and don’t do if() checks all the time, but maybe do so once when loading up. For large chunks of big differences, maybe you do something like:

var Foo = (sometest) ? function() {
    // do it like this
} : function() {
    // do it like that
};

If you take a look at some parts of popular JavaScript frameworks, you see that they are abstractions or fixes for various browsers. As browsers have stepped up to the plate recently, they have fixed a lot, and suddenly you take a step back. A lot of frameworks have a chunk of code to give us the ability to do smart things with CSS querying. Modern browsers support querySelectorAll (even with some bugs) and getElementsByClassName so a lot of the code is un-needed…. unless you care about the old browsers.

We shouldn’t have to download all of that cruft on the other side of the if() statement when we don’t use it!

The GWT compiler can output versions of your application targeted to a given browser. Only the fastest, minimal code, will get sent down. Deferred binding goes far beyond just browser type (can deal w/ locales and much more) too.

GWT isn’t the only horse in this race though.

Alex Russell started to sprinkle in some directives to Dojo that would enable you to do a build that is WebKit targeted. A major use case for all of this is making sure that you are sending down lean code in the mobile space. It can matter everywhere, but when you are dealing with grown up walkie talkies…. you want to really optimize.

And this brings us to YUI. I was really excited to see some of the features in the YUI 3.2.0 preview release. Great stuff for touch/gesture support, but what stood out for me was “YUI’s intrinsic Loader now supports capability-based loading”. A-ha!

I poked around the source to see how it was used. Here is one fake example that shows how it works. When you boot up YUI you can add in “conditions” which are in charge of working out whether to load something. You can currently tie on to user agent, or write a test function:

YUI({
    modules: {
        lib2: {
            requires: ['yui'],
            fullpath: 'js/lib2.js',
            condition: {
                trigger: 'node-base',
                ua: 'gecko'
            }
        },
 
        lib3: {
            requires: ['yui'],
            fullpath: 'js/lib3.js',
            condition: {
                trigger: 'event-base',
                test: function(Y, req) {
                    return Y.UA.gecko;
                }
            }
        }
    }
 
}).use('node', function (Y) { .... });

The YUI team uses this themselves to only load certain ugly DOM stuff for IE6 when needed:

"dom-style-ie": {
    "condition": {
        "trigger": "dom-style", 
        "ua": "ie"
    }, 
    "requires": [
        "dom-style"
    ]
},
 
YUI.add('dom-style-ie', function(Y) {
    // ....
});

This makes a ton of sense, especially for the libraries themselves to do this work. They are the ones that do the heavy lifting of cross browser ugliness, all to allow us to write to an API that works.

Beyond that, we can then ourselves split out code if it becomes a performance issue.

Of course, the value of the test() function is that you can do capability based testing (not just user agent testing…. hence the name!). This means that you can do a test say for Canvas support (as Zach mentions in the comments) document.createElement(’canvas’).getContext, and load up excanvas or another shim library if it doesn’t exist.

Using modernizr and ilk, we could build out “plugins” for YUI that auto load based on common capabilities. You can imagine running a YUI build, having it detect that you are using a capability, and then automatically load up a plugin that has the condition all loaded up. What a great user experience as a developer!

Maybe it makes sense to come up with a common pattern and conventions for dealing with this issue. How do you name your CSS/JS? Do we setup server side hooks so we don’t even need loaders necessarily?

I can certainly see a day where you may be asking the Google Ajax Library service for jquery.js, but it is returning jquery.ie.js to you.