18 ms·
Treating JavaScript like a 30 year old language
- hackNightly 14y agoI 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.
- jerbils 14y agoThanks! :)
- scottschulthess 14y agoDoesn't even mention coffescript
- ubernostrum 14y agoI 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."
- scottschulthess 14y agoWhy 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.
- arms 14y agoIt shouldn't have to. He may not have the option to write Coffeescript at his job, or he simply may not want to (for any number of reasons.)
- mrose 14y agoIn 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.
- antidoh 14y agoI 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.
- phleet 14y agoWell.. that's mostly true. You can get some pretty interesting results if you return something in a function invoked using new: http://wtfjs.com/2010/11/10/false-advertising http://wtfjs.com/2010/11/10/false-advertising
- tomjen3 14y agoIf 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).
- Kartificial 14y agoI just cannot wrap my head around the fact that readable code is considered boring?
- eru 14y agoIt's just a pattern of speech.
- AjJi 14y agoAFAIK, using 'new' is not a matter of preference. Omitting the keyword leads to different results. Am I missing something?
- MatthewPhillips 14y agoSome people think that library consumers shouldn't have to use new. Instead they should call a factory function (which itself calls new).
- phleet 14y agoHere's an argument in favor of not requiring library consumers to use new by the author of the Raphäel library: http://dmitry.baranovskiy.com/post/something-new http://dmitry.baranovskiy.com/post/something-new
- orangecat 14y agoAnd 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.
- ufo 14y agoActually, 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.
- shawndumas 14y agoif (!(this instanceof arguments.callee)) { return new arguments.callee(/* parms */); }
- ufo 14y ago
- kemiller 14y agoTotally 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. http://en.wikipedia.org/wiki/Punched_card http://en.wikipedia.org/wiki/Punched_card 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.
- mhd 14y agoEspecially 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.
- icebraining 14y agoI 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).
- 14y ago
- watt 14y agoI disagree with the point about 80 chars limit. 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).
- mattdeboard 14y agoWe'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."
- ThePherocity 14y agoI 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?
- mattdeboard 14y agoI mean even reviewing code on Github... if you go over 80 (or close to it, not sure the exact column count) it forces scroll. I dunno, it's just convention. I break at 80 cols.
- Roboprog 14y agoMe. 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?
- skrebbel 14y ago> 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.
- luriel 14y agoI'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.
- Terretta 14y ago"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. 1. http://en.wikipedia.org/wiki/Text_mode#PC_common_text_modes http://en.wikipedia.org/wiki/Text_mode#PC_common_text_modes 2. http://en.wikipedia.org/wiki/Punched_card#IBM_80-column_punched_card_formats_and_character_codes http://en.wikipedia.org/wiki/Punched_card#IBM_80-column_punc...
- kibwen 14y agoWhich 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. [1] http://programmers.stackexchange.com/questions/148677/why-is-80-characters-the-standard-limit-for-code-width#comment281684_148678 http://programmers.stackexchange.com/questions/148677/why-is...
- mhd 14y agoNote 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.
- samspot 14y agoOne of my favorite things about the 80 column rule is it makes it even more effective to split your window vertically.
- Xcelerate 14y agoMaybe 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?
- Roboprog 14y agoI 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.
- tikhonj 14y agoIn Haskell you could actually just do adder = (+) 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.
- roguecoder 14y agoAnd 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.
- Roboprog 14y agoWhat 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.
- josephg 14y agoThe 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.
- jerbils 14y agoArticle author here: 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."
- SoftwareMaven 14y agoProject 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.
- FuzzyDunlop 14y agoAgreed, 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.
- frugalmail 14y agoHave you taken a look at http://haxe.org http://haxe.org ? Seems like a good solution against javascript's flaws.
- Roboprog 14y agoSemicolons: 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.
- wycats 14y agoRuby and JavaScript are a bit different. 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).
- anuraj 14y agoI 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.
- greggman 14y agoI 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'd rather read maxCombinedUniformVectors = maxFragmentUniformVectors + maxVectorUniformVectors; than maxCombinedUniformVectors = maxFragmentUniformVectors + maxVectorUniformVectors; or maxCombinedUniformVectors = maxFragmentUniformVectors + maxVectorUniformVectors; 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 http://osteele.com/sources/javascript/functional/ http://osteele.com/sources/javascript/functional/ http://www.ibm.com/developerworks/library/wa-javascript/index.html http://www.ibm.com/developerworks/library/wa-javascript/inde... http://osteele.com/archives/2007/07/functional-javascript http://osteele.com/archives/2007/07/functional-javascript http://www.cubiclemuses.com/cm/blog/archives/000307.html/ http://www.cubiclemuses.com/cm/blog/archives/000307.html/ Even common JS concepts like encapsulation var ErrorLogger = (function(){ var privateErrorCount = 0; return { error: function(msg) { console.log(msg); ++privateErrorCount; }, getNumErrors: function() { return privateErrorCount; } } }()); 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.
- altrego99 14y agoThough 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!
- frankus 14y agoThe 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.
- Someone 14y agoAn 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.
- correctifier 14y agoI 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.
- mkmcdonald 14y agoI'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.
- rbanffy 14y agoWhen so many text editors let you collapse blocks of code, it's hard to persuade programmers to keep line-count sane. Isn't 72 columns a little bit restrictive?
- ricardobeat 14y agoThose 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.
- jerbils 14y agoArticle author here: 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. :)
- ricardobeat 14y agoHi 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).
- jerbils 14y agoDebugging 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.
- azakai 14y ago> 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.
- jerbils 14y agoBecause 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.
- azakai 14y agoIf 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.
- crazygringo 14y agoI'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.
- cabalamat 14y agoAnother advantage of an 80-char limit is that you can display two pieces of code side by side in separate windows.
- coldarchon 14y ago1 var sum = addNumbers('5', 10); 2 console.log(sum); // -> 510 "Whoops. If the client of this code assumes that addNumbers will do any typecasting for them, they will get unexpected results." This is not an unexpected result as variables in JavaScript need to be defined as numbers or they are treated as strings. Therefor 5+10 is a concatenation and 510 of type string is an expected result. If you don't know this basic stuff?
- vorg 14y ago> an 80 character line limit for code [...] eliminates the need to horizontally scroll There's other ways fit your first example within 80 chars: setTransformStyles(context, buildTransformValue(this._transformOrder, _.pick(state, transformFunctionNames))); How about?... 放改型(势, 做改值(这._改订购, _.挑(态, 改函数名)));
- kiwidrew 14y agoThe (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 放改型...