"At some point in computer history, somebody (arbitrarily?) created an 80 character line limit for code. ... I’ve been writing JavaScript for three-ish years"
For a couple decades, and not ending until the late 90s, most text terminals and text modes for graphics cards were 80 characters wide[1], and dot matrix printers also had an 80 character line length (plus margins) dating back to 80 characters per line punch cards from 1928[2]. If a line was longer, you had to scroll that individual line. To let your code be read easily anywhere including your own screen, you stuck to that line length.
Which of course begs the question, why were punched cards 80 characters wide? According to a random StackExchange commenter:
"The cards are that size because in 1890, CTR wanted to reuse currency carriers (the dollar was bigger back then) to carry the census data cards. – Al Biglan"[1]
Assuming this is true, and that the size of the card was chosen to match the size of the US dollar, it can perhaps be assumed that 80 columns was chosen as a reasonable compromize between data density and structural integrity. I'm not sure that this makes sense though, since Wikipedia says that IBM's 80-column cards date from 1928. A more authoritative source would be welcome.
Note that typographical measures are usually even smaller, with 66 characters per line being quite common. And those don't use monospaced fonts and are thus even more narrow, and thus easier to scan. Granted, they usually don't include spurious whitespace, but if 40 characters out of your 80 are empty, you've probably got a different problem altogether.
The google javascript style is overly verbose and really awkward. Javascript isn't a typed object-oriented language. If you fight javascript until it looks like C++, you make an awful mess. Most of the javascript I've read from google is overly verbose, takes ages to compile(!!) and it avoids javascript's best features - anonymous functions (closures), object literals and dynamic typing.
If the author writes his javascript as if it were C++, its really no wonder he hates the language. Javascript is a wonderful little language - but its not C, and if you pretend it is, you're going to have a miserable time.
It's a matter of practicality. JavaScript can do some really cool things, but if it makes the code harder to read/follow/maintain, it's not very useful. From what I've seen, a lot of the JavaScript techniques that have gained popularity over that last couple years make code less grokkable for a project newcomer.
My goal is to write code that anyone can understand. I get much more enjoyment out of that than writing JavaScript "the JavaScript way."
Project newcomers or JavaScript newcomers? Because if you are optimizing for the latter under the pretense of optimizing for the former, you are building code that experienced people won't want to interact with.
FWIW, I'm with you on wanting to write readable, usable code. But my Python code does take advantage of functional aspects and meta programming at time, because I can write far fewer lines of code, which means fewer bugs and less time spent mentally parsing code later.
I meant that I optimize for project newcomers, preferably ones who are comfortable in the finer points of JavaScript.
It's not that I don't take advantage of JavaScript's strengths. I get the sense that people interpreted my article as a glorification of the Google Style Guide, that it should be followed precisely. I suppose I should have worded it better. My personal style is heavily inspired by Google's, but I freely deviate where I feel it is practical. For instance, I use closures and functional approaches when I feel it will make for faster/more readable code. It's mainly the annotations and and line limit that I follow religiously.
Agreed, also on the count that writing idiomatic code is, in my opinion, much more beneficial than having to refer to a third party style-guide to grok a non-idiomatic flavour of it.
The obvious benefit is that knowledge can then be applied to any other project using the language idiomatically, and not as if it were 30 years old. Conversely, code to the third party style guide, and struggle to understand the many things that don't adhere to it.
I'm a huge fan of an 80-character limit. But more importantly, of having a rigorously-defined limit.
It has nothing to do with history. Horizontal scrolling is a usability nightmare, and in programming, word-wrapping introduces ambiguities.
Code should be designed to be read. You should be able to set your editor to the width defined by your project standards, and know that the code will always look the same to everyone. Clear coding is an art, and makes use of well-chosen indentation and linebreaks. Having different people use different widths in a single project destroys that art and legibility.
Now, why 80 characters? Here's my personal reason. According to "The Elements of Typographic Style", by Robert Bringhurst:
> "The 66-character line is widely considered ideal."
Assume that you'll often have 8 spaces of indent on the left side, and the a ragged right edge of perhaps 6 characters, and you get 66 + 8 + 6 = 80. There's nothing perfect about it, but an 80-character width is basically what's generally comfortable for comprehension by the human eye.
The use of intermediate variables is something I'm conflicted about.
On the one hand, they can make code easier to reason about. Also, when using a crappy debugger that doesn't display return values you can more easily see what's going on. In some cases they make code that at least looks like it ought to run faster.
On the other hand, ditching intermediate variables makes refactoring more straightforward. You can immediately see the complete set of dependencies of a line of code and extract common bits of code into helper methods with less hassle.
In general I think I prefer the "cram a bunch of nested functions into one line" approach, but then that might be language-dependent (I mostly do Objective-C these days, and Xcode has a pretty smart automatic line-wrapping feature).
Lisp would be an extreme example where that's pretty much all you do.
An advantage of using intermediate variables is that they provide for a way to add comments without adding comments, in the form of the name of the intermediate result.
That helps in particular when you are calling several generic functions in a row. Names of local variables can contain a bit more of the terminology of the problem at hand.
> I would contend that readability generally has more impact on the success of a project than micro-optimizations and stylistic experimentation. If that means writing like a C coder in the 80’s, then so be it.
Excellent attitude. I need to keep reminding myself of this when I come up with them fancy oneliners again.
I'm sorry to sound like a fanboy, but this is one of the reasons I love Go: is the most readable language I know.
It is expressive, but free of magic, code says what it does, there is no hidden magic tricks, this annoys people used to other languages with more "features", but to me it is Go's greatest feature.
If the line consists of boilerplate code, I will allow it to go over 120-160 chars most of times. The idea is to just get that code out of sight, as nobody should have to read it anyway. If it's important, I will break the line up. If not - like a long exception message that gets constructed with bunch of context information - I'll let it grow out of window. It's not something you will need to look at, read and grok every day. And I am happy to have it out of sight most of time.
I break up lines when thinking about stepping through them in debugger (though javascript debuggers seem to be able to step statement by statement, not line by line).
We're so different, you and I. "Getting code out of sight because it's ugly" is such a foreign concept. If a code block is that ugly, it either needs to be made not ugly or put directly in the line of sight with plentiful comments.
"Shouldn't have to read it" !== "won't ever have to read it."
I agree completely with this, all code should be visible, but I still go well over 80 personally because I'm don't, nor will anyone likely edit my code on a 80 char terminal. When I was hacking on an IBM mainframe through a 3270 terminal, the 80 character limit made a lot of sense.
Why use the 80 char rule because of an edge case of some throwback editing javascript in a term that only allows for 80 characters? I mean, who does that?
Me. When I bring up the Netbeans editor, there is a red line down the right margin at column 80, and I'm not inclined to change that setting, although I sometimes type a few characters past it. This is a wise tradition, handed down from the tribal elders :-) I sometimes need to see at least a little bit of something else on screen besides your hideously wide code.
If you ever have to print out code, it makes a nice line size convention as well. Printing is becoming less common, unless you publish books, but it's still worth considering that it might be easier for the reader if the lines aren't mind-numbingly long.
Why do newspapers have multiple columns of text, when clearly they have space to go 14 inches or more across?
Almost forgot: if you need more than 80 columns, your routine is probably too long. Indicated by deep nesting, and/or variable names that need to be more than one or two English words because the scope and intent of the variables is not obvious.
I had a manager once who would seriously write 250-500 character lines of VB6. When I see code disappear off the right margin I get very nervous. You can hide a lot of functionality that way, especially if your language supports multiple statements on a single line.
I have worked with a strict 80 character rule, and I find that it usually causes worse looking code with excessive multi-line statements, poor variable naming and makes refactoring more labour intensive.
I have a soft limit of around 100 characters for C++, which is good for readability and still allows me to have two side by side editing windows.
Maybe I'm an exception, but I generally find code with LESS syntax to be more readable.
var makeAdder = function(x) {
return function(y) {
return x + y;
};
}
vs
makeAdder = (x) -> (y) -> x + y
Is anyone else like this? Do you think people are hard-wired to prefer one form of syntax to another, or do you think it's a "whichever you have more experience with" kind of thing?
I think I could get used to the second, but I'm not yet. At a glance, it looks like Erlang or Haskell, but that just shows you how little I know about those languages.
It's tough to strike a balance between brevity and familiarity sometimes.
because operators are just normal functions which happen to be infix by default. I think this is great--it's consistent, flexible and elegant at the same time. Not treating operators as something special makes the language simpler.
And to me that means absolutely nothing at first glance. It's much harder to read because I have to do all the work of translating it into the first example myself, and I have to do it when I was presumably trying to figure out what the code means. By the time I do I could have just written it that way in the first place.
The difference in style is similar to how the invention of punctuation, spaces, capitalization and paragraphs made writing much easier to read, and shorthand is annoying as all get out. It is certainly possible to misuse punctuation, spacing and paragraph breaks to the point where they make writing harder to read, but most often the writing wouldn't be good without them either.
What about the currying in the previous example? It made a function that had some value of X pre-bound to the addition operation, requiring only 1 operand/argument when called.
Totally aside, but interesting: 80 characters was not an arbitrary limit, at least not directly. It was the size of the IBM standard punched card, and the terminals that succeeded them. Famously, versions of COBOL (FORTRAN too?) well into the 1990s would not even recognize input past column 80 even though it had long since graduated to text files.
I still like to use 80 characters even today because it means I can fit two or even three pages of code side-by-side without wrapping. Great for merging.
Especially when a tab isn't 8 spaces worth and you don't have a near useless level of indentation from the start (e.g. Java's "class" scope), I rarely found a problem with 80 (or 78) character limits. Quite the opposite, usually there's something "wrong" with code that exceeds that limit (a "code smell", as the hip kids like to say).
Granted, quite often it's a "language smell", like Java or earlier C++'s verbose initialization forms and class terminology (AbstractFactoryImpl etc.). Other than that, it's often longer formulas or string building exercises, which usually could benefit from some temporary variables or printf-style format languages. If a statemenet has more than one operator and polysyllabic variable names, I generally prefer some variation of "let x be the overlong constant/class/descriptive name", e.g. "int x = DomainBasedStaticConfigurationSingleton.MAXIMUM_FROBNICATION_VALUE", instead of just adding up those monsters themselves. And being German, I'm actually quite used to silly compound nouns.
I don't know; I think it's fairly easy to hit that limit with some constructs like list comprehensions, particularly if they're inside a method (which cuts 12 characters with indention), yet remain readable. Something like:
[person.name for person in people if person.country_of_origin == 'Netherlands' and person.age > 30]
That's well above the limit, yet I still find it more readable than either a for loop that appends to a list or a map/filter (which would also have go through the list twice).
A longer/complicated list comprehension looks pretty similar to a (simple) SQL statement. And in both cases, there's really no reason why you couldn't put it on multiple lines, and they usually offer pretty good places to insert line breaks (e.g. "if" and "and" in your example).
But does it really improve readability? Personally, I don't think it does - in neither case; unless it's really pathological, but then it shouldn't all be forced into a single list comprehension.
Well, it certainly doesn't help readability if parts of a line are cut off or the editor has to do an ugly linewrap, spoiling indentation. So as long as it doesn't significantly decrease readability for those corner cases and the benefits outweigh the drawbacks, I'm all for certain code conventions.
Those are all fairly standard practices (except for the compile step which brings portability issues). I got the impression that the author has some underlying reason for this post that went unexplained.
If the lack of default parameters and style consistency are your main peeves with Javascript, it's faring quite well :)
Ironically, those are problems that CoffeeScript solves, yet it seems this guy would be the last person to try it.
I'll get into CoffeeScript when I feel that it solves more problems than it creates (it's very important for me to be able to debug raw source code in a language). My goal as a programmer is to reduce complexity, and I think it will take about 10 years for CoffeeScript to let me do that.
EDIT: Forget to mention, there's nothing in particular that caused me to write this. I just realized that, more and more, my style goes against what a lot of people do. I figured I'd document it for anyone interested in it. :)
Hi Jeremy. Dmitry's argument you mention, for instance, is questionable and not very popular. I think I can't point to what you're going against (vs "old style" coding), maybe some examples in the post could help.
On CS: you are already using a compile step that dynamically changes code, how more complex can it get? I have thousands of lines of CS in production and it never caused any more problems than JS. If you think of CoffeeScript as a tool to write Javascript, not a separate language, things go much smoother (you want to debug the javascript output, not the cs source).
Debugging compiled code is absolutely unpleasant. Fortunately, I only have to do it rarely. From what I can tell, debugging JavaScript that was compiled from CoffeeScript is a standard practice, and I simply don't want to pursue that. It's interesting how you describe CoffeeScript as a tool rather than a language, but in my opinion it is still a very leaky abstraction.
As I mentioned, I look forward to revisiting it when a standard toolset has matured.
There are lots of people who feel it (CoffeeScript) does indeed solve more problems then it creates.
If it actually does create more problems then it solves then a lot of people are just plain making a mistake by using it :) which I don't think is the case.
Plenty of programmers I know had a similar knee jerk reaction to the idea of CoffeeScript and have since decided it is a worth-while trade off.
Semicolons: it's too bad Netscape didn't choose to use colons instead (but then it wouldn't sorta look like C, would it).
As opposed to common dogma as this is, JavaScript is essentially a line oriented language, like Ruby, Shell Script, BASIC, Groovy or dBASE. OK, so it's more like Ruby, where the line will continue if it doesn't look done.
Had they used colons instead of semicolons, it would have been obvious that "oh, I'm using this punctuation to add another statement to this line", but of course, it's usually the null statement in JavaScript.
It's a shame JavaScript (and Ruby) didn't adopt the line continuation character convention (e.g. - backslash or ampersand) for incomplete lines. As it is, one might be best served by learning what incomplete statements look like, just in case, and alternately, where the parser might think your statement is shorter than you intended.
Yes, I add the semicolons at work to avoid the <<trivial criteria>> contest.
In Ruby, once you reach the end of a line, it is unambiguous whether the line is complete. You don't need to scan the next line to figure it out.
Ruby does support a line continuation character if the line is complete, but you want to continue it anyway.
foo = Struct.new(:bar).new("HI")
puts foo \
.bar
So in Ruby, the rule is: if you get to the end of a line and the expression is complete, the expression is finished. Otherwise, continue on the next line.
This is really nice for human-readability (and as a side effect, pasting code into IRB).
I use the Google style guide as well since it's required by my job and while I have learned somethings from it I'm not a fan.
80 characters? I never had that limit for the 27 years of programming proceeding using the Google style guide and it never caused me any grief. I find that naming things descriptively and an 80 character limit are at odds.
I admit it's kind of useful for side by side diff tools but in my previous 27 years of programming I never felt like "If only this code was 80 characters I could read the diff".
More importantly though, the Google Style guide is written by Java programmers to try to make JavaScript into Java, totally ignoring all the benefits of treating JavaScript like JavaScript. That has it's benefits, especially for Java programmers. They don't have to learn some of the cooler things about JavaScript. They can go on treating it like a traditional oop language. And they get static type checking.
On the other hand, all of these FP concepts are out
Are not allowed by the Google Style guide as well as many other JSisms.
Another nit, Google Style guides disallow formatting for readability except for comments?!?!
Allowed
var kStateRun = 1; // character is running
var kStateRunToWalk = 2; // character is transitioning from run to walk
var kStateWalk = 3; // character is walking
Not allowed
var kStateRun = 1; // character is running
var kStateRunToWalk = 2; // character is transitioning from run to walk
var kStateWalk = 3; // character is walking
Either lining things up makes them easier to read or it doesn't. Comments are not some exception. If lining up comments makes them easier to read then lining up anything makes it easier to read.
> 80 characters? I never had that limit for the 27 years of programming proceeding using the Google style guide and it never caused me any grief.
I didn't think that way until very recently, and then something occured to me: limiting things to 80 characters means you can fit more vertical strips of code on your screen without line breaks. On a 1920x1080 screen with a 6x13 font[1], I can split vim into 4 vertical strips each of which are 79 characters wide. It's not perfect, but it means that my screen is filled with code instead of whitespace. Keeping code width low is like dyanmic-range compression[2] for code.
>> I find that naming things descriptively and an 80 character limit are at odds.
> I don't. I use descriptive names for functions and short, concise words for variables (sometimes clear abbreviations)
That might work. Unfortunately abbreviations are forbidden by the Google Style Guide.
> As for lining up
my point still holds. Either lining up helps or it doesn't. If it doesn't help then lining up comments should not be allowed. If it does help, then it helps every where.
I find that naming things descriptively and an 80 character limit are at odds.
Agreed. 80 columns made a lot more sense in the FORTRAN days where variable names couldn't be more than 6 characters. Even in this article's example code, after doing the "right" thing of creating intermediate variables (debatable, as discussed in other comments), he still has to break the function call which harms rather than helps readability.
To be clear, I don't follow the Google Style Guide exactly, at least not for my open source projects. It's more of a jumping-off point that I then tweak to my liking. As I said in the article, it's not worth going into every detail of my style preferences (like spacing and naming), as I find that stuff pretty trivial.
If a style guide is making code less readable, I would argue that the style guide needs to be amended.
On a related note, breaking statements into multiple lines can screw with your VCS workflow immensely.
It's not a problem if you're doing something sensible like extracting nested function calls, but inserting newlines into simple statements will make tools like `git blame` a lot less useful.
I find that long variable names are usually a sign of design that needs improvement. For example, those names are highly repetitive and don't actually tell me how each of those variables is different from the other, which is the information I care about right that moment. By putting them into a function or prototype who's name communicates the commonality, say "getAllMax" on UniformVectors it could be just as communicative to say something like:
And I agree with that. "new" exposes too much implementation detail: it always allocates an object, and it's exactly the type specified, neither of which callers should normally care about. I much prefer how Python does it.
Actually, in Javascript you can preemptively return a value of a different type from the constructor instead of relying on the implicit `return this` at the end.
That said, I agree that the way "new" specifies the concrete type of the returned value is pure evil. In OO things should be typed according to their interfaces, not according to their concrete implementations.
It does but there are other ways to create objects (even using prototypal inheritance) in JavaScript that are pretty popular in the wild (Object.create and object literals with {} for example). The code behind this and the constructors, etc, would need to be rather different though (that is, you're right, you can't just drop new and expect it to work as-is.)
The (crazy but awesome) "unicode literals" feature in Python 3 means that your example is actually a valid statement:
Python 3.2.3 (default, May 3 2012, 15:51:42)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 放改型(势, 做改值(这._改订购, _.挑(态, 改函数名)))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '放改型' is not defined
Of course I didn't actually define a function named 放改型...
Though some are good suggestions for writing maintainable codes, I do not see a lot of opportunities to improve javascript from this.
The pieces I would like to have are a) optional arguments and b) strict type checking. They are actually syntactic sugar in a way, because you can get the same effect using typeoff function.
But restriction to 80 characters... would be definitely recommended as coding practice, but never be forced by the language!
I have always felt that scripting languages should stay clear of OO syntax largely. Try to do small files which are procedural. OO is for large monolithic modules - good to collabarate and manage complexity - scripting should stay where it needs to be - simple and standalone, no threading, but asynchronous where possible. This makes life easier for everybody.
I'm pleased that someone else favours a sensible line limit.
I stick to 72 columns for width and 20 lines per function body. The result has been very concise code that's easy to follow. Only exceptional cases such as heavy recursion have eluded the line limit.
If popular JavaScript projects wrote code with cleanliness in mind, maybe more people would take the language seriously.
> I don’t like JavaScript. I write an enormous amount of JavaScript — in fact I write it almost exclusively — but I don’t really like it as a language.
Why would you work "almost exclusively" in a language you don't like? There are plenty of opportunities on software with all sorts of languages.
Because I want make UIs and apps with open web standards, and JavaScript is the only practical language. CoffeeScript and other macro languages are cool, but currently there is no way to debug and step through the source.
I can't wait for the day that CoffeeScript has a robust debugger.
If debugger integration is a must-have feature for you, then fair enough. I'd make the opposite choice myself which is why the previous statement surprised me.
I thoroughly enjoyed this article. I'm always looking for ways to improve the readability and "share"ability of my code, and the author has provided several tips that I'll be taking forward. The part on strict-ish typing is brilliant. Very good read.
I liked the bit about using new. As he says, some people go with capitalizing their constructors, but capitalization is not enforced by the compiler. 'new' is explicit, it can't be anything but a new object.
If you are writing types in Javascript, you owe it to yourself to use webstorm, as it can do code completion in javascript (it can also do reasonable inference).
I am debating starting up a bot which just scans for stuff like this and auto-posts a reply of "Yes, this article didn't mention your favorite buzzword, and you must be incredibly perceptive and intelligent to have noticed this and pointed it out."
Why refer to CoffeeScript as a buzzword in this context? Coffeescript has gained popularity recently because it addresses some of the concerns about writing javascript raised in the post.
Coffeescript is not a buzzword, it's a relevant technology. Just because it's popular doesn't mean you should dismiss it, it's popular for a reason.
In Scott's defense, I think it's totally valid to bring up CoffeeScript (though perhaps in a more elegant way with a bit more info as to why it's relevant). It's possible the article's author was not aware of its existence (I think this is likely as CoffeeScript seems to address his main concerns about JS).
Even if Coffee isn't in use at the moment, if it provides some value it would be worth promoting within the organization. New technologies routinely pop up, and the onus of proving their worth ultimately lies on the developers, even if they aren't the decision makers when it comes to selecting which ones are adopted and which ones aren't.
For a couple decades, and not ending until the late 90s, most text terminals and text modes for graphics cards were 80 characters wide[1], and dot matrix printers also had an 80 character line length (plus margins) dating back to 80 characters per line punch cards from 1928[2]. If a line was longer, you had to scroll that individual line. To let your code be read easily anywhere including your own screen, you stuck to that line length.
1. http://en.wikipedia.org/wiki/Text_mode#PC_common_text_modes
2. http://en.wikipedia.org/wiki/Punched_card#IBM_80-column_punc...