Running with Code Like with scissors, only more dangerous

3Oct/131

I’m going to be on Channel9

Posted by Rob Paveza

I went and hung out with Larry Larson and Andrew Richards from the Channel9 show Defrag Tools today to record an episode! It was way cool, even though I got a little lost heading to the building which was literally right across the street from my own. (In my defense, I was up really early and I thought the building was further down the street).

All said and done, I got a cool Channel9 dude and I got to take a picture in the studio!

I'm @ Channel9 on 10/14/2013

I'm @ Channel9 on 10/14/2013

Be sure to check out Defrag Tools on 10/14 to see it, because I'll be talking about Just My Code in Visual Studio. If you haven't seen the blog I linked to last time, it's definitely worthwhile, but at the very least, you ought to watch the video, because it's AWESOME!

Update: It's live! Check it out!

19Sep/130

Just My Code for JavaScript

Posted by Rob Paveza

Super-excited that we FINALLY get to talk about a new feature that went out in Visual Studio 2013 RC last week. Check out the details in Andrew Hall's blog post on MSDN.

15Mar/130

A Loop for WinJS Promises

Posted by Rob Paveza

I had a co-worker ping me from an internal mailing list recently because he was having trouble reading from a network stream. I dug this out of mothballs from Win8 Consumer Preview:

WinJS.Class.define('Game', function() { /* constructor */ },
    { /* instance prototype */ },
    { /* static members */ 
        LoopWhileTrue: function (context, testCallback, actionReturningPromise, state) {
            /// <summary>Loops an action (that returns a promise) until another callback (that returns a Boolean) indicates that it should no longer continue.</summary>
            return new WinJS.Promise(function (success, error) {
                function evalActContinueLoop() {
                    if (testCallback.call(context, state)) {
                        var innerPromise = actionReturningPromise.call(context, state);
                        innerPromise.then(evalActContinueLoop, function (e) {
                            error(e);
                        });
                    }
                    else {
                        success(state);
                    }
               }
                evalActContinueLoop();
            });
        }
    });

This code was used for managing game state in a card-playing game app that I never finished. Usage might look like this:

var gameplay = Game.LoopWhileTrue(game, game.isGameInPlay, game.playHand, game.state);

gameplay’ then became a Promise that:

  • is fulfilled when the entire game completes (all hands have been played or a terminal score is achieved, based on the value returned by calling game.isGameInPlay(state)).
  • results in an error-fulfillment state if an internal call results in an error.
  • iteratively calls game.playHand(game.state), passing in ‘game’ as the this pointer (important in JS) until it is fulfilled (see 1st bullet).
  • if game.playHand completes synchronously, this method could cause a stack overflow. This can be broken with periodic use of setImmediate.

This method can conveniently be used to emulate a for-loop or a while-loop. It doesn't quite as well emulate a do-while-loop because it checks the terminal condition, but you could write a simple adapter method to always return true for the first call to the method.

1Oct/121

Announcing TypeScript

Posted by Rob Paveza

I'm very excited to announce that my team at Microsoft has released TypeScript, a new language for application-scale JavaScript development. TypeScript cross-compiles to JavaScript, and is fully compatible with existing JavaScript code. That means that your existing JavaScript can go directly into TypeScript, unchanged, and is immediately usable.

You can start by adding type annotations to your JavaScript, which allows your tools to give you compilation warnings and errors when you're doing something that appears to be incorrect.

The next step beyond annotating your code is that TypeScript exposes classes and modules. Anders discusses in his talk (video on the TypeScript homepage) that the design of TypeScript classes and modules was heavily influenced by the current design of ES6 classes and modules, so it should continue to be familiar as the ECMAScript standard evolves.

Lambdas (thick arrow syntax) preserve a reference to 'this', helping to address one of the most common errors in JavaScript programming. Class extensibility works like you expect, including super-constructor logic, which is another one of those areas of JavaScript programming that is hard to just get right.

Oh - and did I mention that it's completely open-source and available for Node?

Check it out! And keep an eye on my blog - I'll be talking about it as things evolve (and once I add TypeScript support to SyntaxHighlighter Evolved).

And one other editorial note - I recently used TypeScript to port a C#-based low-level graphics class I wrote that decodes a raw image stream into pixels into JavaScript + Canvas. It went off beautifully. Check it out - I think you'll be impressed how easy it is to work with! And in the meantime, check out Soma's blog and the Channel 9 video.

16Feb/120

Bridging the gap between Jurassic and the DLR, Part Two

Posted by Rob Paveza

Part Two: A More Complete Object Model

Once I started implementing the rest of the object model, things started coming together very well.

Let's take a look at the rest of the ObjectInstance implementation:

        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            return TryCallMemberFunction(out result, binder.Name, args);
        }

        public override bool TryConvert(ConvertBinder binder, out object result)
        {
            if (binder.ReturnType == typeof(string))
            {
                result = this.ToString();
                return true;
            }
            else
            {
                try
                {
                    result = Jurassic.TypeConverter.ConvertTo(this.engine, this, binder.ReturnType);
                    return true;
                }
                catch
                {
                    result = null;
                    return false;
                }
            }
        }

        public override bool TryDeleteMember(DeleteMemberBinder binder)
        {
            return Delete(binder.Name, false);
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            this.FastSetProperty(binder.Name, value, PropertyAttributes.FullAccess, true);
            return true;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = GetNamedPropertyValue(binder.Name, this);
            if (object.ReferenceEquals(null, result))
                return false;

            return true;
        }

For FunctionInstance:

        public override bool TryInvoke(System.Dynamic.InvokeBinder binder, object[] args, out object result)
        {
            try
            {
                result = CallLateBound(this, args);
                return true;
            }
            catch
            {
                result = null;
                return false;
            }
        }

For ArrayInstance, things were a little more interesting. JavaScript doesn't support multidimensional arrays (as in C#, where you can access something via someArr[1,5]). However, it's important to consider the type. Fortunately, Jurassic provides that as well, fairly easily.

        public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
        {
            Debug.Assert(indexes != null && indexes.Length > 0);

            result = null;

            if (indexes.Length > 1)
                return false; // multi-dimensional arrays are not supported.

            if (object.ReferenceEquals(null, indexes[0]))
                return false;

            Type indexType = indexes[0].GetType();
            if (indexType.IsEnum)
            {
                indexType = Enum.GetUnderlyingType(indexType);
            }

            if (indexType == typeof(byte) || indexType == typeof(sbyte) || indexType == typeof(short) || indexType == typeof(ushort) || indexType == typeof(int) || indexType == typeof(uint))
            {
                uint index = unchecked((uint)indexes[0]);
                try
                {
                    result = this[index];
                    return true;
                }
                catch
                {
                    result = null;
                    return false;
                }
            }
            else
            {
                string index = indexes[0].ToString();
                try
                {
                    result = this[index];
                    return true;
                }
                catch
                {
                    result = null;
                    return false;
                }
            }
        }

        public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
        {
            Debug.Assert(indexes != null && indexes.Length > 0);

            if (indexes.Length > 1)
                return false; // multi-dimensional arrays are not supported.

            if (object.ReferenceEquals(null, indexes[0]))
                return false;

            Type indexType = indexes[0].GetType();
            if (indexType.IsEnum)
            {
                indexType = Enum.GetUnderlyingType(indexType);
            }

            if (indexType == typeof(byte) || indexType == typeof(sbyte) || indexType == typeof(short) || indexType == typeof(ushort) || indexType == typeof(int) || indexType == typeof(uint))
            {
                uint index = unchecked((uint)indexes[0]);
                try
                {
                    this[index] = value;
                    return true;
                }
                catch
                {
                    return false;
                }
            }
            else
            {
                string index = indexes[0].ToString();
                try
                {
                    this[index] = value;
                    return true;
                }
                catch
                {
                    return false;
                }
            }
        }

        public override bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes)
        {
            Debug.Assert(indexes != null && indexes.Length > 0);

            if (indexes.Length > 1)
                return false; // multi-dimensional arrays are not supported.

            if (object.ReferenceEquals(null, indexes[0]))
                return false;

            Type indexType = indexes[0].GetType();
            if (indexType.IsEnum)
            {
                indexType = Enum.GetUnderlyingType(indexType);
            }

            if (indexType == typeof(byte) || indexType == typeof(sbyte) || indexType == typeof(short) || indexType == typeof(ushort) || indexType == typeof(int) || indexType == typeof(uint))
            {
                uint index = unchecked((uint)indexes[0]);
                return Delete(index, false);
            }
            else
            {
                string index = indexes[0].ToString();
                return Delete(index, false);
            }
        }

I did add one set of precompilation directives so that I could modify ScriptEngine with one little item:

        public 
#if SUPPORT_DYNAMIC
            dynamic
#else
            object 
#endif
            GetGlobalValue(string variableName)
        {
            if (variableName == null)
                throw new ArgumentNullException("variableName");
            return TypeUtilities.NormalizeValue(this.Global.GetPropertyValue(variableName));
        }

With that gem, we're in good shape. I'll update the test program; let's take a good look:

    class Program
    {
        static void Main(string[] args)
        {
            ScriptEngine engine = new ScriptEngine();

            engine.SetGlobalFunction("write", (Action<string>) ((s) => { Console.WriteLine(s); }));
            
            engine.Execute(@"
var a = {
    A: 'A',
    B: 20,
    C: function() { return 'Hello'; }
};

function double(val)
{
    return val * 2;
}

var array = [1, 5, 9, 13, 21];
");
            dynamic obj = engine.Evaluate<ObjectInstance>("a");
            Console.WriteLine(obj.A);
            Console.WriteLine(obj.B);
            Console.WriteLine(obj.C());
            obj.D = "What's that?";

            Console.WriteLine("C#: " + obj.D);

            engine.Execute(@"
write('JavaScript: ' + a.D);
");

            dynamic dbl = engine.GetGlobalValue("double");
            Console.WriteLine(dbl(20));
            Console.WriteLine(dbl.call(null, 20));

            dynamic array = engine.GetGlobalValue("array");
            Console.WriteLine(array[2]);

            Console.ReadLine();
            
        }
    }

Output is happily correct:

A
20
Hello
C#: What's that?
JavaScript: What's that?
40
40
9

Particularly neat about this implementation is that the calls automatically recurse. Note that I use the intrinsic JavaScript call method on the Function instance (of dbl). This implementation covers a whole bunch of typical scenarios and use-cases, and I'm happy to see that it has worked out fairly well thus far.

One item I've found is that there's a TypeLoadException when targeting .NET 4. This has something to do with a new CAS policy in .NET 4. For now, applying this attribute to the test program as well as the library will resolve the issue, though I don't intend for it to be long-term:

[assembly: System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)]

Next time, we'll do some more fit and finish, with precompilation constants and a security review.

14Feb/120

Bridging the gap between Jurassic and the DLR, Part One

Posted by Rob Paveza

Part One: ObjectInstance derives from DynamicObject

A while back I posted that I was joining the Jurassic team; Jurassic is an open-source JavaScript engine for .NET. If you've ever gone through the long search for a JavaScript implementation on .NET (other than JScript.NET, of course), there are a bunch of incomplete implementations, and if you're lucky enough to find the blog about the Microsoft project of JScript running on the DLR (once called Managed JScript), you'll find that it was an implementation that was specifically designed to give design feedback on the DLR itself, and was not planned to be carried forward into production. Personally I think that's too bad, but I'm happy to see a couple of projects (notably, Jurassic and IronJS) that have stepped up to fill the gap.

I had considered implementing IDynamicMetaObjectProvider, but inheriting from DynamicObject seems to be a better design decision all-around. Since all of the other JavaScript objects inherit from ObjectInstance, it's a simple matter of overriding its virtual methods instead of creating a new implementation of DynamicMetaObject for each class in the hierarchy.

I've created a new library project within the solution as well as a simple testing project to advise on the API as well as to step into my DynamicObject overrides. Here are some simple components:

// These are new:
using System.Dynamic;
using System.Diagnostics;

// This is updated
    public class ObjectInstance
        : DynamicObject
#if !SILVERLIGHT
        , System.Runtime.Serialization.IDeserializationCallback
#endif
    {

// The class exists as normal
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = GetNamedPropertyValue(binder.Name, this);
            if (result != null)
                return true;

            return false;
        }

        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            try
            {
                result = CallMemberFunction(binder.Name, args);
                return true;
            }
            catch
            {
                result = null;
                return false;
            }
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            this.AddProperty(binder.Name, value, PropertyAttributes.FullAccess, true);
            return true;
        }

    }

This is the source of the test application. It's very straightforward:

        static void Main(string[] args)
        {
            ScriptEngine engine = new ScriptEngine();

            engine.SetGlobalFunction("write", (Action<string>) ((s) => { Console.WriteLine(s); }));
            
            engine.Execute(@"
var a = {
    A: 'A',
    B: 20,
    C: function() { return 'Hello'; }
};
");
            dynamic obj = engine.Evaluate<ObjectInstance>("a");
            Console.WriteLine(obj.A);
            Console.WriteLine(obj.B);
            Console.WriteLine(obj.C());
            obj.D = "What's that?";

            Console.WriteLine("C#: " + obj.D);

            engine.Execute(@"
write('JavaScript: ' + a.D);
");

            Console.ReadLine();
            
        }

We create a global function 'write' which writes a string to the console. Then we create a global object a with properties A, B, and C. We then use C# to retrieve the value of this object as a dynamic. This is what provides us access to the DynamicObject's overrides intrinsic within C#'s support of the DLR. We then access each property (which each return a dynamic) and, happily because of Jurassic's automatic conversion of primitives to their respective .NET types, when these values are returned as dynamic, they can be automatically converted to their appropriate types for their Console.WriteLine parameter. You can see that we invoke TryGetMember on A and B, TryInvokeMember on C, and TrySetMember and then TryGetMember on D.

OK, it's late, so I'm not going to stick this out anymore right now. I'm not even sure if the previous paragraph was particularly coherent. :-)

There's a lot to update: it doesn't support case-insensitive languages (like Visual Basic), it's not particularly good at error checking, and I haven't dealt with any other components yet. The good news is that it seems like we should be good to go for the rest of the components.

Next time, we'll look at other classes, like ArrayInstance, FunctionInstance, and more.

9Jan/121

Revealing Prototype Pattern: Pros and Cons

Posted by Rob Paveza

A short while ago, I wrote a post generally saying good things about the Revealing Prototype Pattern but mostly focused tearing down the other part that was presented with it, namely the way that variables were declared in a chain separated by the comma operator. This post will discuss some of the pros and cons of using this pattern, and give some examples about when you should or shouldn't use it.

Advantages

As Dan notes in his post, this features a significant improvement over straight prototype assignment (assignment of an object literal to a prototype), in that private visibility is supported. And because you're still assigning an object to the prototype, you are able to take advantage of prototypal inheritance. (Next time: How prototypal inheritance really works and how it can make your head explode).

Except for chaining his variable declarations, I have to admit Dan had me pretty well sold on the Revealing Prototype Pattern. It's very elegant; it provides good protection to its inner variables, and it uses a syntax we've been seeing more and more of ever since jQuery became a popular platform.

Unfortunately, it has some nasty drawbacks.

Disadvantages

To be fair, Dan lists some of the disadvantages about this pattern; however, he doesn't quite list them as such, and I think he was possibly unaware of some of their implications:

There's something interesting that happens with variables though, especially if you plan on creating more than one Calculator object in a page. Looking at the public functions you'll see that the 'this' keyword is used to access the currNumberCtl and eqCtl variables defined in the constructor. This works great since the caller of the public functions will be the Calculator object instance which of course has the two variables defined. However, when one of the public functions calls a private function such as setVal(), the context of 'this' changes and you'll no longer have access to the two variables.

The first time I read through that I glossed over the problems; I didn't quite understand the issue until I wrote some code. So let's do that - we'll implement the Java StringTokenizer class:

function StringTokenizer(srcString, delim)
{
    if (typeof srcString === 'undefined')
        throw new ReferenceError("Parameter 0 'srcString' is required.");
    if (typeof srcString !== 'string')
        srcString = srcString.toString();
    if (typeof delim !== 'string')
        delim = ' ';
    
    if (!(this instanceof StringTokenizer))    // enforce constructor usage
        return new StringTokenizer(srcString, delim);
        
    this.sourceString = srcString;
    this.delimiter = delim;
}
StringTokenizer.prototype = (function()
{
    var that = this;
    
    var _tokens = that.sourceString.split(that.delimiter);
    var _index = 0;
    
    var _countTokens = function() { return _tokens.length; };
    var _hasMoreTokens = function() { return _index < _tokens.length; };
    var _nextToken = function()
    {
        if (!_hasMoreTokens())
            return false;
        
        var next = _tokens[_index];
        _index += 1;
        return next;
    };
    var _reset = function() { _index = 0; };
    
    var resultPrototype = 
    {
        countTokens: _countTokens,
        hasMoreTokens: _hasMoreTokens,
        nextToken: _nextToken,
        reset: _reset
    };
    return resultPrototype;
})();

If you've ever written a jQuery plugin, you'll probably recognize what I did with the prototype assignment function; when writing jQuery plugins, it's common to close over the current instance of the jQuery object by assigning var that = $(this); so that you can write event-handler functions without losing access to the overall context. Unfortunately, what I did in this case is wrong; you may already see why.

var that = this;

In this context, this is a reference to the global object, not to the instance of the object - even though the prototype is being set. This is a generalization of what Dan said. Rewriting it to overcome it results in information leaking:

function StringTokenizer(srcString, delim)
{
    if (typeof srcString === 'undefined')
        throw new ReferenceError("Parameter 0 'srcString' is required.");
    if (typeof srcString !== 'string')
        srcString = srcString.toString();
    if (typeof delim !== 'string')
        delim = ' ';
    
    if (!(this instanceof StringTokenizer))    // enforce constructor usage
        return new StringTokenizer(srcString, delim);
        
    this.sourceString = srcString;
    this.delimiter = delim;
    this.tokens = srcString.split(delim);
    this.index = 0;
}
StringTokenizer.prototype = (function()
{
    var _countTokens = function() { return this.tokens.length; };
    var _hasMoreTokens = function() { return this.index < this.tokens.length; };
    var _nextToken = function()
    {
        if (!this.hasMoreTokens())
            return false;
        
        var next = this.tokens[this.index];
        this.index += 1;
        return next;
    };
    var _reset = function() { this.index = 0; };
    
    var resultPrototype = 
    {
        countTokens: _countTokens,
        hasMoreTokens: _hasMoreTokens,
        nextToken: _nextToken,
        reset: _reset
    };
    return resultPrototype;
})();

The code works correctly; but you can see that we have to make public all of the state variables we'll use in the constructor. (The alternatives are to either initialize the state variables in each function, where they would still be public; or to create an init function, which would still cause the variables to be public AND would require the user to know to call the init function before calling anything else).

Dan also indicated that you needed a workaround for private functions:

There are a few tricks that can be used to deal with this, but to work around the context change I simply pass “this” from the public functions into the private functions.

Personally, I prefer to try to avoid things one might call clever or tricky, because that's code for "so complex you can't understand it". But even in the case where you have a public function, you'll still get an error if you don't reference it via a public function call. This error is nonintuitive and could otherwise make you go on a bug hunt for a long time. Consider this change to the above code:

    var _hasMoreTokens = function() { return this.index < this.tokens.length; };
    var _nextToken = function()
    {
        if (!_hasMoreTokens())   // changed from:   if (!this.hasMoreTokens())
            return false;
        
        var next = this.tokens[this.index];
        this.index += 1;
        return next;
    };

Simply removing the 'this' reference in the caller is enough to cause 'this' to go out-of-scope in the _hasMoreTokens function. This is completely unintuitive behavior for developers who grew up in the classical inheritance model.

Alternatives

I wouldn't want to give you all of these options without giving you an alternative. The alternative I present here is one in which the entire object is populated in the constructor:

"use strict";
function StringTokenizer(srcString, delim)
{
    if (typeof srcString === 'undefined')
        throw new ReferenceError("Parameter 0 'srcString' is required.");
    if (typeof srcString !== 'string')
        srcString = srcString.toString();
    if (typeof delim !== 'string')
        delim = ' ';
    
    if (!(this instanceof StringTokenizer))    // enforce constructor usage
        return new StringTokenizer(srcString, delim);
        
    if (typeof Object.defineProperty !== 'undefined')
    {
        Object.defineProperty(this, 'sourceString', { value: srcString });
        Object.defineProperty(this, 'delimiter', { value: delim });
    }
    else
    {
        this.sourceString = srcString;
        this.delimiter = delim;
    }
    
    var _tokens = this.sourceString.split(this.delimiter);
    var _index = 0;
    
    var _countTokens = function() { return _tokens.length; };
    var _hasMoreTokens = function() { return _index < _tokens.length; };
    var _nextToken = function()
    {
        if (!_hasMoreTokens())
            return false;
        
        var next = _tokens[_index];
        _index += 1;
        return next;
    };
    var _reset = function() { _index = 0; };
    
    if (typeof Object.defineProperty !== 'undefined')
    {
        Object.defineProperty(this, 'countTokens', { value: _countTokens });
        Object.defineProperty(this, 'hasMoreTokens', { value: _hasMoreTokens });
        Object.defineProperty(this, 'nextToken', { value: _nextToken });
        Object.defineProperty(this, 'reset', { value: _reset });
    }
    else
    {
        this.countTokens = _countTokens;
        this.hasMoreTokens = _hasMoreTokens;
        this.nextToken = _nextToken;
        this.reset = _reset;
    }
}

The advantage of a structure like this one is that you always have access to this. (Note that this example is unnecessarily large because I've taken the additional step of protecting the properties with Object.defineProperty where it is supported). You always have access to private variables and you always have access to the state. The unfortunate side effect of this strategy is that it doesn't take advantage of prototypal inheritance (it's not that you can't do it with this strategy - more of that coming in the future) and that the entire private and public states (including functions) are closed-over, so you use more memory. Although, one may ask: is that really such a big deal in THIS sample?

Usage Considerations

The Revealing Prototype Pattern can be a good pattern to follow if you're less concerned with maintaining data integrity and state. You have to be careful with access non-public data and functions with it, but it's pretty elegant; and if you're working on a lot of objects, you have the opportunity to save on some memory usage by delegating the function definitions into the prototype rather than the specific object definition. It falls short, though, when trying to emulate classical data structures and enforce protection mechanisms. As such, it can require complicated or clever tricks to work around its shortcomings, which can ultimately lead to overly-complex or difficult-to-maintain code.

Like most patterns, your mileage may vary.

6Jan/120

Defining Variables in JavaScript

Posted by Rob Paveza

I've lately been reviewing different patterns and practices recently, and after reading his article about the Revealing Prototype Pattern, I wanted to take some time to analyze Dan Wahlin's approach to defining variables. It's hard to believe I found some common ground with Douglas Crockford, but as they say about broken clocks.... [Addendum: apparently, since JSlint says to 'combine with previous var statement,' I don't agree with Crockford.] Anyway, to begin, this post is inspired by Dan Wahlin's presentation of the Revealing Prototype Pattern; I noticed what I thought was a curious way for him to define his private variables, and looking back through his blog posts he discussed it in the original blog post of the series, Techniques, Strategies, and Patterns for Structuring JavaScript Code. For the most part, I like what Dan has to say, but I'm going to have to disagree when it comes to defining variables.

The Proposition

As Dan points out, this is the standard way of defining variables in JavaScript:

var eqCtl;
var currNumberCtl;
var operator;
var operatorSet = false;
var equalsPressed = false;
var lastNumber = null;

He advocates trading that for this:

var eqCtl,
    currNumberCtl,
    operator,
    operatorSet = false,
    equalsPressed = false,
    lastNumber = null;

It saves on 20 keystrokes, and he claims improved readability. Now, I disagree with Crockford's argument that, because JavaScript hoists variables to the top of the function, that you should always declare the variable there. I believe that, whenever possible, you should try to maximize locality of a variable. This is a principle discussed in Steve McConnell's Code Complete; the reasoning behind maximization of locality is that the human brain can only comprehend so much at once. (This is, of course, another argument in favor of many, simple, and small subroutines). By delaying the declaration of a variable until it needs to be used, we are able to better-comprehend the meaning of the variable and how its use affects and relates to the rest of the program. As such, I believe that one of the premises for moving these declarations into a combined var statement - specifically, to reflect the hoisting - is a poor rationale.

Let's carry on.

Similarities to Other Elements

In The Prototype Pattern, Dan demonstrates the use of a JavaScript object literal in assignment to the Calculator prototype, so that any object created using the Calculator constructor would inherit all of those properties:

Calculator.prototype = {
    add: function (x, y) {
        return x + y;
    },
    subtract: function (x, y) {
        return x - y;
    },
    multiply: function (x, y) {
        return x * y;
    },
    // ...
};

The important thing to note here is that we are simply defining an object literal; we are not writing procedural code, and that comma is not an operator! It is an important part of the JavaScript grammar, to be sure, but the comma here does not have the same semantic meaning as the comma we saw before. This subtle difference may lead to coding errors, in which someone who uses comma syntax with both will mistakenly believe they are declaring an object literal and use colons to separate the identifier from the value; or that they are declaring variables and use assignment syntax to separate the property from its value.

Comma Operator Considered Harmful

It surprises me to learn that JSlint advocates combining var declarations. Crockford's The Elements of JavaScript Style, Part 1 indicates that he isn't terribly fond of it either:

The comma operator was borrowed, like much of JavaScript's syntax, from C. The comma operator takes two values and returns the second one. Its presence in the language definition tends to mask certain coding errors, so compilers tend to be blind to some mistakes. It is best to avoid the comma operator, and use the semicolon statement separator instead.

Whichever way Crockford prefers it, I think what we need to remember is just because you CAN do something does not mean you SHOULD.

Let's consider Dan's full body of JavaScript from the Revealing Prototype Pattern. I'm going to shrink it a little bit, to emphasize the changes I'll make; and I'm removing any of his comments.

var Calculator = function (cn, eq) {
    this.currNumberCtl = cn;
    this.eqCtl = eq;
};

Calculator.prototype = function () {
    var operator = null,
        operatorSet = false,
        equalsPressed = false,
        lastNumber = null,
        add = function (x, y) { return x + y; },
        subtract = function (x, y) { return x - y; },
        multiply = function (x, y) { return x * y; },
        // I'm going to do something evil here.
        divide = function (x, y) {
            if (y == 0) {
                alert("Can't divide by 0");
            }
            return x / y;
        },
        setVal = function (val, thisObj) { thisObj.currNumberCtl.innerHTML = val; },
        setEquation = function (val, thisObj) { thisObj.eqCtl.innerHTML = val; },
        clearNumbers = function () {
            lastNumber = null;
            equalsPressed = operatorSet = false;
            setVal('0',this);
            setEquation('',this);
        },
        setOperator = function (newOperator) {
            if (newOperator == '=') {
                equalsPressed = true;
                calculate(this);
                setEquation('',this);
                return;
            }
            if (!equalsPressed) calculate(this);
            equalsPressed = false;
            operator = newOperator;
            operatorSet = true;
            lastNumber = parseFloat(this.currNumberCtl.innerHTML);
            var eqText = (this.eqCtl.innerHTML == '') ?
                lastNumber + ' ' + operator + ' ' :
                this.eqCtl.innerHTML + ' ' + operator + ' ';
            setEquation(eqText,this);
        },
        numberClick = function (e) {
            var button = (e.target) ? e.target : e.srcElement;
            if (operatorSet == true || 
                this.currNumberCtl.innerHTML == '0') {
                setVal('', this);
                operatorSet = false;
            }
            setVal(this.currNumberCtl.innerHTML + button.innerHTML, this);
            setEquation(this.eqCtl.innerHTML + button.innerHTML, this);
        },
        calculate = function (thisObj) {
            if (!operator || lastNumber == null) return;
            var displayedNumber = parseFloat(thisObj.currNumberCtl.innerHTML),
                newVal = 0;
            switch (operator) {
                case '+':
                    newVal = add(lastNumber, displayedNumber);
                    break;
                case '-':
                    newVal = subtract(lastNumber, displayedNumber);
                    break;
                case '*':
                    newVal = multiply(lastNumber, displayedNumber);
                    break;
                case '/':
                    newVal = divide(lastNumber, displayedNumber);
                    break;
            }
            setVal(newVal, thisObj);
            lastNumber = newVal;
        };
    return {
        numberClick: numberClick,
        setOperator: setOperator,
        clearNumbers: clearNumbers
    };
} ();

Note my comment: "I'm going to do something evil here." Here goes:
console.log('Hello, world')

Do you see what happened here? Let me put it in context.

        subtract = function (x, y) { return x - y; },
        multiply = function (x, y) { return x * y; },
        console.log('Hello, world')
        divide = function (x, y) {
            if (y == 0) {
                alert("Can't divide by 0");
            }
            return x / y;
        },

JavaScript semicolon insertion blew away the var when I inserted any valid statement or expression. In fact, I could have simply put 'Hello, world!' or 5 there, on its own line, and because the next line is a valid statement that stands on its own, JavaScript semicolon insertion blew away the var. As such, divide, setVal, setEquation, clearNumbers, setOperator, numberClick, and calculate were all just elevated to global scope, possibly blowing away existing variables and leaking a whole bunch of information with them. This could happen in any instance in which someone mistakenly types a semicolon (let's be honest - JavaScript is a semicolon-terminated language; it will happen somewhat frequently), or if they forget to put a comma at the end of a line.

As such, joining variable declarations together by using the comma operator is inherently an unsafe operation. You might think of it as a run-on sentence; it's not a good thing to do in English, so why would it be good to do in JavaScript or any other programming language?

And if that's not reason enough, here's another: declaring a variable is a statement. You are stating to the compiler, "I am declaring this variable to be a variable." Use the var statement to make a statement, and use the comma operator to indicate that there are operations. (Specifically, the one and only place I can think of in which a comma operator would be appropriate is if you need a single for-loop with multiple iterator variables, e.g., for (var i = 0, j = myArray.length - 1; i = 0; i++, j--). Of course, I don't want to say you should never use it, or else I'd be like Crockford with his dogmatic "I have never seen a piece of code that was not improved by refactoring it to remove the continue statement," which is patently silly.

But, beware the comma. He is correct in that it is easy to mark programming errors with commas. If you're going to declare a variable, do everyone a favor and declare it, using var, make it feel special by giving it its own line and declaration and semicolon. It will help in maintenance down the line.

28Mar/110

A Recent Discovery: IronJS

Posted by Rob Paveza

Since Microsoft first announced Managed JScript and shortly thereafter announced its demise (more on that here), I’ve been chomping at the bit for an implementation of JavaScript on the DLR.  Actually, I’ve probably been hoping for it for far longer, because JavaScript is near and dear to my heart.  If not for Brinkster offering free ASP-based web hosting back when I was just a young’un, I may never have discovered server-side programming, and may never have ended up where I am today. 

IronJS is a free, open-source implementation of ECMAScript v3 on the DLR based predominantly on F#.  It’s even the right kind of free, currently licensed under the Apache License version 2 (not a copyleft license).  Check out this picture of its testbed application running:

image

As a learning exercise, I intend to figure out a good way to shoehorn this into my Battle.net (1.0) chat client, JinxBot.  It actually shouldn’t be terribly difficult, but while I considered adding it as a plugin, I think I’d like it to be part of the core application instead. 

I’ll more than likely be covering IronJS in several parts in my blog in the coming weeks (possibly months, since I’m getting married on May 1).  But these are topics that I intend to cover:

  • Hosting IronJS in a C# application, loading, and executing JavaScript code
  • Sharing objects between script and .NET
  • Isolating script from .NET (preventing script from having run of the whole runtime)
  • Isolating script from script (running multiple environments in one application, similar to how web pages in browsers like IE and Chrome all run from one instance of the script engine but have different contexts so they have different sets of objects)
  • Performance optimizations
  • Dynamically generating isolation layers
  • Other considerations

Stay tuned!  In the meantime, check out IronJS on GitHub and get it running on your machine!