The Changelog: Software Development, Open Source - CoffeeScript and JavaScript (Interview)
Episode Date: July 23, 2010Wynn 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)
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,
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.
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.
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
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.
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
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.
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
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.
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,
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.
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.
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
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
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.
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,
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
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
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.
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
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
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
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.
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
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
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
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,
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.
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.
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
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,
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
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
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
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.
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
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.
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.
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.
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,
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.
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,
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.
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.
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,
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.
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.
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
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.
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,
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,
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,
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.
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
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.
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.
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
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.
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,
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.
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.
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
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.
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.
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
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.
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.
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,
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
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.
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.
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,
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
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
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.
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,
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?
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.