5 ms·
Coffeescript 1.9.0 contains a backwards incompatible change
- bmh100 12y agoI understand the pain of having changes that should be innocent leading to breaks in production. What is your strategy around testing for upgrades like this? JavaScript is not my area of expertise.
- striking 12y agoOftentimes, you'll already have written tests to make sure your logic works. Otherwise, you might just run your app in a test environment and make sure it doesn't immediately crash. (Because that's what CoffeeScript would do in this case, as far as I know.) Pretty standard stuff across the industry.
- deleted 12y ago[deleted]
- alessioalex 12y agoThe author of CoffeeScript also created Underscore. He did the exact same thing there: https://github.com/jashkenas/underscore/issues/1805 https://github.com/jashkenas/underscore/issues/1805 So bottom line: if you use CoffeeScript, Underscore of Backbone.js pay close attention to upgrades.
- pom333ss 12y agoThis is your punishment for using Coffeescript.
- pom333ss 12y agoWhy downvote?, Coffeescript is not even a language. Programmers who use this crap must suffer.
- skilesare 12y agoCoffeescript is an amazing tool that has allowed me to be 10x as efficient writing js code. ECMA 6 fixes a bunch of things that coffeescript makes really easy, but until the transpilers work as well as coffeescript, coffeescript still has a place. (From what I understand they are getting close and may have arrived)
- raverbashing 12y agoAnd what's the lost efficiency for hitting into incompatibilities between JS<>Coffescript, like the topic? JS seems small enough that you shouldn't have many problems in this matter, but there's usually some warts
- conanbatt 12y agoThere is a cost, but its without a doubt heavily outbalanced by having half the code. The JS it generates is a tad ugly, but you save way more time, clarity and readability than with vanilla JS.
- skilesare 12y agoThis is the first issue like this that I've seen. I actually didn't know about that particular syntax. I've been doing @example inside my code when I need 'this'. Coffeescript is just coffeescript so there really aren't any incompatibilities. The only gotcha that I've hit a few times was the automatic returns that are inserted. Sometimes you have a chain of functions that requires a true to be returned from a function and if you don't do it explicitly, coffeescript will return a falsy value.
- coldtea 12y ago>Coffeescript is an amazing tool that has allowed me to be 10x as efficient writing js code. I seriously doubt the 10x number, as it's just some syntactic sugar, and not that advanced at that, and comes with its own issues. Actually, I (and Fred Brooks, in "No Silver Bullet") don't think there's any technology that added to some programming language will make you 10x more productive. Maybe having an editor compared to writing to punch cards.
- AngrySkillzz 12y agoYou very clearly created this count to troll; exists for less than a day, only comments are trolling Coffeescript and D.
- bmh_ca 12y agoI was burned by this as well. The breaking code would look like this: ``` a = (@arg) -> console.log(arg) # Used to print arg. # Now needs to be: console.log(@arg) ``` The problem was particularly exacerbated on our end by using `coffeeify`, which includes the latest CoffeeScript - so one could not easily pin to a particular version of CoffeeScript (i.e. 1.8.x). This brings into question, for me, the decision making process for CoffeeScript. So the migration begins. Contrast, lodash which just had a bunch of backwards-incompatible changes. They changed its version from 2.x to 3.x, so we all head a heads up. Lots of things broke, but we knew to look for them.
- untog 12y agoWhy were you referencing a variable that doesn't exist? Your code shows a bug in CoffeeScript, which was fixed.
- davej 12y agoIt's interesting to note that the current #1 story on Hacker News is io.js 1.3.0. And the current #1 comment on that story is wondering what the reason is behind the version jumps in quick succession without much in the way of new features (1.0.3->1.0.4->1.2.0->1.3.0). These two stories nicely sum-up the romantic vs semantic versioning debate.
- michaelmior 12y agoI think even when using semver, you should lock down your dependencies (e.g. npm shrinkwrap). My approach is often to periodically delete npm-shrinkwrap.json, Gemfile.lock, composer.lock, etc. and then install updated dependencies and thoroughly test things. You still get the benefit of a reasonably loose specification of what versions of dependencies you expect to be compatible with, but additional security in knowing that you won't be surprised by unexpected breaking changes.
- meesterdude 12y agoES6 is pretty good - I'd rather write with that than coffeescript.
- bryanlarsen 12y agoHint: if a project claims to be following semver and the major number is small, the project either is very young, not being actively maintained or they're probably not actually following semver. All three are red flags. Library maintainers shouldn't be afraid to bump the major.
- Zr40 12y agoAccording to [1], the previously accepted syntax was never documented as being valid. That means that code affected by this change was relying on undocumented behavior. [1]: https://github.com/jashkenas/coffeescript/issues/3819 https://github.com/jashkenas/coffeescript/issues/3819
- xtrumanx 12y agoWell that adds a much needed bit of context to the conversation. Someone decided to use undocumented behaviour in a production application and got bit. Worded as such it doesn't make Coffeescript to sound so ridiculous.
- jrochkind1 12y ago"decided" implies they knew they were using undocumented behavior and chose to do it anyway. The use of the word 'undocumented' also implies that unless a behavior is explicitly mentioned in the documentation, it should be considered 'private' and 'subject to change' -- also not a safe assumption with many projects, whose documentation is far from completely covering all intended behavior.
- xtrumanx 12y agoSorry, I'm not a Coffeescript user so I'm familiar with its idioms. I looked up the Coffeescript website and it says: > As a shortcut for this.property, you can use @property. It also said that since March 2010 according to the Internet Archive's Wayback Machine. Why did this fellow decide to use `property` instead? I don't know but I wouldn't hold this specific situation against the Coffeescript team. But that's just like my opinion, man.
- davidbanham 12y agoCompletely agree that the particular bit of code shouldn't have been relying on that functionality. A totally reasonable response would be "Oh, sorry, I had no idea people were using that in that manner." Fine, fair enough. But! It was known that people were relying on that behaviour and it was mentioned in the changelog. That is a big point in favour of Jeremy as a package maintainer. Not only does he know how his code should be used, but he has an understanding of how people are using it in the wild. That's wonderful and praiseworthy. Where I get grumpy is that this was seen as a significant enough event to mention to the humans who happen to be reading the changelog. Yet, it wasn't deemed appropriate to tell all of the computers that are installing dependencies about it.
- artursapek 12y agoI've written a big project in Coffeescript in the past and it was teremendously more fun than it would have been to write in vanilla JS. However with ES6 around the corner I think it would be a mistake to start any projects in Coffeescript now. We just adopted ES6-to-5 translation via Babel[1] at work and people are really excited about it. [1] http://babeljs.io/ http://babeljs.io/
- yoshuaw 12y agoThis reminds me of this excellent ode to exotic versioning schemes -- http://sentimentalversioning.org/ http://sentimentalversioning.org/
- yoshuaw 12y agoFrom the backbone archives (linked in the article): https://github.com/jashkenas/backbone/issues/2888#issuecomment-29076249 https://github.com/jashkenas/backbone/issues/2888#issuecomme...
- thinkpad20 12y agoI'm not sure why this was made into a blog post and put on HN. This kind of thing seems more suited to a bug tracker. Mistakes happen sometimes; report them and let the developer community take a look at them. That's the advantage of open-source.
- kevincennis 12y agoBut, like... Why did you update to a new version of Coffeescript and not know about this bug before it made it to your production environment? I agree that Coffeescript should probably just use semver. But they don't, and you have no control over that. What you do have control over is when you update your dependencies and whether or not you validate releases before deploying to production. It seems a little disingenuous to act like this is entirely Coffeescript's fault.
- yclept 12y agoalways pin your dependencies
- lmm 12y agonpm has a substantial amount of valuable automated tooling that assumes semver. It is the standard of that community.
- kevincennis 12y agoYeah, I completely understand that. I work on big Node apps every day. But anyone who's had an app in production for very long learns pretty quickly that you you use "1.8.0", not "^1.8.0" if you don't want things to break.
- Touche 12y agoThere's a lot of value in being able to receive bug fixes without explicitly knowing about them and manually upgrading. Most people do not have enough time to do this, we get paid to ship features not fiddle with developer productivity tools. This is why npm shrinkwrap exists.
- davidbanham 12y agoI didn't update the deps. This situation arose when a new server was spun up. Chef dutifully checked out all the various repositories, installed the deps, etc etc. npm saw that there was a new version of a dep that was advertised as being backwards compatible, so it installed it. Then things broke. The prevention to this is npm shrinkwrap. Had that been used on this particular service, it would have continued installing coffeescript 1.4.0. It also would have missed out on any security patches, bugfixes or performance improvements that may have happened in the meantime.
- iamdanfox 12y agoI've greatly enjoyed writing CoffeeScript, but am concerned that over the long term, it will fall behind javascript in terms of feature support. The [Babel][1] transpiler (formerly 6to5) and tooling like Facebook's typechecker, [flow][2] have large teams and a rapid pace of development. I don't want to miss out on cool features like generators, let/const, etc just for CoffeeScript's lovely bracket-less code. [1]: https://babeljs.io/ https://babeljs.io/ [2]: http://flowtype.org/ http://flowtype.org/
- feedjoelpie 12y agoDitto. I don't think the CoffeeScript philosophy as it stands will ever have it keeping up with the pace of JavaScript proper at this point. Within the next year, I think our company will be migrating back to the land of curly braces. The charms of CoffeeScript just aren't worth missing out on all the great stuff coming to JavaScript as of late.
- slindsey 12y agoPeople can do whatever they want with their version numbers. But I like to follow the Apache Version Numbering (http://apr.apache.org/versioning.html http://apr.apache.org/versioning.html) where backward compatibility is inherent in the number. Any change that breaks something requires a major version number change.
- flipp3r 12y agoEven if it would use semver, you should not auto-install or update packeges in your production environment without having it tested first. Semver is just a promise other people are making, and in production you shouldn't rely on that IMO.
- jashkenas 12y agoCoffeeScript doesn't follow "Semantic" versioning. Most projects that claim to follow "Semantic" versioning actually don't. Take, for example, the other news at the top of the front page, Io.js 1.3.0 — a minor version bump that should include zero breaking changes to the public API. And yet, 1.3.0 "broke" the way that urls are resolved with regards to trailing slashes: https://github.com/iojs/io.js/pull/278 https://github.com/iojs/io.js/pull/278 If you follow SemVer — and I don't think that Io.js should, or have to pretend to — this must be yanked, and re-released as Io.js 2.0. Ironically, the behavior being complained about in this post relates to how CoffeeScript decides to name internal compiler variables. This is not something that has ever been part of the public API — and is something we can (and might) change at any point. We've changed it in the past. Breaking changes in your API are a good thing — when the new way is better than the old. But this isn't one of them. For more on SemVer, and why you should resist giving in to its fascist attempt at world version domination, see: https://gist.github.com/jashkenas/cbd2b088e20279ae2c8e https://gist.github.com/jashkenas/cbd2b088e20279ae2c8e I get that SemVer is an attempt to address dependency pain — but it's woefully inadequate, reductive and dangerous. We can do better.
- deleted 12y ago[deleted]
- kenperkins 12y agoI've felt for quite a while that we could have had a 4 octet semver that allows for a first octet romantic version while the others are proper semver. For example: io.js version 1.2.0.0 instead of 1.3.0. It would still be machine readable, but allows a human component (romantic version) to precede. Thoughts?
- dragonwriter 12y agoFirst, why? Semver is for humans -- it puts a defined meaning to version numbers so that humans can gain useful information from them (this also is useful for automation, because once there is a clear unambiguous meaning, workflows, automated or not, can use that meaning as input.) The "romantic" version is pure noise that adds no information, for humans or machines. Second, why octets specifically instead of numbers (or, more precisely, non-negative integers) more generally? Is there any value in restricting the range of components of a version number to 0-255?
- coderzach 12y agoMaybe semver needs a fourth "Vanity" version, that you can increment when it "feels right". i.e. Backbone 1.43.3.1
- gerjomarty 12y agoThe problem we had when trying to push semantic versioning of our app to the rest of the business internally was mostly the fact that breaking changes necessitated a change in the major version, but the business and marketing side wanted control of when a major version could be released. I can see their point, because going from, for example, 1.1.0 to 2.0.0, a user might well expect lots of new features, or at least a significant UI change, and not just "it looks and does the same except for one or two breaking changes". The compromise was to have an architect's vanity number at the front of the Semantic version, so VANITY.MAJOR.MINOR.PATCH
- jrochkind1 12y agoThe other option is simply _not releasing breaking changes_ until you are ready for a 'major' release with new features. Sometimes this can be a pain, but every choice here can be a pain, the question is how much pain, and for whom (consumers, developers.... marketting people).
- Touche 12y agoThen don't advertise the version number. Give your big releases a flowery name and be done with it.
- epidemian 12y agoWhat's up with these kind of childish slander of OSS projects being upvoted to the top? Anyway, funnily enough, this change was not only rectified on CoffeeScript 1.9.1, but it was also a change that only affected code that relied of the names of compiler-generated variables. foo = (@bar) -> # Bad: "bar" is not declared anywhere console.log bar # Good: the parameter is "@bar", so that should be used instead console.log @bar Relying on a "bar" variable existing inside that function body is no different from relying on an "_i" variable exiting inside a look like: for a in arr console.log "the index is", _i ... which, BTW, would also break if upgrading to CoffeeScript 1.9, because the compiler-generated iterator variable would now be called "i" :) Update: i misinterpreted something. What was rectified in CoffeeScript 1.9.1 was the addition of an "_at_" prefix for the generated parameters of `(@something) ->` functions, which broke Angular's dependency injection mechanism when using it like `(@$someAngularThingy) ->`. You still can't access the auto-generated "bar" parameter in the first snippet. If you access a "bar" variable inside that function, the auto-generated parameter is then named "bar1", which is the Right Thing to do :D
- ufo 12y agoDid the first example at least give a warning or did it silently succeed?
- epidemian 12y agoAlas, no, the compiler does not warn about that. I don't know if it should though, as accessing a "bar" variable inside that function might be legal if bar was assigned as global variable, which the CoffeeScript compiler has no way to track.
- ufo 12y agoAh, thats unfortunate... I do think giving a warning should be possible though. Coffescript has some weird variable scoping rules but the scopes are still static so the compiler you should be able to detect if you are accessing one of the compiler-generated internal variables.
- kibwen 12y agoI'm interested in this story because Rust is a language that does intend to follow semver, which AFAIK is something that has never been attempted by a programming language. As of yet it hasn't been forced to bump versions thanks to clauses 4 and 9 of the semver spec, but that will change as of the 1.0.0 release on May 15. Before that date I highly anticipate a document from the Rust developers that will attempt to lay out precisely what does and does not constitute a "breaking change" in order to avert the situation that has arisen here.
- davidbanham 12y agoOr they'll just pull on their grown-up trousers and bump the damn major every time there's a breaking change.