Braceless Programming

During the Software Passion Summit in Gothenburg, I had the privilege to talk to Douglas Crockford, the grandfather of Javascript and the creator of JSON and JSLint

While I think that JSLint is an awesome tool, I also think that it is too opinionated and therefore I use JSHint, an alternative that allows me to tweak more of the parameters to fit my style of coding. Douglas think that this is sacrilege, but I disagree. There are two major things I disagree with in JSLint and they are:

  1. I must have braces for every conditional and loop statement. I don't like this, I want my code to look as clean as possible and lots of braces clutters it.
  2. I must declare my vars at the top of the function. I don't like this because it complicates refactoring.

So this is what I think:

All braces that are not necessary should be omitted.

and

Variables should be declared on first usage.

In Javascript, and other C-like programs, there are only two valid cases for using braces. It is when I am declaring objects and functions (and in other C derivates: classes).

So what does this mean in practice?

Lets pretend that I have a function that looks like this:

The above fulfills JSLint style, but it does not fulfill my braceless since it has a bunch of unnecessary braces. This is how the code would look like in braceless style:

Braceless style encourages breaking the code up into small functions and this is a good thing. It makes it easier to test and it makes it easier to reason about. It also lowers the cyclomatic complexity

At the moment it is not possible to configure JSHint to disallow braces for loops and conditional, but it would be a good thing.

There are other cases where braces appear in Javascript most notable when creating new objects. I could argue that object creation should also be moved to its own function but, I currently don't follow this guideline myself.

This Post Has 24 Comments

  1. I agree on your variable declaration point, but disagree on the braces. I used to write braceless myself for a long time, but have since found that braces helps in reading and re-writing code. This is especially true when using Vim.

  2. @Starfish, I don’t see your point, I use Vim myself. In what way does it help when reading and re-writing code?

  3. I agree with Starfish’s preferences.

    Ever since being forced to use braces in the early 1990s for C because of a coding standard at work, I never looked back. It is not only visually more clear, but also it allows adding additional statements without having to go back and add braces, and also (when in C/C++/Java) it creates a lexical scope for variable declarations.

    As for “var” in JavaScript, it’s a broken concept (I await lexical “let”), so that complicates matters, but I like putting them close to initialization or use (as in C/C++/Java) even though I know they are being hoisted up.

  4. @Franklin, One of my points for using the braceless style is that it does not allow me to add additional statements without extracting a new method. It
    keeps me sane, but you don’t have to agree with me.

    As for the let statement, I’m looking forward to it too.

  5. In ordinary language, avoiding braces means not using them when they are needed, e.g. writing if (cond) statement1; else statement2; instead of if (cond) { statement1; } else { statement2; }.

    Now that is a matter of taste (and trust; see Franklin). The style wars in C first translated to C++, then Java and C#, and now Javascript. Fine. Go ahead, flame away, I’m afraid it won’t change anyone’s opinion.

    Refactoring when there is more than one statement in loop or conditional statement doesn’t make sense to me. That works on one example, but doesn’t generalize. How would you do this for finding arg^-1?

    if (a[i] < min) {
    minIndex = i;
    min = a[i];
    }

    Your example is just classical OOP, in fashion since Simula 67 (and yes, that's the year it was released). It has nothing to do with avoiding braces, just with breaking down behavior, or refactoring. It's a highly sensical thing to do, also if you wouldn't avoid a single brace doing so. I can actually write your original code without braces:

    for (i = 0; i < animals.length; i++)
    if (animals[i].isHerbivore())
    grass = prepareGrass(animal);
    for (i = 0; i < animals.length; i++)
    if (animals[i].isHerbivore())
    water = prepareWater(animal);
    for (i = 0; i < animals.length; i++)
    if (animals[i].isHerbivore())
    animals[i].feed([grass, water]);
    for (i = 0; i < animals.length; i++)
    if (animals[i].isCarnivore())
    meat = prepareMeat(animal);
    for (i = 0; i < animals.length; i++)
    if (animals[i].isCarnivore())
    water = prepareWater(animal);
    for (i = 0; i < animals.length; i++)
    if (animals[i].isCarnivore())
    animals[i].feed([meat, water]);

    Now that's ugly, but it does the same (assuming none of the functions influences other animals) and has no braces at all. Does that make it better?

    WRT variable declaration up front: that makes sense in Javascript, as the language's definition has a scoping rule that really deviates from anything else out there. But it's the definition, so I'm a bit surprised that Crockford has a problem with anybody using the language the way it was designed.

  6. Sorry about the previous example, I should have replace all animal with animals[i] and turned all water, grass and meat into arrays as well, so water[i] = prepareWater(animal[i]); … animals[i].feed([meat[i], water[i]]);

  7. @Theo First of all, thanks for your input and even though I don’t agree with
    you, I value your feedback.

    1. Flame? Calling a post, where I express my preferred style of programming for flame, is a bit over the top. If I would tell you that I like helping old ladies cross the road, is that also a flame?

    2. Avoid. According to Dictionary.com, http://dictionary.reference.com/browse/avoid, avoid means “to keep away from; keep clear of; shun: to avoid a person; to avoid taxes; to avoid danger.” It has nothing to do with something being “needed” or not. I would argue that if something is needed, it is unavoidable.

    3. If I was to write a min function for arrays in my preferred style I would
    write it like this

    function min(a, b) {
    return a < b ? a : b;
    }

    function arrayMin(array) {
    return array.reduce(min);
    }

    But that said, I don't have any problem of putting in braces in cases where they are needed. I don't avoid at all cost.

    4. OOP, I would probably more call the style I was using in my example procedural than I would call it classical OOP. So that means it dates back even further than Simula-67. But I only used this to demonstrate this very example. Apart from the braceless programming style I also prefer a much more functional style where most functions don't have side-effects. As you can see from the example of arrayMin above.

    5. The case for variable declaration in the top of the functions is actually a
    valid case. If you write long functions and reuse variables it can actually
    become an issue since all variables declared in Javascript have function
    scope. But, in my case, I don't write long methods and, therefore, I don't
    have this problem.

  8. Crockford’s arguments for most of his constructs have to do with avoiding bugs, not with creating the most concise or elegant-looking code. You can agree or disagree with that, and I think he takes too hard a line in some situations, but personally I agree with these two.

    With the var thing, I honestly could go either way, but the point is to write code that reflects the way it is interpreted. Putting a var statement inline is inaccurate, plain and simple. If you are in the habit of declaring variables when they are needed, as most of us are in non-JS contexts, you can easily make mistakes because you could assume a variable is undeclared at some point in a function, if its declared later.

    Of course, using a syntax checker should easily avoid issues here. It should just tell you if you’ve declared a variable twice, or used it before you declared it (which, though legal in JS, I think anyone would agree is a very bad idea).

    But for the braces, I see no benefit to not using them. It’s a bug factory. It’s too easy to add a line that’s indented and think it’s part of the group. It encourages writing one liners which are definitely not readable.

    You don’t need to add an extra line for every brace, either. I think the concise, braced version of your example is absolutely more readable and takes up no more space.

    if (animal.isHerbivore()) {
    feedHerbivore(animal);
    } else if (animal.isCarnivore()) {
    feedCarnivore(animal);
    }

    The braces are visual cues. Without them you could be looking at a single logic group split on two lines because it was too long. You don’t know until you read the code if you can’t depend on braces.

  9. Having to declare all my variables at the start of each function would be a deal-breaker for me. That’s positively prehistoric. I also omit braces where I can; it makes the code more compact.

  10. Wouldn’t removing the braces be Visual Basic?

  11. @Anders

    I think that variable declaration at the start of the method doesn’t really make much sense, especially if you only need the variable within a limited scope. Limiting scope allows for the resuse of iterators without having to worry about data bleeding, and leads to more separated code blocks.

    As a personal style, I use braceless if- and for- statements when appropriate, however I have to disagree with writing code specifically for that purpose.

    In the example you provided, I can see the use in providing a function to handle code that is repeated, and that does lend itself to a braceless structure. However, I think there needs to be some kind of balance in that philosophy. The way I see it, a _purely_ braceless design philosophy leads to many interdependent methods, which can make the code less readable, and much more difficult to debug and test.

    Assuming that you are advocating a logical and resasonable limitation on how braceless the code should be, I would definitely agree with your design philosophy.

  12. It is a good idear. There are so many languages without braces really, and you will see ada, basic, cobol, …

  13. UGH! I used to write as little braces as possible, and to this day am a “minimalist” (if that’s a word)….but I detest, detest, DETEST!!!, braces on the same line as code. It does nothing for readability for me to have braces if all that you’re doing is putting them on the same line as code. And I know, I know, I can hear you all screaming at me now saying that almost everyone does that….but (GAG), it’s not for me…When reviewing code that has braces that way, I don’t complain, but If I can find any reason to spend a few minutes and push those braces down to a new line by themselves….I’ll make a new commit for it. I run stylecop on my side and check for that kind of stuff…but way back when I was VIM/Unix developing I was still the same.

  14. @Jamie, I’m aware that Crockford’s uses this style in order to avoid bugs.

    I just don’t see that type of bugs when using the braceless style. The
    declaration bugs never appear since the style encourages short functions.

    Omitting the braces are not a bug factory, since when I never use them inside functions I never make the mistake of assuming the extra line should be executed inside the loop of conditional statement.

    Omitting the braces also encourages short functions and I think this is good.
    If I find myself wanting to add braces, it is a sign that I should refactor my
    code to abide to the Single Responsibility Principle.

    @Code Monkey, I agree, the style does not have to be pure, for the sake of
    being pure. I use it because it encourages, what I think is, good behavior.

    @zighouse, :)

    @chuck, In Javascript there is actually a good reason for having the braces at the end of the line.

    return {
    first: ‘Hello’,
    second: ‘Tapir’
    };

    means return the object, while

    return
    {
    first: ‘Hello’,
    second” ‘Tapir’
    }

    returns undefined, because of semi-colon insertion.

  15. “Omitting the braces are not a bug factory, since when I never use them inside functions I never make the mistake of assuming the extra line should be executed inside the loop of conditional statement.”

    If you can change “I never” to “nobody ever” then you will be ready to apply your code style in an environment that contains more than one programmer :-)

    If your project might need maintenance by another, and especially if it’s likely to outlive its original author’s engagement with it, then the good coding style is the one with the fewest gotchas. You personally might never fall for the gotcha of assuming an indented line (for, e.g. a “for” construct) is part of a compound statement, but this is a real thing that really happens, so not everybody is as immune to it. It’s akin to “Oh yes, I always leave my rake lying in the long grass. It’s no problem because I always remember where I left it”

  16. Anders, I agree with you 100%; the practice of declaring variables at the beginning of a function, say, is a throwback to properly block-structured languages such as Algol-60, in which variables only exist within the scope of the blocks in which they’re defined. But as we’re all aware, in JavaScript, the scope is (unfortunately) the function itself, no matter how deeply inside a bunch of blocks something is defined, so therefore defining a thing on first use is valid and completely understandable. I have to believe that doing so is also marginally faster, simply from the point of view of how the lexical analysis of the JavaScript works; in terms of cyclomatic complexity, you’re definitely correct.

  17. Braces are a good thing. I had a contractor write some logic without them. Then later came back, added a new line of logic after a line after the if statement which caused a major issue because, of course it ignored the always ran the new second line, because it wasn’t inside braces. Having braces, if even around one line of code helps prevent such over-sites when a developer is in a hurry.

  18. I think either universal, Crockford’s or yours, is too strong. Eliminating braces for one-line conditionals can make code much more readable, because it fits more on the screen vertically. But where I make an exception is when the “one line” runs onto more than one line. A single code line that is far too wide to be seen is often broken up across multiple visual lines. For instance, an argument with many, long arguments might have those arguments spread across several lines to help the programmer visually parse what is happening. Language-wise, this is all one line, as is an if statement inside another if statement. But because it looks like more than one, it should have braces around it just to make sure people looking at it will instantly understand it as a single block (even though technically it is only a single line).

    Variables, too, shouldn’t be universally declared this way. Refactoring is not easier when your declarations are scattered everywhere in unpredictable places, it is harder. But the main problems here are two:

    1) In JavaScript, declaring a variable inside a block, and especially inside a for statement, _looks_ like you’re defining something for a narrower scope than you really are. As with braces, the rule should be “make it look clearly and unambiguously like what it actually is”, rather than “always do” or “always don’t” something.

    2) Changes to the code can very easily make the “first use” of a variable no longer the first use. Do you really want to have to go searching for where something is defined every time you move lines of code from one location in a function to another? Modifying code is a pain in the neck when everything is scattered willy-nilly throughout. And if you’re in the habit of declaring loop variables inside the for statement, and you re-use the same variable in another loop further down, you either are going to wind up declaring the same variables multiple times or have to keep track of which ones have been used and which haven’t yet…and then you set yourself up for the case where the first loop gets eliminated or changed at some point leaving the second loop accidentally left using a never-defined variable which suddenly is moved into the global scope.

    And algorithms are easier to visually understand if they don’t run on with all kinds of extra declaration lines in the middle of functional code.

    So really, the rules should be “eliminate all unnecessary braces that don’t help you visually read the code properly” and maybe “declare single-use variables where they are used, and those used throughout a function at the beginning of that function.”

  19. So you want braceless javascript?

    Have you considered that maybe you should just use coffeescript then?
    http://coffeescript.org/

    No braces at all, even gets rid of some of those annoying extra parens.

    Not that I’m advocating coffeescript, just saying that based on your desired JSLint changes and your reasons for wanting the changes, it really sounds like what you want is coffeescript.

  20. @sweavo, Yes, I agree, that is a valid point. But when I come into a project I try to follow the style that is used inside the project. And I expect others to do the same. The style is pretty obvious once you get used to it.

    @Dan, I’m glad you agree.

    @Just Me, It is a valid point. When the project is using braceless style it is
    very clear. New programmers will have to be educated in this style.

    @TMcGill, You are quite right about using the style rigidly is not always a
    good idea. I especially like your example of algorithms. I agree that they are often more clearly stated in one method than spread out in many.

    @Gates VP, Yes Coffeescript is nice, the braceless style is valid in
    Coffescript too, though. It just has to be called something else.

  21. @Anders

    1. sorry for the misunderstanding about the flaming. I have been too brief. I wanted to say that such choices have their pros and cons, and that you’ll find people defending either side. Then it turns into a flame war, but still nobody gets convinced.

    2. And I butchered “needing”. It should have said “not needing”.

    3. The argmin function is supposed to find the index of the least element. In Ruby you might get away with one statement (as you can assign multiple variables at once), but in Javascript it’s going to look ugly. On the other hand, building a function just to do that seems like a waste. The point being that there is no style rule that covers 100%.

    4. OOP is more a line of thinking than a notation. We’ve come to think of it as obj.fun(…), but you can do OOP in C if you want. Or in Javascript!

    5. I agree about declaring variables on top: it’s more hygienic. I was just surprised that someone who could have changed that at Javascript’s conception, objects when the language is used the way it was designed. Or perhaps I’m overestimating his influence on the language?

  22. @Theo 1, 2, No worries :)

    3. I see, yes, that is a valid exception for performance reasons,
    but an alternative solution with about twice the running time
    is quite clear, too.

    // Find smallest element and its index
    function minWithIndex(array) {
    var min = Math.min.apply(Math, array);
    var i = array.indexOf(min);
    return [min, i];
    }

    4. I agree, OO can be done in any language.

    5. Yes your are overestimating his influence. He was only an early
    adopter, Brendan Eich created it.

    Thanks for your feedback, you made me rethink my position, and
    that is always good.

  23. Thank you all for an interesting debate – especially to Anders who started it. Made me remember a debate some years ago when we were discussing if all elements in programming language should be text or not.

Leave a Reply

Close Menu