5 ms·
Brief Video: Rewriting JavaScript into CoffeeScript
- jashkenas 15y agoFor more in this genre, see: http://www.screenr.com/xd0 http://www.screenr.com/xd0
- ecto 15y agoBut... why?
- deleted 15y ago[deleted]
- jashkenas 15y agoI'm not sure where you got that idea -- it's not at all true. "or=" is the same as "||=", and means: Assign the variable on the left to the value on the right if the variable is falsy. "?=" means: Assign the variable on the left to the value on the right if the variable does not yet exist (ie. is either "null" or "undefined"). Two different things, both useful.
- axiak 15y agoSince ?= looks so familiar, any chance of an elvis or defined-or operator in coffeescript? if a? then a else 0 becomes either a ?: 0 (if you like groovy) or a // 0 (if you like perl)
- stoodder 15y agoGotcha, thanks for the correction! I've removed my post. Could you clarify if or= still exists? I was reading the change log for 1.3.1 and I think I may have interpreted this line incorrectly "Conditional assignment of previously undefined variables a or= b is now considered a syntax error.". Thanks!
- natep 15y agoMy interpretation of your quote is that the feature is there, but if the LHS is undefined, then the error is caught by the compiler, rather than at run-time (what is the falsity of an undefined value?)
- stoodder 15y agoYea, you're correct. This has been one of those "duh" moments. Thanks for the reply!
- gps408 15y agoCan someone explain the 'same name key:value shortcut' feature?
- jashkenas 15y agoIt's a DRY thing. Often in JS, object literals assign their keys to values of the same name -- you'll see a lot of this: $.ajax(url, { data: data, contentType: contentType, success: success, error: error }); ... not so nice. So as a first stab, you can clean it up like so: $.ajax url, {data, contentType, success, error} ... but it's especially nice in the context of destructuring assignment, like for your Node.js imports, for example. {spawn, exec} = require 'child_process'
- gps408 15y agoNice. Thanks Jeremy.
- threecreepio 15y agoI both like and use CoffeeScript, but the video does show off one thing that i personally quite dislike about it.. Implicit returns (which I love in ruby..). When trying to port over some applications to coffeescript, I had to revisit a whole lot of my functions to add in an empty return; line after code like: test: (m) -> m(i) for i in this.set Since I didn't really expect them to build up and return arrays of the results of invoking m, which at times could result in a method that would generate gigantic arrays that I would subsequently throw away, killing my performance. I probably should have expected that, sure, and if you don't have to deal with too much data it probably won't matter.
- jashkenas 15y agoOut of curiosity ... if you love implicit returns in principle, then why would you dislike them in this context? Certainly, you need to keep in mind the return value of a function while you're writing it -- if you don't want to return any value, then just "return". And it's definitely something that you need to keep more in mind while porting JS than when writing code from scratch. But given all that, would you really prefer explicit returns in CoffeeScript?
- eaurouge 15y agoOut of curiosity ... if you love implicit returns in principle, then why would you dislike them in this context? I'll guess it's because speed is less of a concern when programming in Ruby. if you don't want to return any value, then just "return". Yes, but that leads to clutter and goes against one of the selling points of CoffeeScript. Previous discussions on this: http://github.com/jashkenas/coffee-script/issues/1401 http://github.com/jashkenas/coffee-script/issues/1401 http://github.com/jashkenas/coffee-script/issues/899 http://github.com/jashkenas/coffee-script/issues/899
- threecreepio 15y agoI hadn't actually looked at the issues list to notice that this and similar issues have already been brought up plenty enough, so, sorry about that. And I do like implicit returns, and they're one of the main reasons I'm using CoffeeScript in some projects. What I was trying to express was that I don't generally run into this issue in ruby because the similar looping constructs don't behave this way, and don't carry the same kind of unexpected side-effects: def test(lst) lst.each{|i|do_stuff(i)} end this method will return "lst" back to me, it won't create any new arrays of the do_stuff(i) results, the same goes for for/while loops, whereas: def test(lst) lst.map{|i|do_stuff(i)} end will return the block results. The key difference being that the map method always creates an array and returns it, even if I would have a return; after, so it is consistent. The only situation where I get into the problem is with looping, and after some time using CoffeeScript, only rarely, so it may just be one of those things you have to put up with. Still crops up occasionally after refactoring though. I would not want to get rid of implicit returns, and would far rather continue dealing with the loop problems than that. Would just love it if those weren't the only options.
- munificent 15y agoThis is very cool, though I personally find postfix flow control confusing to read. The postfix loop with destructuring is especially odd to me. As I read left to right, I see variables that don't exist "yet" until I get to the later loop clause. This is probably just a familiarity thing and I would get used to it, but compared to all of the other changes in the video which I think are pretty clean that stood out to me as a bit... iffy?
- jashkenas 15y agoAgreed. I think there's a bit of LOC-golfing at work here. That loop is more nicely written as: for {handler, context} in @events[topic] handler.apply context, args
- MatthewPhillips 15y agoI agree. I also find unless statements to be difficult to read. I use this pattern all of the time in my JavaScript: if(!foo) { maybeDoSomething(); return; } bar(); This lets me early exit, if needed, while letting the meat of the function not suffer from unnecessary indentation. The unless statement makes the early exit seem like the default action rather than the exceptional action it (hopefully) is.
- nxn 15y agoIs that code really valid CoffeeScript? Last I looked, and I admit that the last time was months ago, 'on' was a reserved keyword (an alias of 'true') and I had to do some quite ugly hacks to be able to have a method named 'on'. This may have been related to dynamically adding the method onto the prototype of some constructor rather than defining it in a class. Besides that, I still get feelings of discomfort when thinking about rewriting JS to coffeescript when knowing that the compiler will just write it as JS again. EDIT: Tried it. In this case it seems to works.
- zzzmarcus 15y agoYou can also cut and paste it into this site: http://js2coffee.org/ http://js2coffee.org/. It's not always perfect, but it will get you 95% of the way there.