If JavaScript is so cool, then why does my nephew say it’s not a real programming langauge?

Posted: August 22nd, 2007 | Author: Joey | Filed under: Coding | 3 Comments »

Every now and then I am asked which is my favorite programming language. To me that is like choosing which is my favorite kid. Am I going out to play Frisbee, or trying to get them to flip off the car next to us? It all depends, man. But I must say, I like JavaScript.

If you are like most people, you just gave me that – “Did you just fart?” – look. Yes, JavaScript. Most of the time, my questioner doesn’t know how to respond, and I imagine they are having flashbacks of rainbow-colored trailing cursors. I figure they think I am joking, so I offer a couple reasons why I like it. I try to explain that JavaScript just does what I want it to do. I think of the best way to explain 1st class functions and closures, but I give up before I start, “I’m just kidding. I like Ruby.”

“Yeah,” they nod, “my cousin has his certification for Ruby with Rails, and he says that in ten years anybody will be able to write web software by just talking to their Mac.”

“Have I introduced you to my two year old yet? He’s good with his hands…”

From my experience, anyone that understands any concepts of functional programming generally doesn’t give a rat’s ass which language I prefer. (Ruby is my other favorite language.)

I really wish I could more elegantly explain why I like JavaScript, but the examples I come up with are usually contrived and show no benefit to doing it “that way”. At work last week, I found myself using closures to solve a problem in a way I felt was a clear example of why I like JavaScript. So, I’ll share.

Without wandering too far from the topic, I’ll explain the background of the problem. Often when you are creating an interactive web page, your JavaScript needs to write out HTML. Whether you are updating some status, showing some dialog box or message, or inserting rows into a table, it needs to be done. There are more or less two ways of doing this. Concatenating HTML and variables is ugly, but fast. Creating DOM elements and manipulating the DOM is dreadfully tedious and slow, but clean. Both methods tend to drive me crazy. I personally solve this problem by using Prototype’s Template object. You don’t need to be familiar with it, just know that you can create an object, then call an evaluate method on that object to render a template.

I put my HTML snippets into a global collection, and use them from there. This lets me keep the code at least looking clean. This is where the JavaScript fun comes in. There are a million ways to accomplish this, so I am going to throw out some requirements, just to narrow down the number of ways to do this. I don’t think these are unreasonable.

  1. It must be simple. By simple, I don’t mean easy to understand, just easy to use. I like succinct.
  2. It must be efficient. I only want one Template object that I can reuse, and it must be instantiated when it is first used (lazily).
  3. I must be able to insert debugging statements at will. I don’t want to have to refactor code just to put logging messages.
  4. It must be elegant. This is, of course, purely opinion, but wasn’t that the point of this whole thing?
  5. And one more, I want to be able to reference these snippets, too. You know, a way to pass them around as parameters or something.

In other words, I want to be able to do this:

header.innerHTML = Snippets.welcome({name:'Joey'});

That would replace the token “name” with “Joey” in a template that probably looks like:

new Template('Welcome, #{name}!')

I want welcome to be a function, I don’t want it to be an object that I have to call evaluate on. To me, that violates requirements 1, 3, and 4. If I were writing this in PHP, I would do something along the lines of the following in order to meet all the requirements. (I’ll just use two snippets for the sake of the example, “welcome” and “status”. Usually I’d have many.)

class Snippets {
 
  private static $templates = array();
 
  private static function load ($name, $template) {
    if (!array_key_exists($name, self::$templates)) {
      self::$templates[$name] = new Template($template);
    }
    return self::$templates[$name];
  }
 
  private static function evaluate ($template, $data) {
    // insert debugging statements here
    return $template->evaluate($data);
  }
 
  public static function welcome ($data) {
    $template = self::load('welcome', 'Welcome, #{name}!');
    return self::evaluate($template, $data);
  }
 
  public static function status ($data) {
    $template = self::load('status', 'System is #{status}.');
    return self::evaluate($template, $data);
  }
 
}

That is pretty clean, and can be pretty much translated directly into any other object oriented language. It meets requirements 1, 2, 3, and 4. The load method caches the template objects, and only instantiates them when they are first used. The evaluate method is abstracted out to allow me to put all debugging/logging statements in one location. For some languages, requirement 5 can still be met. For example, with PHP you can “reference” which snippet to use by doing something like:

/**
 * Greet a user by name
 * @param string $name Name of user
 * @param array $template Option snippet to use, defaults to "welcome"
 * @return void Displays output directly
 */
function greetUser ($name, $snippet = array('Snippets', 'welcome')) {
  echo call_user_func($template, array('name'=>$name));
}
greetUser('Joey');

Requirement 5 is met, but requirement 4 is now broken. It’s not pretty by any definition. Less dynamic languages, like Java, will undoubtedly be even uglier, resorting to reflection. The cleaner way in Java would be to make those functions be object references instead of functions, require them to implement some interface, and have the user call the evaluate method. To me, that is the opposite of requirement 1: it is easy to understand, but annoying to use. This explains it much better, and even if you disagree, you should read it.

The JavaScript code will basically be the same, except that I will be able to reference the functions directly.

var Snippet = {
  create : function (html) {
    var template = null;
    return function (data) {
      if (!template) {
        template = new Template(html);
      }
      // insert debugging/logging statements here
      return template.evaluate(data);
    };
  }
};
 
var Snippets = {
  welcome : Snippet.create('Welcome, #{name}!'),
  status : Snippet.create('System is #{status}.')
};

That code satisfies all the requirements, and it does so beautifully. Not only is Snippets.welcome a method that I can call and pass the data to, but I can pass it around as a parameter, or assign it to a variable. Imagine adding another 20 snippets to both the PHP and JavaScript code above, and I think the effect is even more dramatic.

As I said in the beginning, JavaScript just does what I want it to do. No, I didn’t fart.


3 Comments on “If JavaScript is so cool, then why does my nephew say it’s not a real programming langauge?”

  1. 1 Hayden said at 11:11 pm on August 23rd, 2007:

    You had better not let our kids flip off other drivers! Mumbo jumbo, blah blah blah.

  2. 2 Kristy said at 9:29 am on August 24th, 2007:

    I like your new page!

  3. 3 Joey said at 10:26 am on August 24th, 2007:

    Why, thank you.


Don't be shy...