Trust

Trust yourself, trust your skills, trust your tools.

By nature, any programmer who has worked for any decent amount of time is going to be gun shy about a lot of things.  We say “probably” a lot,as well as “most likely” and “should”.  We’re not comfortable saying yes, is and will. Because things which we were sure of have at some point not been sure.  Some of this is because the people in business that we are coding for look at things differnently than programmers.  We might say, “So, what you are saying is that orders which are delivered are never picked up by a customer?” And the business people nod and say yes, and are glad you get it. So you go back and you make a couple of kinds of orders, ones which are delivered and ones which are picked up by the customer, and over time logic is added to these that are based on those facts: delivery and pickup, and all is well.

Then one day the business people have a problem, see sometimes when an order is out for delivery, the delivery person gets abducted by aliens, and then the customer might want to come and pick up the order instead of waiting for the delivery person to be rescued or replaced by autonomous drones.And now none of it works anymore, and the programmers are mad because the customer said this would never happen, and here it is happening all over the place all the time. And the business people are confused because they were really just talking about a rule that applies 90% of the time.

And over time, programmers learn to be a little bit scared of absolutes, they lose some of their trust of the world being an orderly place (well it isn’t, after all:) and it changes the way we think.

There’s a classic joke:

Three Americans, an engineer, a physicist, and a programmer were all on a train in Scotland. They looked out and saw a bunch of white sheep. The engineer looks out and sees a black sheep. “There are black sheep in Scotland!” he says.

The physicist looks out and says, “Well, there’s at least one black sheep in Scotland.”

The programmer looks out and says, “There’s a sheep in Scotland who is black on one side.

This is okay behavior at one point, but it bleeds out into other things. I’ve seen a lot of good, senior programmers who were scared of their shadows. Anything new was looked at askance. Anything that works differently is inherently dangerous. That, unfortunately can get in the way and lead to inefficient code. This is really true when the technology is really fundamentally different than the one you are used to.  In the case I”m thinking about it, it’s a C# programmer writing code in JavaScript, and just not really being comfortable.  That’s my read on it anyway, and reading code is a lot like reading the mind of the person who was writing it.

We’ve got an iPad app that is writing with Backbone.js, and is a giant mess of complicated JavaScript. Part of my job is to maintain it, add features, and clean it up where I can.  It’s a product that has many implementations and customers, so there’s a product level config that gets read in. Now, product A was created before Feature 1 was created. Only customers who pay for Feature 1 to be incorporated in the product, get that feature, but it’s part of the base code. (There is, I think a better way to have implemented this in the build process, but that’s not what I inherited).  The app object (which is a global javascript object) loads the products config and runs through a process that turns on and off the features of the product, based on what is on.

    var featureOne = app.product.config.hasOwnProperty("FeatureOneFunctionality") ? 
                           app.product.config.FeatureOneFunctionality : 
                           false;
    this.featureOneIsOn = featureOne ? true : false;

Um, okay? I mean, it passes the first test of code, it certainly works. It’s mostly okay. But it shows some fear. What’s a better way to write this code, and have it do the same thing?

        this.featureOneIsOn = !!app.product.config.FeatureOneFunctionality;

Some days I’d drop the “!!” off the front, but that forces it to boolean, which is needs to be. Odds are if it’s set it’s true or false already, so the only other value we’re going to get is undefined and !!undefined is false.

But, in C# if you referred to “app.product.config.FeatureOneFunctionality” and it didn’t exist, then that throws an error. It probably won’t compile, even. in C# the product config page would inherit from a standard one, when you add a feature you’d add it to the parent object, with a default value of false, and you’d be done. You could do this with JavaScript, but that kind of inheritance isn’t really right either, and could potentially break this code.

My guess is that this lack of trust of JavaScript is why they are calling Object.hasOwnProperty. Of course, if the config file ever were inherited like you would do in C# all these hasOwnProperty calls would fail. Because Object.hasOwnProperty is asking does this Object have a property named X which is defined on this property and not on its prototype? If an object has a “FeatureOneFunctionality” property that it got via prototypal inheritance, and wasn’t set, it’ll return false. As long as falseis our default, this code is okay (as it defaults it to false) but if we ever had a global feature that defaulted to true, this would cause it to be falseinstead.

There are other ways to check if an object has a property or not, that don’t depend on Object.hasOwnProperty, but that’s neither here nor there. In this case, it’s just a value property, and it’s a boolean. Not having it means it’s false. Pretty straightfoward.

And never mind that ternary operator later. That was also elsewhere in the code, where two variables were compared, thusly:

    var showThing = showITMode == "showIt"? true : false;

And this is also a lack of trust, either in themselves or in the code. Why not just this:

   var showThing = (showITMode == "showIt");

I added the parentheses because it makes it clearer to the next person than what it would look like before. It’s no more necessary than the ternary operator, but there’s a reason we call that the “obfuscation operator”.

This is part and parcel of the attitude I’m dealing with at work. JavaScript is seen as a scary thing without rules or logic. So we spend a lot of time writing rules around what you can and can’t do with it, and it takes the power away form the language. JS’s truthy and falsey values are weird, but understanding them can help you write cleaner looking, easier to reason about code. Closures and lexical scoping are hard concepts, but can help you get rid of this and the complications it creates. [this is one of those examples that drives OO programmers from type-safe languages nuts. The idea that this can change based on where and how a function is called? That’s foreign and anathema to them. I’m not a huge fan of it either, but that’s a later article]

Just a note that this example does not come directly from work code. It’s an amalgamation of things that are in the code, which is why it might seem worse than it is. This is code that’s running out in the wild and doing its job, it’s just not pretty, and doesn’t pass the second test of code: easy to read and reason about.