The Changelog: Software Development, Open Source - CoffeeScript and JavaScript (Interview)

Episode Date: July 23, 2010

Wynn and special guest host Micheil Smith sat down with Jeremy Ashkenas from DocumentCloud to chat about CoffeeScript, a cool language that compiles to JavaScript....

Transcript
Discussion (0)
Starting point is 00:00:00 This is John Resig, you're listening to The Change Log. Welcome to The Change Log, episode 0.2.9. I'm Adam Stachowiak. And I'm Winn Netherland. This is The Change log. We cover what's fresh and new in the world of open source. If you found us on iTunes, we're also on the web at the changelog.com and we're also up in GitHub. Yep. Head to github.com forward slash explore. You'll find some training repos,
Starting point is 00:00:35 some feature repos from our blog as well as the audio podcast. And if you're on Twitter, go to twitter.com forward slash change log show and and hit the follow button. And also follow Adam Stack. And I'm Penguin, P-E-N-G-W-Y-N-N. Fun interview this week with a guest host, Michael Smith from Australia. We sat down with Jeremy Ashkenaz from Document Cloud. You may remember from episode five. Yeah, episode five.
Starting point is 00:01:01 Yeah, that was a lot of fun. Talked about, what did we talk about in that episode? Underscore.js. You don't have the episodes memorized? Oh, my bad. Yeah, that was a lot of fun. Talked about, what did we talk about in that episode? Underscore.js. You don't have the episodes memorized? Oh, my bad. I'm sorry. There's, what, 29 of them now? There you go.
Starting point is 00:01:11 Talking about CoffeeScript this time. So back to JavaScript. We're big fans of Haml and Sass, and those are preprocessors to write HTML and CSS. CoffeeScript's kind of the same thing for JavaScript. It allows you to write JavaScript in another way, provides some additional syntax, time savers, and enhancements to output JavaScript to either use in the browser or the server side
Starting point is 00:01:34 with something like maybe, I don't know, Node.js. Cool. Are you using this anywhere? I'm using it in Titanium personally, which we've talked about, I believe, episode 7-ish or something. Yeah? You don't know the episodes when? I don't. I don't have them re-memorized. So, yeah, I'm using it to do some iPhone and iPad stuff lately. Very cool. Well, you're a very out-there kind of guy, always mixing a bunch of products into the mix of your work.
Starting point is 00:02:00 So this is kind of fun. So is it fun to work with? It is. You know, I'm a mash-up of design and development, and my projects are a mash-up of every fun So is it fun to work with? It is. You know, I'm a mashup of design and development, and my projects are a mashup of every fun toy that I want to play with. Cool. And so Jeremy gives us a lot of good nuggets in this interview? He does. Some insight into the design of the language and kind of the inspiration behind it
Starting point is 00:02:20 and some of the languages he ripped off from to provide us this cool new syntax. Ripped off. All right, cool. So it's a good interview, I suppose. Let's get to it. All right, man. All right, we're joined this afternoon by Jeremy Ashkenaz from Document Cloud. I'm going to talk about CoffeeScript. I also should mention we've got a guest host today, Michael Smith from Way Down Under.
Starting point is 00:02:49 Say hello, Michael. Hi. So, Jeremy, I want you to introduce yourself to the folks that maybe didn't catch episode 0.5 that was Document Cloud and underscore JS? Right. So it's been, I guess it's been a little over six months since I talked to you guys the first time about the stuff that we were doing with Document Cloud. But so basically I'm working on this project that is to make an online repository of primary source documents
Starting point is 00:03:19 that news organizations contribute and the journalists get to use to do their document-based research. And when they're done writing their story, they put the documents online alongside the story for extra context. And so that's a large JavaScript application. And we're doing a ton of client-side JavaScript to show the entities that are present in the documents and to show the dates that are present on the timeline.
Starting point is 00:03:38 And I've been using JavaScript heavily on the client side for a long time and I'm very excited about what's going to happen when we can start using the same language on both the server side and the client side. And not only is it going to be the same language, but it's also going to be a very nice language and it's going to be a very fast language. And so I've had this kind of idea kicking around in the back of my head for a long time about what would JavaScript look like if it could look like anything you wanted it to look like. If it hadn't been basically stuck in a place where you had all the browsers having to agree on what JavaScript would be in order to make any progress,
Starting point is 00:04:13 if it had been a language that had evolved, what could it look like? So that's kind of what CoffeeScript was, and it was just for fun. And it still is. It's for fun. I'm not trying to sell it or to build a business out of it or to persuade you to use it. It's a thought experiment about what JavaScript could look like, potentially. And so, yeah, that's what we're going to talk about today. Let's talk about what it looks like. So what is the syntax influence of CoffeeScript? There's actually been a whole bunch. It's been kind of fun.
Starting point is 00:04:39 So my own background is mostly doing Ruby and JavaScript stuff with a little bit of Java. But CoffeeScript, I guess people think that it looks a lot more like Python than it does like Ruby these days. So it's got basically the regular simple scripting language syntax that you're used to, but it uses significant whitespace to limit blocks. So if you have a function or you have a class or you have an array or a switch statement or an if-else, you use whitespace and indentation to delimit the start and the end of that. And, of course, you can wrap it in parentheses if it's not totally clear what you're up to.
Starting point is 00:05:11 But there's also been a strong bunch of contributions from the functional programming community and from Haskell in particular. So there's been a whole bunch of Haskellers who have come on and have added features and have contributed both syntax and implementation. So I'd say there's a big strain of that in there as well. Okay, so since it compiles down to JavaScript, is there anything that you support in CoffeeScript that you don't actually support in JavaScript
Starting point is 00:05:38 or things that you can't sort of get access to because you're cross-compiling? Right, so an important thing to mention here sort of get access to because you're cross-compiling. Right. So an important thing to mention here is that CoffeeScript is a very limited language. It's not like you have complete freedom. You're not working with C. You're not working with assembly. You can't do anything you want to. You can't implement new constructs or new semantics very easily because it's a source-to-source
Starting point is 00:06:04 language. And not only is it source-to-source, but we're trying to keep the compiled JavaScript very clean and very readable. And in a perfect world, if we had everything worked out correctly, then the JavaScript that gets generated by the CoffeeScript compiler would be the code that you would have written anyway if you had done it by hand or something very close to that. So that's our goal.
Starting point is 00:06:24 And so because of that, there's a lot of things that we can't implement. A very simple one that has actually come up several times before has been indexing into an array. It would be great in JavaScript if you could index into an array with a negative number and get the value off the end. So instead of having to do array.length-1 to get the last element, you could just say array-1 and get back the final one. But that's something that we could support naively in CoffeeScript,
Starting point is 00:06:50 you know, if you actually use a literal number. But because you could pass a variable in as the index or a function in, there's absolutely no way for us to reliably do negative array indexing without actually changing the runtime, which we can't do. So that's just a very simple example of a tiny, tiny feature that would take two seconds if we had access to the runtime, but we don't, so we can't do. So that's just a very simple example of a tiny, tiny feature that would take two seconds if we had access to the runtime, but we don't, so we can't implement it. Do you actually need to learn JavaScript to write CoffeeScript, or can you just learn
Starting point is 00:07:13 CoffeeScript and forget about the JavaScript? Right, I mean, so that's more of a documentation question, I think, than an actual code question. So you definitely could learn just the CoffeeScript semantics which are slightly different than JavaScript and I can get into what those differences are in a second but right now the documentation is basically a list of the ways in which it differs from JavaScript
Starting point is 00:07:35 you're using the JavaScript runtime JavaScript functions behave the same way numbers behave the same way and basically all the semantics are JavaScript semantics. So, yeah, so right now it's basically, you know JavaScript, here's a cleaner way to write it is the idea. You know, I'm a big fan. I'm using it in a couple of projects now.
Starting point is 00:07:55 And when I explain it to folks that haven't seen it, the example that I give is it's, you know, it's Hamill istml and sas is to css coffee script is to javascript is that a fair statement um i'm not sure actually how fair that is because i think the interesting thing about that comparison which of course has been what it's been since the beginning um is that you know with with css and with html you have basically static languages and you're writing abbreviations that expand into larger formats and i think with something like coffee script you're actually compiling into programming language, it goes a little bit beyond that, because you can actually start to change the semantics of the code and change the way you would have written things. It's not just a one-to-one expansion. You can actually start
Starting point is 00:08:36 to write things in a little bit of a different way. So to get into that a little bit, there's kind of, I think, three core aspects to CoffeeScript. There's the syntax changes. So at the basic level, it's a cleaner, you know, you have to type less. You don't have to type as many parentheses. You don't have to type as many semicolons or brackets just to write what you would have written in JavaScript. The second aspect of it is that there's semantic cleanups. So the core thing there is that everything is an expression in CoffeeScript. And we try to make every function returns a meaningful value. Every if statement or switch or try catch is an expression that can be used as part of a larger
Starting point is 00:09:16 computation. There's no difference for the most part between statements and expressions. So a lot of work has been done there, basically, as you go, as the nodes compile, as you have the compiler that's turning your code into tokens, into nodes, into JavaScript, to say if you're using the result of a particular statement, then that statement gets converted into an expression in JavaScript, and so you can use it. So there's been a lot of effort there, and so you can use it. So there's
Starting point is 00:09:45 been a lot of effort there, and that's an example of a semantic cleanup. There's a couple other ones like switch statements, which don't work very well in JavaScript unless you're using strings to compare on, work on any object in CoffeeScript because you compile them into if-else chains instead of switch statements, and things like that where the statements don't actually work the same as they would in JavaScript. So that's the second aspect of semantic cleanups, and then the third aspect is bonus features. So I thought it was really cute in the last presidential campaign when John McCain started talking about goodies in legislation.
Starting point is 00:10:15 So I think of the bonus features as the goodies that you get alongside with CoffeeScript. And so things like that are the array comprehension. So instead of having to write out your explicit for loop, you can do a comprehension over an array and get back the list of values. And so that takes care of mapping and filtering and reducing, actually. And you also get range comprehensions and object comprehensions, too. So things like that are bonus features. And the existential operator and splats and all these goodies we can talk about. about so those are the three parts the syntax the semantic cleanups and then the the goodies okay so with these goodies um you're obviously adding on things like different for loops and
Starting point is 00:10:57 things like that are you following the echema script 5 specifications when designing those, or do you follow some other sort of standard? So in terms of extra features, so there's ECMAScript 5, which we now have since this fall, and all the code that, and we've been, yes, we've been influenced by ECMAScript 5, but even to a large extent ECMAScript Harmony. So there's this great wiki with all the suggestions that were in ECMAScript 4ony. So there's this great wiki with all the suggestions that were in ECMAScript
Starting point is 00:11:25 4 and didn't quite make it out, you know, when ECMAScript 5 came over and took and made it a much more minimal language than the next version of JavaScript was going to be. There's a lot of great suggestions for things that they wanted to do that aren't implemented yet in this ECMAScript Harmony wiki. And so we've taken a lot of things directly from there where we can and where we think that it makes sense so um the i mean for example the syntax for i'm not sure this is on the wiki but the syntax for splats for doing variadic arguments where you can have a couple um positional arguments and then a splat that soaps up the rest of the arguments to a function or you could pass in a variable number
Starting point is 00:11:59 of functions into a sorry a variable number of arguments into a function without having to use apply um the syntax for that with the triple dots was suggested by Douglas Crockford. And another piece of syntax that we took from ECMAScript 5 is a string interpolation. You can look at the proposal they have on the wiki right now, and that's very similar to what was proposed for ECMAScript Harmony, where you can interpolate naked variables just using a dollar sign into a string, or you can use a dollar sign with brackets and have arbitrary expressions interpolated into a string. So, yes. Going off the usage and implementation of splats in JavaScript, or in CoffeeScript,
Starting point is 00:12:39 now that you've got these extra language features, it's doing a lot of behind-the-scenes work to make them actually work in JavaScript. So one thing that I noticed when I first saw some CoffeeScript was actually that the developer sent me the compiled JavaScript when I was trying to help them out and try and figure out what their problem was with it. Now, of course, I couldn't actually read the JavaScript that I had compiled a fair bit because there were so many things that were being done behind the scenes. And I couldn't say, change these couple of lines, because he wasn't actually writing those few lines. Is cross compiling from CoffeeScript to JavaScript adding a barrier in the debugging process? Yes, so absolutely. Anytime you have a source-to-source translation, there's going to be a barrier in the debugging process.
Starting point is 00:13:28 And so the way it's worked out in practice is our tactic, instead of building a special CoffeeScript-only debugger, has been to make the generated JavaScript as readable as we possibly can and use whatever tricks we can to make it as readable as possible. So, for example, if you do compile a CoffeeScript file to JavaScript, you load it in a browser, and you get an exception in the browser, it's going to give you the line number of the JavaScript and not the line number of the CoffeeScript.
Starting point is 00:13:52 And that is the single biggest problem with figuring out and debugging right now. You have to keep your JavaScript files handy and go look up what's happening and then see where that occurs in the CoffeeScript and fix it. And I thought it was going to be a larger problem personally than it has been for me. I haven't had too much trouble with tracing back
Starting point is 00:14:09 and figuring out where things are going wrong. But from a beginner's perspective, if you're just getting started with it, it certainly would be more daunting. So I think what you might have been referring to are our use of temporary variables. So we do have to put in some temporary variables to do things like convert a comprehension,
Starting point is 00:14:28 a one-line array comprehension in CoffeeScript into the equivalent JavaScript. You have to use a temporary variable for the memoized array where you're caching all the result values before you turn the computed result of passing the function through the array. So you'll get things like that where you'll have a variable with a name, usually underscore A, underscore
Starting point is 00:14:46 B, underscore C, a temporary variable that has no equivalent on the CoffeeScript side. And so before you're familiar with what that is doing, then yeah, it wouldn't make any sense. With those temporary variables, would it make more sense to assign them as an actual
Starting point is 00:15:02 meaningful value? As a meaningful name? Yeah, yeah. So rather than underscore A, actually have it, so it's, say... Underscore results? Arguments length or something like that. Sure, we could do that. The problem is then you have name clashes
Starting point is 00:15:18 with anything that's in external scope that might already be defined, unless you happen to have a function wrapper around that. And we don't necessarily know what's in external scope that might already be defined unless you happen to have a function wrapper around that. And we don't necessarily know what's in external scope because you could be including other scripts onto the page that could be having things at the global level. So that gets a little bit tricky. It might actually be a worthwhile change to start doing underscore meaningful name and then if something's already declared that we can detect to make it a double underscore or add a one after or something like that. Because right now we do have a way of seeing, in the particular file you're compiling, of seeing what's in scope, which is how CoffeeScript scoping is handled for you.
Starting point is 00:15:58 You don't have to use var to declare a keyword in CoffeeScript. So we could take advantage of that probably to do better with meaningful names for those variables. Getting back to the goodies for a moment, two that drew me in were your approach to classes, inheritance, and also for function binding. Could you talk about those two features for a moment? Sure. So with classes, the idea is that this has actually been very controversial because people, you know, when you talk about classes in JavaScript, and of course, a lot of people who do significant work
Starting point is 00:16:29 with prototypes and with inheritance in JavaScript, you know, will yell at you if you have something called a class. So there's a big argument about whether we should call it class or whether we should call it proto or something else, to which my answer has always been that if you look at any amount of JavaScript code that uses prototypes to do inheritance, then they always work in classable patterns, regardless of whether you call it a class or not.
Starting point is 00:16:53 You always have a base object with a prototype, and you always make many new instances of it with different data. And so calling it, you can call it whatever you want, but I'd say call it a class just because that's what it is. So what we're trying to do here is to make it easier to work with prototype chain because it's not very easy to correctly set up a prototype chain so that you can have more than one level of inheritance without it breaking and with having the instance of operator working correctly. And being able to call super efficiently is one of the most difficult things. And so usually if you override a function, you want some way to reference the base implementation so that you can run that and then subclass it, and then do your specialized overrides on that function. And it's very, very difficult with regular prototypes to call super in JavaScript.
Starting point is 00:17:40 You have to know the name of your parent, and you have to go look at their method, and you have to apply it on your current object. And so CoffeeScript is trying to make that easier for you. So we use a variant of the Google Closure Libraries. I think it's called goog.inherits function to do the subclassing. So it's about, let's see, it's about five lines of JavaScript that actually makes the child class. And then anytime you call super within a method inside of the subclass, it makes a direct reference to the parent class for you. So you don't have to write it out by hand and performs very well for that reason.
Starting point is 00:18:16 So function binding is another problem that tends to be a brain bender for new JavaScript developers. Right. So talking about function binding, we actually used to have more support for function binding developers. Right. So talking about function binding, we actually used to have more support for function binding in the language, but it was decided that instead of having kind of a cryptic operator for binding functions directly, we would make that more of a standard library thing,
Starting point is 00:18:35 you know, because you should really be able... Really, binding should be... And I guess maybe in some future version of ECMA script, it will be, but it should be a method on a function object. You should be able to call function.bind and pass in the context you want to bind it. So what we have right now is basically the syntax for defining a function in CoffeeScript looks like this. You have your arguments, you have an arrow, and then you have your function body on the right-hand side. And the function body can be many lines.
Starting point is 00:19:01 It can be indented. So arguments goes to you know computation and it's a it's a regular little sort of ascii arrow as the as the function syntax but if you use a fat arrow with like the hash style arrow if you're familiar with ruby with the equal sign and the and the arrow the hash rocket as we would call it in ruby exactly hash rocket there you go use a hash rocket instead of a instead of skinny arrow. You get a function that's bound to the current object. So basically anytime you're doing something fancy with jQuery or you have an AJAX callback and you need to have your function stay bound to the current object so that you can reference everything else,
Starting point is 00:19:38 you can use a fat arrow to make sure that it stays bound. And it works the same way in classes. If you have a method on a class, you're going to pass that to a callback or pass that to something async. You can define that with a fat arrow. And that means you'll always stay bound to the instance of the class that you're creating. So you don't have to worry about creating a special wrapper function when you're ready to go do that callback. So that's a little convenience. What about when ECMAScript 5's bind is natively supported on functions. That's going to be a wonderful day.
Starting point is 00:20:08 So there's been a lot of requests and talk about adding things like getters and setters which are starting to get better supported to the CoffeeScript syntax. And that would be fantastic. So taking the function binding example, when the day comes that bind is supported across all the browsers and you can rely on it, then we could switch our implementation to actually use Bind and, you know, all your code would still work across all browsers like it had before and would now just work in a better way. And I think in general, we would hope to do that with ECMAScript features that start being supported.
Starting point is 00:20:50 So Jeremy, are you using CoffeeScript on the client side or the server side so I've been using it for a couple little fun projects and for some art projects I've been using it with Canvas a lot because that's been a ton of fun to take you know old processing sketches and to do in CoffeeScript and Canvas and do things like the the Buddha Brot fractal where you have this great sort of inverted Mandelbrot fractal. And it's actually amazing because if you do it in processing and you have it using Java and you think... And actually, some of my background is in working on Ruby processing, which is doing processing through JRuby. And so comparing the JRuby version of a Buddha Broad Fractal to the CoffeeScript and Canvas version,
Starting point is 00:21:27 like the speed is just unreal. You can have these great mathematically intensive computations running in the browser and going so much and being comparable to the speed at which processing would do them in the JVM.
Starting point is 00:21:40 So yeah, so I've been playing a lot with that. And then also been using it a little bit on the server side for some Node.js applications. I've been playing a lot with that. And then also been using it a little bit on the server side for some Node.js applications. I've been using it with Express, which has been a lot of fun, too, because it makes Express really fun to work with. And then also just raw Node.js. We have a piece of Document Cloud, which is a pixel tracker, because people embed the documents that they upload on the different websites. You'll have the Chicago Tribune.
Starting point is 00:22:07 Right now, the Chicago Tribune has a bunch of great documents regarding the Blagojevich trial, and I think they've got hundreds and hundreds of them in there. And so we have a little pixel tracker so that we can keep track of the remote URL that people are embedding these documents at, and we can start sending traffic to them, and we have a public search, and that's written in Node.js and CoffeeScript. And, yep, it's about 100 lines. It's pretty short. Okay, so with Node.js, I noticed that it's actually one of the requirements
Starting point is 00:22:35 for CoffeeScript, and the compiler actually runs on top of Node.js, rather? Yep, that's correct. So CoffeeScript is written in CoffeeScript, Node.js rather? Yep, that's correct. So CoffeeScript is written in CoffeeScript itself. When it started out, it was a Ruby program because I didn't have anything to write it with. So I actually started with Ruby and with Rack. And then it built and built and eventually it became a viable language that worked in the browser and worked in Node.js. And then there was a big, I think it was around 0.3.0, but a really sort of big switch.
Starting point is 00:23:14 So I basically ported the entire Ruby compiler over to CoffeeScript itself, and then I ran it on itself, and then I ran that parser on itself, and then we had a completely bootstrapped compiler. So now it compiles itself, and the source code is written in CoffeeScript. And so, yeah, I played around a little bit with doing it on Narwhal and Rhino as opposed to Node, but then just the speed of Node, in terms of me, because compiling can take a little while to generate the parser,
Starting point is 00:23:39 the speed of Node has been great. And so now the basic, the server-side version of it that you would install into user local bin and you would use from the command line is based on Node. But the compiler also runs in the browser too. So the JavaScript is pretty Node-agnostic at the core. You can run it in Firefox or Internet Explorer or whatever. So more than just Node, it also has a dependency,
Starting point is 00:24:00 or I guess it can be aided in the install process with Node Package Manager. Have we found our default package manager for Node now? As NPM, yeah. I think NPM has won the battle at this point. Well, development of TJ Holloway-Chuck's Kiwi package manager seems to have halted now, so NPM seems to be the default. So why the dependency on Node from a parsing standpoint? It's just a JavaScript runtime. Because it also does run in the browser,
Starting point is 00:24:36 and people have gotten it to run on Rhino also. It doesn't really matter where you run it. It's just our default runtime. But you can take, so there's a compiled, if you go into the extras slash CoffeeScript.js directory, that's a compressed, minified, compiled version of the entire compiler. And you can drop that onto a webpage. You can load that into Rhino and, and work with that. Although you do have some hooks to use Coffee directly in the server.
Starting point is 00:25:02 Some hooks, you mean the node, the node hooks? Yeah, you could use coffee uh you've got some examples on the website of using coffee as your coffee script in node right on the server side that was right so that was that was a special hook that was actually that was added to node i think by by tim smart um so that if you have a different file extension that's not js node can run a pre-processor like coffee script on it and then run it I still don't, because of the debugging reason that we talked about before, I still don't recommend running it directly because effectively what you're doing is you're reading in a file and then you're generating JavaScript in memory and then you're calling
Starting point is 00:25:35 eval to run it, which will work fine, but as soon as you have to debug that, you're debugging a huge eval and that's not very fun. So still recommend compiling it to javascript before you actually launch node in both cases for both the server and for and for and for node work but it's certainly possible let's talk about compilation for a second because you've got several different options i guess the default that i'm using is just a coffee watch command line interface but there's also a lot of community contributed scriptsributed scripts for Rack and for Rails plugins and others. Yeah, there's a great resources section. So CoffeeScript.org is the web page, and there's a resources section down at the bottom with a whole bunch of different syntax highlighters and integration into different Rails and Rack.
Starting point is 00:26:19 And I think there might be a Python 1.2 ways to compile it and to preprocess it if you have it as part of a website. So those just make it more convenient. But the basic, you can also use the basic copy command pretty easily because it can watch. If you do copy, watch, and then a directory and give it an output directory, it will compile every CoffeeScript file that's found recursively in the directory. Anytime it changes, using Node's great watch file support, which works, uses the file system to do really good watching of files for when they change, it'll compile that over into the parallel directory structure in JavaScript. So that makes it pretty easy to have it running in the background in development and not have to worry about it. When you refresh your page, you'll get your new code.
Starting point is 00:27:00 Yeah, that's exactly how I'm using it in an accelerated titanium mobile application right now. It's written in JavaScript, and just watching that folder, and it spits out the whole tree into the output folder. As far as the debugging in Stacktrace, titanium currently doesn't support that in JavaScript anyway. So one of the pluses that I get from CoffeeScript is that nice JSLint evaluated script. There's no more warnings in the titanium compiler telling me that I missed a semicolon or something. Right. I guess the titanium compiler is very strict about the JavaScript that it
Starting point is 00:27:34 accepts, I've heard. Because I don't even know how it works. Does it turn it into Objective-C, or do you know how that works? It creates native objects on the fly, but it goes through, even at runtime, it goes through, it uses WebKit to interpret the JavaScript, and then they have these proxy objects that proxy between the JavaScript and the Cocoa objects, so it creates Cocoa objects at runtime. Great.
Starting point is 00:27:58 So I guess you're actually using JavaScript core as an interpreter inside of the app. Right. I'm not sure if it's the vanilla WebKit JavaScript interpreter or if they've forked that as well. That's cool stuff. So it's a nice fit until they introduce a debugger for the JavaScript, and this is like all upside, no downside. Okay, so also on the debugging,
Starting point is 00:28:22 you mentioned before that if you're using it in the browser and there's an example on the website, or there has been an example I've seen where you've used a text slash copy script tag. Uh-huh. Rather, when you use a script tag with text slash copy script as the content type, do you get any enhanced debugging in the browser? For instance, TJ Holloway-Chuck's recent templating engine, Jade, when you're using it in the browser, it'll actually give you a complete stack trace of where the error occurred in your template? Is there anything like that that you can do in CoffeeScript? So, again, it's not a completely static language like HTML is. So, yes, if you do it in the browser, and if you go to CoffeeScript.org and you do the Try CoffeeScript page, then, yes, you will absolutely get the syntax error.
Starting point is 00:29:27 It will tell you what line it occurred on, and it will show you what went wrong, which is basically just a feature that our parser generator, which is we use Jyson, which is a great parser generator for JavaScript. So, yes, if you have a syntax error in your code, that will be pointed out to you. But because it's not a static language, you're actually running the code, then you have your real problem, which is have a syntax error in your code, that will be pointed out to you. But because it's not a static language, you're actually running the code, then you have your real problem, which is not a syntax error. Your real problem is you have a bug in your code. And then you're basically doing an eval, and that's the difficult part.
Starting point is 00:29:53 So the syntax errors aren't so much the issue for running it directly in the browser, but calling an eval on code instead of loading it as a regular JavaScript is, which is why it's recommended to compile the JavaScript first and then you don't have this problem at all. But if you're just doing some fun scripting around and you're not too worried about having to debug a major application, then the text slash coffee script thing is pretty fun. And so that's what coffeescript.org uses actually to hook into jQuery and to set up the try coffee script box. That's all done with a little text coffee script tag down at the bottom. And I think the best example of it is this
Starting point is 00:30:25 website, The Lincoln Shire Poacher.com by Chris Lloyd, which has a whole bunch of Raphael sketches that are written in CoffeeScript down at the bottom of the page. You can click on the refresh button to redraw the Raphael sketches. And so those are a good example of a nice place to use it.
Starting point is 00:30:43 Okay, so a quick question on a couple of your other projects. You've also written Underscore.js and Docker. With Underscore.js, was that actually originally written in CoffeeScript or was it written originally in JavaScript? So that was written in JavaScript first. That's from the fall, actually. So that's from when I first started the Document Cloud project.
Starting point is 00:31:05 So at Document Cloud, everything that we do has to be released open source. It's funded by the Knight Foundation. The idea is that we both make this service and also every single bit of code that we write will be made open source sooner or later. So it was extracted directly from the application there, and it was basically
Starting point is 00:31:22 just a collection of all the little functional helpers that you might want to use when you're writing JavaScript and trying to do sophisticated stuff on the client side, being able to select and filter and reduce a lot of things that are now in ECMAScript 5 that Underscore uses if they're available. So that was not written in CoffeeScript first. But it was kind of a test. So besides having the compiler of CoffeeScript itself be written in CoffeeScript, doing the underscore port was kind of a test of, all right, I've got this real-world library. I've got a bunch of performance benchmarks so I can know if it slows down.
Starting point is 00:31:53 I've got a big test suite so I can make sure that it behaves correctly. And is it possible to write it in CoffeeScript and have it work? And so the answer was, yes, it is possible. And we've got that as one of the examples in the CoffeeScript checkout. And also that it's actually a little bit faster than the JavaScript version because of things like comprehensions, where in JavaScript you would have had to write out the for loops by hand every time instead of using an each or a for each. But you don't have to worry about that as much in CoffeeScript because it will generate the efficient for loops for you where possible. So it ended up beating the original underscore and a couple of little benchmarks by a bit.
Starting point is 00:32:27 Speaking of those for loops real quick, the one that we didn't talk about was the for of that I fell in love with. The for of? Right. Yeah. Basically, we'll give you the key back end, evaluate the object on the fly,
Starting point is 00:32:43 similar to what Ruby does, where you can do multiple keys into the to a loop right so so the comprehensions in coffee script you have i guess you have sort of three basic types you have you can comprehend over an array or over an object or over a range so the range is the simple one the range is basically a for loop with a fixed start and end you know from one up to ten do this um so you say you know for i in range and you give it fixed start and end, you know, from 1 up to 10 do this. So you say, you know, for i in range, and you give it a start and end point. And then you have the array comprehensions where you can say for value, index in array. And then you also have object comprehensions where you can say for key comma value of object and we actually just
Starting point is 00:33:25 added a new one a new variant of it where you can say for all key comma value of object which will so the difference between there is is a subtle javascript thing where usually a for in in javascript will look up the entire prototype chain and if you've added methods like say prototype js does to the array prototype you're going to get um methods that you don't care about that you're not interested in so by default coffee script is safe and only looks in and uses a has own property check to only look in the closest object but if you want to speed that up a little bit you can say for all key comma value of object and then they'll give you everything with a with a vanilla um javascript 4n with no special checks.
Starting point is 00:34:06 And so this gives you a unified interface, these three different kinds of comprehensions, because you can use all of them are expressions. You can use them directly. You know, you can't usually just return a for loop and have that mean anything. But if you return a comprehension, that'll give you back all the values, the computed results of all of the values being passed through the block of code that you've given. And they all work in identical ways with that. Well, this is the part of the interview where we turn it upside down.
Starting point is 00:34:32 The folks that we speak to are usually who's on our open source radar, so we get to turn it right back at you and ask what kind of projects are on your open source radar. I'm getting pretty excited about it. So I think when we talked in the fall, you asked me the same question, you know, and I talked about Node.js and you said that, you know, everyone's been saying that recently. And I think that's still definitely the case and still going strong and has a whole lot of steam and a whole bunch of great patches that come out constantly and you have to keep up with. And I'm still waiting for the first sort of end-to-end, or at least the first person who glues it together end-to-end,
Starting point is 00:35:10 where you actually have rich models in the browser with a good standard library of common functions that then works seamlessly with the server-side, and maybe it integrates Comet, so you get live updates across all of your models because this is something that any client-side app that does a lot of work in the browser ends up doing. So in our case, we're dealing with journalists in the newsroom
Starting point is 00:35:33 working with documents and writing stories and annotating the documents. And you can share those between different newsrooms. You could have someone in Chicago and someone in Miami working on the same project and annotating the same document. And now what you want document and now you have to what you want to do is you want to be able to live update the changes back and forth when someone kind of like a Google Wave style or an Etherpad style
Starting point is 00:35:52 thing where as soon as someone finishes typing an annotation it appears instantly and you can really work together and collaborate in that way and that's something that JavaScript is a great language for enabling instead of like a rich Flash app and that's something that is very complicated right now because you have to use Comet. It's very, very difficult to get the changes pushed across correctly in a performant way.
Starting point is 00:36:13 And so Node provides the performance that's needed for doing that well. And WebSockets coming of age are going to provide the Comet replacement that's a little bit nicer to work with. And I think that someone's going to come out with an end-to-end solution that knows how to talk to databases in the background for persisting data, that has good ways of routing URLs to actions in the server, that has client-side models that can be shared with the server and can do validations on both end and can transparently sync changes. So all you have to worry about is basically your client-side app, and you can call save in the browser,
Starting point is 00:36:46 and it'll safely save it to the server with validations and has that all hooked together. I think that's what I'm waiting for. That's what I'm hoping to see in the next year. That's quite the dream. Who'd have thought that five years ago, going into the next decade, we'd be so excited about JavaScript? Yeah, who would have thought?
Starting point is 00:37:03 So where can folks catch up with you online? The CoffeeScript Twitter handle, is that you or a fan? That's actually not me. That's an unofficial one, but he answers questions pretty good too, so you can ask him. But if you want to, so right now, CoffeeScript, if you have an idea for an enhancement or a question or an issue, you should use the GitHub issues page. And if you want to just chat about it, come into the CoffeeScript room, all one word, CoffeeScript on Freenode. That's the IRC room. And there's usually someone who can answer your question there. Cool. Thanks for joining us today, Jeremy. All right. Thanks a lot. It's been fun. See you next time.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.