DailyJS

DailyJS

The JavaScript blog.


Tagstyle
Featured

libraries style node modules ES6

Standard, propertyinterceptor

Posted on .

Standard

Feross Aboukhadijeh's Standard (GitHub: feross/standard, License: MIT, npm: standard) is a zero config linter that checks your code against community conventions:

Adopting standard style means ranking the importance of community conventions higher than personal style, which does not make sense for 100% of projects and development cultures. At the same time, open source can be a hostile place for newbies. Setting up clear, automated contributor expectations makes a project healthier.

Be aware that one of the choices is no semicolons, which I don't believe is popular enough to be considered a "community convention". However, key contributors in the Node community do advocate dropping semicolons, so things seem to be moving that way.

This project uses eslint and contains the .eslintrc file so you don't have to worry about it. In fact, the idea of settling on a standard style guide for a project is sensible and something that can be automated rather than left to the PR/code review stage.

propertyinterceptor

If you use Object.getOwnPropertyDescriptor and Object.defineProperty then you might like Simon Blackwell's propertyinterceptor (GitHub: anywhichway/propertyinterceptor, License: MIT, npm: propertyinterceptor):

A simple, standardized means of creating reliable chained before and after methods on Javascript object properties for validation, security, functional reactive programming, and more.

It adds the following methods:

  • Object.intercept.afterGet(someObject,someProperty,interceptor)
  • Object.intercept.beforeSet(someObject,someProperty,interceptor)
  • Object.intercept.afterSet(someObject,someProperty,interceptor)

You can also short circuit the interceptor chain by throwing an Error object. If you like getOwnPropertyDescriptor or defineProperty but dislike the boilerplate, then you might prefer Simon's API.

Featured

language style node

Semicolons, Objectively

Posted on .

Last week in Programming Styles in the Node Community I discussed the styles of three prominent developers in the Node community. The ensuing debate mainly focused on semicolons. Rather than telling you my opinion on the topic, I'd like to explore it objectively so you can make your own decision on whether to use them or not.

Style and semantics aside: how are semicolons handled by minimizers? Is it safe to write a client-side library without semicolons?

Let's look at the two most popular minimizers according to JavaScript Developer Survey 2011 Results.

YUI Compressor

YUI Compressor can be downloaded as a zip file and includes a jar file in the build/ directory that can be used like this:

java -jar yuicompressor-x.y.z.jar myfile.js -o myfile-min.js --charset utf-8  

This basic usage will insert semicolons. If you write a file without semicolons, it'll remove newlines and insert them for you. It'll also add semicolons to the end of a file, so concatenating multiple files is safe.

Closure Compiler

Closure Compiler is also a Java application, and there's a web interface for it at closure-compiler.appspot.com. By default semicolons are also inserted, and a semicolon will again be appended to the end of the file to aid concatenation.

In cases where usage is ambiguous, Closure Compiler will raise JSC_SUSPICIOUS_SEMICOLON. Try this in the web interface:

if (true);  
else alert('no');  

The Closure Error and Warning Reference documentation explains this warning, which can be turned off:

The compiler assumes that this is a mistake, and that you meant to have a statement between if (true) and the semi-colon.

Both of these libraries will also strip unnecessary semicolons. For example, given this simple example:

function hello(longName) {  
  alert('Hello, ' + longName);
}
hello('New User');  

The semicolon after alert will be removed.

Standards

Standard ECMA-262 and previous versions of ECMAScript include "Automatic Semicolon Insertion":

Certain ECMAScript statements (empty statement, variable statement, expression statement, do-while statement, continue statement, break statement, return statement, and throw statement) must be terminated with semicolons. [...] For convenience, however, such semicolons may be omitted from the source text in certain situations.

Prior to this edition of ECMAScript, deprecating or removing this feature was discussed by Brendan Eich and Douglas Crockford in es3.1:semicolon_insertion. Crockford said:

Strong language in a spec is not likely to work. A carrot of better features that induce rewriting works better, but nothing is predictable.

This "carrot" approach comes up frequently in the discussion of ECMAScript's development, and it can be seen under the list of Themes in the index to the Harmony namespace at the ECMAScript Wiki: harmony:harmony.

Conclusion

When deciding on JavaScript style, the debate on whether to use semicolons will never end. Objectively we can say that:

  • The tools to write client-side code without semicolons exist and are widely used
  • The specification explains how semicolon insertion works, and even includes concrete examples
  • Semicolons are going to stay around for a while

Other languages have optional semicolons. Take Ruby for example: the community at large embraced writing code without semicolons. However, many JavaScript developers learned the language without the benefit of newer tools that help work safely without semicolons. Others are working with server-side JavaScript, running code on one platform rather than multiple browsers and meddling HTTP proxies. They're able to embrace styles that were previously deemed "unsafe".

The nature of the language is changing, so expect to see less semicolons in the future.

However, if you like the "machine"-like look of semicolons, and feel more comfortable expressing your intent by using them judiciously, then by all means use them!

Keep your style consistent, and enjoy writing JavaScript.

Featured

language style node

Programming Styles in the Node Community

Posted on .

Programming style is where opinion and reason collide, often leading to endless arguments with no clear winner. The real secret to style is to be consistent, and respect other people: if you're working on a project by another author, then follow their style. Some companies and open source projects may have their own in-house style guide, but it's generally fairly easy to pick up the style of a project after browsing the source for long enough.

Why do I bring this up? Well, the Node community has several dominant styles, each with their own advantages. If you're starting your own Node projects then you might like to use the style of a well-known developer for guidance of inspiration.

TJ Holowaychuk

TJ Holowaychuk, author of Express, Jade, Stylus, and Mocha, has an extremely consistent style. TJ uses two spaces for indentation, semicolons to end lines, and formats commas at the start of a new line:

var connect = require('connect')  
  , Router = require('./router')
  , methods = Router.methods.concat('del', 'all')
  , middleware = require('./middleware')
  , View = require('./view');

This practice is becoming more common in JavaScript, and the arguments for and against it vary. Isaac Z. Schlueter created a gist on the subject at gist.github.com/357981 which grew into a heated debate that currently has 64 comments (since April 2010). It's worth noting that TJ also carries this over to his JSON formatting, and generally only uses one var statement at the top of each new scope.

One of TJ's more subtle stylistic habits is to remove the space before the opening brace of a method:

exports.parseQuality = function(str){  
  // ...
};

When writing a function, however, he'll usually retain the space:

function quality(str) {  
  var parts = str.split(/ *; */)
    , val = parts[0];

  var q = parts[1]
    ? parseFloat(parts[1].split(/ *= */)[1])
    : 1;

  return { value: val, quality: q };
}

Notice that the ternary operator is split across new lines as well, which can make longer expressions more readable.

TJ also uses double quotes sparingly as well. Most strings are written using single quotes.

TJ's Luna project isn't related to JavaScript, but during development he made an interesting point: he likes the "machine-like" look of JavaScript's operators. Some languages provide and instead (or as well as) &&, but TJ prefers the way operators like && read:

Personally I'm not a fan of "wordy" operators, aka or and for || &&, etc, though again they can look ok within reason, but I find the "machine-like" look of operators provide a nice visual separation.

I think the "visual separation" comment is interesting, because I find semicolons in JavaScript also provide visual separation, although other people may find this noisy.

 Isaac Z. Schlueter

Isaac Z. Schlueter, author of npm (where would we be without it?) is outspoken about style and language "magic". I enjoyed reading his post Experts, Idiots, and Taste, and JavaScript is Not Web Assembly is related to this. Isaac doesn't like language "magic". He's pragmatic and keeps things simple. Let's take a look at his coding style.

Like TJ, Isaac uses leading commas and two space indentation, and usually groups variables under one var. Functions are spaced out like this: function help (args, cb) {.

The biggest difference between TJ and Isaac is semicolons. Isaac doesn't use them to end lines unless necessary:

function checkGit (folder, cb) {  
  // if it's a git repo then don't touch it!
  fs.lstat(folder, function (er, s) {
    if (er || !s.isDirectory()) return cb()
    else checkGit_(folder, cb)
  })
}

Isaac has written a detailed explanation of this decision in An Open Letter to JavaScript Leaders Regarding Semicolons. He makes good points as to why semicolons can be left out, although admits that this style may only be slightly superior.

Ryan Dahl

Ryan Dahl, creator of Node, has a slightly different style yet again. Like TJ and Isaac, he uses two spaces for indentation. Conversely, he'll use multiple var statements per-line:

var express = require('express');  
var socketio = require('socket.io');  
var bench = require('./bench');  

This is from d3bench, a small benchmarking app. He writes functions and methods with a single space: io.sockets.on('connection', function(socket) {. He doesn't line up colons in object literals:

var r = bench.run({  
  url: "http://localhost:8000/buffer/12345",
  concurrency: 10,
  requests: 50000
});

Deeper Style Choices

Indentation, semicolons, and other formatting topics are one side to coding style. Another is the choice of language features. Both TJ and Isaac use exceptions sparingly. Isaac is outspoken about exceptions:

I have settled in the last few years on the sentiment that try/catch is a mistake, and an anti-pattern.

This is from try/catch/throw on the Node Google Group.

TJ sometimes organises code into folders, with an index.js file, so a group of modules can be loaded with one require. Router in Express is an example of this. This technique removes a barrier from splitting up code into multiple files. Both authors also make heavy use of other Node modules, rather than reinventing their own solutions to common problems. The npm package.json is a good example of this.

Conclusion

Before starting a new project, it's worth researching the programming styles used in the community of your chosen language and framework. Encourage the rest of your team to be consistent, even if they're freelancers or contractors who have their own styles. The best comment I've read on how important it is to respect a project's style is by Isaac:

In your own house, you get to decide the styles and customs. But be aware that it might have an effect on who feels comfortable at your parties.

Yes, it's all FUD, in reply to Actual drawbacks to omitting semi-colons?.

References:

Featured

programming style

Significant Whitespace

Posted on .

In his homoiconic blog, Reg
Braithwaite
recently discussed jQuery
because he heard that it "changes the way you think about programming".
In Significant
Whitespace
,
Reg discusses how jQuery embraces the use of chained calls on separate
lines to increase readability:

instance
  .call1(text)
  .call2({...})
  .lastcall('open');

He makes an interesting stylistic point:

To keep the logic clear I've been using the following style guideline: When I'm returning the receiver, I do not indent.

So when he returns something else from a chained call, he indents:

$(event.target)
  .parents('body > *')
    .find('.wants_close')
      .trigger(event);

He likens more complex chained and indented calls to
haml and sass. JavaScript isn't aware of the level of indentation, but he suggests that
this could be useful, and relates this to jQuery's end()
method.

His last point is what really made me understand his arguments:

I have some other reasons for wanting this in the language that have to do with destructuring assignment, pattern matching, and other uses for code that looks like the data it manipulates.

Even though his hypothetical language would be interesting,
understanding end() can trip up jQuery beginners working on
other people's code. I've had to untangle deeply nested ends before and
it's one of those things that encourages me to finish work early and hit
the beer. If you're feeling a little bit lost, the end()
documentation
makes it all clear once you
work through the examples.