Please direct all thanks for this over to http://github.com/jwalton. He's been toiling away on these for a couple of months now, originally as a bit of a skunkworks. Managing to get them merged in cleanly to an oft-changing code generation codebase was no small feat.
Edit: If you're having any trouble getting these to work, `npm cache clean` and reinstall. I screwed up the initial publish.
Important Update: Just pushed out a 1.6.1 release which patches some bugs that snuck in this morning. Give it a spin.
It also makes it possible to generate source maps in the browser itself -- so if you're doing anything fancy with eval-ing CoffeeScript on the client side, you're in luck...
Absolutely fantastic! Though it is fairly easy to manually map the javascript source line to coffeescript code, I am hoping this feature can somehow be embedded into editors to make it much easier to write large coffeescript modules (live coding).
Can source maps handle source files in a different location than the compiled JS file? In my few minutes after installing, I didn't immediately see a way to do this.
> CoffeeScript includes a (very) simple build system similar to Make and Rake.
Arrrrrrrrrrrgggggghhhh.....
Why do people insist on doing this feature creep nonsense? Just stop! The world doesn't need another build system. The fact that you personally don't understand make (or cmake, or autotools, or rake, or scons, or ant, or...) is not a good excuse for inflicting another one of these things on the rest of us.
Yes, I'm sure it meets the needs of the coffeescript project nicely. But what introducing it has actually done in build a brand new barrier to those who want to work on coffeescript. You're ghettoizing your project with this nonsense.
Also: just for the record, those "cakefile" examples look awful to me; modulo language syntax, it looks just like scons. Everyone who has ever tried to use it for something serious hates scons.
Whoa there buddy, no need to stress. Just don't use it.
The only reason why `cake` exists is because at the time that CoffeeScript was first released, there wasn't a "standard" JavaScript build tool, and we wanted the "coffee-script" project to have as few dependencies as possible. Adding a simple way to expose functions to the command line made it possible for CoffeeScript to build itself, without relying on "make" (Windows), "jake" (very rare), or "rake" (a Ruby dependency).
Regarding your comment below -- it's definitely not going to grow. All it does is expose functions to the command-line. See a litany of "closed wontfix" tickets if you don't believe me ;)
Also -- and perhaps mainly -- releasing "coffee" and "cake" binaries together was too cute to resist.
This isn't new, CoffeeScript has included this for a while.
One thing to keep in mind is that Cake is tiny, the complete source shouldn't take more than a minute or 2 to read and understand[1] and is a nice example of CoffeeScript style.
You're right that it's not new in 1.6; I misread the page. It was new to me, however. And you're right that it's quite small, and easy to read.
Which allows me to pronounce that It's tiny because it's limited. What happens when the project bumps up against those limitations (parallel builds would be nice, or maybe default rules, or the ability to invoke and export environment variables to subprocesses, or...)? Will they abandon cake and move to a build system that already meets their more advanced needs?
Hell no. They'll add features. So the cake of 2019 will, assuming a still-robust coffeescript community, look a lot more like rake or ant or scons or cmake. It won't be tiny. It won't be easy to read. It will be yet another ridiculous build system.
The history of cake.coffee[1] suggests otherwise. It's been edited relatively few times since the initial checkin, mostly to make it compatible with node.js API changes, and sometimes to pare it down and simplify it. It was hardly touched at all in 2012. It is small and mindful of feature creep.
>Hell no. They'll add features. So the cake of 2019 will, assuming a still-robust coffeescript community, look a lot more like rake or ant or scons or cmake. It won't be tiny. It won't be easy to read. It will be yet another ridiculous build system.
Which you will be free not to use. Along with not using Coffeescript.
It appears that running `cake` doesn't check to see if there have been changes since the previous build. I wouldn't use a build system that didn't at least have this essential feature.
Cake is a nice little tool. It could be detached from CoffeeScript and turned into a separate module, but it isn't hurting anyone.
When you're writing a node.js or browser project it's good to write build scripts in a language not too far from the main one, and it has the advantage of being able to use the whole node.js module ecosystem.
Take a look at this build script: https://github.com/ryejs/rye/blob/master/Cakefile#L52-L79 using flour[1]. I don't think you can get more succinct than that with any other build system, and it's blazing fast thanks to asynchronous I/O.
Thank you for this! One of the biggest justifications for avoiding Coffee-Script has been the difficulty in debugging the translated code since there is (no longer) a 1-1 line mapping. This is now a thing of the past!
For anyone wondering (since it's such a new thing that not a lot of people know much about it): Source maps are currently only supported in Chrome, but it's also implemented in recent WebKit nightlies and Firefox is actively working on support. In order to use source maps in Chrome, open the options panel on the dev tools and make sure the "Source maps" option is enabled.
Right. As far as I know, they currently work in Chrome, in Node.js (with a library), in Webkit nightlies, and are getting close-ish in Firefox nightlies: http://fitzgeraldnick.com/weblog/45/
If you have Visual Studio, they have source map debugging for TypeScript working. You can do CoffeeScript dev in Visual Studio [1], but I have no idea if source maps work with that.
Thanks for that! Added to my comment. I meant to mention WebKit initially, but I got so focused on double-checking that my Firefox information was current that I just stopped afterward.
If you've downloaded a prior version of version 1.6, you'll have to remove it from your `node_modules` folder and do an `npm cache clean` before reinstalling, as the version number is the same.
I've just pushed out a 1.6.1 update, trying to address these. If you're having any trouble with it, give 1.6.1 a try -- and if you're still having trouble, let me know.
For someone who is new to Javascript (and programming in general), how do you know when it'a ok to move on to coffeescript? (I started with ruby and I like how coffeescript has similar syntax)
Early in my Javascript career, I read "Javascript: the good parts", and started with Coffeescript very early. And I very often would look at the Javascript that Coffeescript was generating for me. I was pleased to find that Coffeescript automates a lot of the things that the book recommends. Totally worth doing early, in my mind, especially if you're interested in Coffeescript.
Don't consider learning a language like CoffeeScript or ClojureScript until you thoroughly understand JavaScript. I think it's much easier for a beginner to learn JavaScript APIs (both built-in and third-party), which you'll need, from JavaScript examples without having to translate them to another language in the process.
Also, I'm not sure you can use these other languages' features judiciously without understanding their reasons for doing things a certain way. You will need to know how `this' and `prototype' are used and things of that nature, then you can decide if you find the abstractions and overhead of compile-to-JS languages useful.
Spend a weekend building a tiny project with CS. Or use it to add a small feature to a project you already have.
You have to constantly be on the lookout for new tools that will give you new capabilities or make it easier for you to do the things you already do. So you should be willing to try something different like CS -- recognizing that it's a learning experience and it might not work out.
It's fine if you decide that CS isn't the best, and you want to stick to plain JS. Not every tool works well for every person. Sometimes everyone raves about the goodness of technology X, you try it and agree. Other times, you try it and hate it.
Sometimes you come back months or years later to a technology that gave you bad experiences, and due to changes in both you and the technology, you're pleasantly surprised. Or a long-proven technology that you've been using for years has slowly but surely been surpassed by something else, and is now nearly obsolete.
So it's not guaranteed that CS right now will work out for you, but you don't know until you try. And even if it doesn't, you should keep it in the back of your mind and take another look in a few months or years.
Probably right now. But that's a good question. As you've already seen, the documentation on http://coffeescript.org is phenomenal.
As a dev with maybe 1.5 years of JS experience, I've learned coffeescript in a week. I still don't have the coding style that my code reviewers want, but I'm writing functional code.
The biggest hurdle I've found is getting an auto-compiler for coffeescript. You don't want to do it manually:
I have not had great luck mixing coffee --watch and gvfs for either FTP or WebDAV. An ugly, but effective solution is to configure your editor to compile on save. The most annoying part of that is when you switch to a project with a different build process, and you have to either reconfigure your editor, or deal with extraneous .js files being output.
You can also ask yourself what step of learning you're at. Do you just want to build stuff? Then you can probably jump to coffeescript right away (especially with the new Source Maps feature). Do you want to get more in-depth knowledge of popular programming languages? Then stick with JS; learn how it handles types, how it handles functions, what the prototype chain is, how exceptions are thrown, etc. Maybe even read JavaScript: The Good Parts.
People build amazing sites in both languages... so you can't go wrong... it's just a matter of what you want to learn on the way. Good luck!
Agreed. CoffeeScript is a leaky abstraction of JS; the underlying paradigm of JS still peeks out even though it's papered over (see the fat arrow =>).
Once you have a grasp of JS (and the things you might not like about it), you can then move to CS. When something looks a bit off in CS, you'll probably be able to translate why it is that way due to the JS underpinning.
Since I've programmed JS before CS was created, I've long been resigned that I'd have to understand and follow the idioms of both languages. But using CS is so much sweeter to read and write that I end up being lulled into thinking that I'm writing Ruby. I can't tell if my brain is taxed more at having to switch between Ruby and regular JS, or if it's more tiring to constantly remind myself "this is not Ruby. This is not Ruby. This is not Ruby" while writing long stretches of CS :)
But I've only dabbled with CS so I'm sure like with anything, practice reduces this mental fatigue. I am bummed that CS went to camelcase, but the justification back then was a good one
I think it could work well to start with CoffeeScript -- that is, to learn JavaScript by first learning CoffeeScript. For the real world you must understand native JavaScript, of course, but that could come incrementally. I don't actually know anyone who's done this, however.
@jashkenas: with the release of this surprise, 'skunkworks' feature, what do you see as the future for Coffee-Script-Redux? Does the project remain relevant despite the recent activity in the original Coffee-Script project?
IIRC, this is one of the big reasons behind CoffeeScriptRedux. In fact, I have been following development of it closely and he's been working hard. I know he's contributed lots to the standard CoffeeScript codebase.
Does this deter him from completing that project? If not, what big features does Redux plan to offer that regular CoffeeScript does not? Using pegjs instead of jison?
You'll have to get Michael to answer that question, but to clear the air a bit -- it's very nice to have two versions of the compiler that don't share a common ancestry (Redux is a complete rewrite).
We may merge the Redux version in and bless it as the "official" compiler some day, when it matches feature parity, and if the codebase ends up cleaner than the original (both very likely things to happen). Even in the worst case scenario, where no merge happens, we all benefit, both for learning, new features, and shared fixes for bugs, from having two independent compatible implementations of the language.
95% of the language features were supported during my funding period. Since then, it's nearly reached 100% feature parity, and the tooling/interfaces have been much improved. The code is a lot cleaner, a lot smaller, more modular, more extensible, and uses standard IRs.
I will say I very much like Redux and have used it for dumping AST nodes. I recently became interested in a project where I wanted to hack on and extend the grammar. I found this difficult in Redux, Coco (and friends), and couldn't use CoffeeScript because of lack of source map support previously.
I think a huge benefit for Redux will be making the grammar very clean and extensible. I know it's on your roadmap to CS-ify it.
Edit: Oh, and if you're curious, I wanted to play around w/ translating the CS AST to TypeScript AST, but I'd obviously need to add more typing/declaration syntax to the grammar.
Congratulations on all this hard work. Source maps will CS an even more appealing alternative to plain Javascript and make my life as a developer better.
Thanks to all parties involved in producing this release.
Yeah, I would also love a "CoffeeScript for C". Honestly, I think C is a rather overrated language--it's liked not because it's good but because it's the best at what it does. And best is only a relative measure!
The most promising thing I've seen is CIL[1][2]. This is not a language per se, but it follows the same idea as CoffeeScript: simplify and get rid of stupid edge cases and odd syntax. The difference is that CIL is designed as an intermediate language (hence the name); it's a target for a DSL, compiler or code generator more than a language proper.
For embedded programming, I think a DSL embedded in Haskell or OCaml outputting C through CIL can give you all the benefits of C without many of the problems. More importantly, it gives you a power to abstract that C sorely lacks, as well as a nice type system.
There are some existing DSLs in this vein (that is, generating C rather than using CIL necessarily). One example I came across recently is atom[3], but I haven't used it (or any other language like that). It's certainly something to keep in mind.
Many languages — Haskell included — can compile to C. Compiling down to C and then piggybacking off the system C compiler is a fairly common way of getting a sophisticated native codegen without needing to implement one yourself. But simply compiling down to C doesn't necessarily put the language in the same relationship with C that CoffeeScript is with JavaScript.
To be honest, I could imagine a slightly nicer skin over C, but C is already a pretty good C. Any "CoffeeScript for C" would probably work out to a poor reimplementation of an early C++ compiler with the semicolons removed.
This isn't compiling Haskell down to C. It's using a DSL to generate C. The DSL just happens to be embedded in Haskell.
Haskell is just an environment, a language factory. Haskell is used for creating the abstractions and meta-programming. You can also piggy back on Haskell's type system to enforce certain invariants.
But ultimately the semantics of the DSL--what actually gets turned into C--are not necessarily related to Haskell at all. Instead, the semantics are tailored for your particular application. In the particular case of atom, this application is hard real-time programming.
Another example is something one of my friends worked on in OCaml. He essentially created a little algebraic system which provided all the operations for a field (with maybe a couple other ones). This is enough to implement a bunch of variations on a Kalman filter. He could then iterate quickly and test the code locally; when he was content, he could use the same code to output abstraction-free C which he could then compile and deploy on ARM.
The point being that the host language is not related to C; it's the embedded DSL that plays the role of CoffeeScript. (Although any reasonable DSL would be quite a larger departure from C than CoffeeScript is from JavaScript.) You just use Haskell/OCaml/Scala/whatever to save having to implement a parser, type system and so on.
AFAIK it isn't removed, but it is no longer developed and requires GHC to be in unregistered mode, which most people's won't be. But I could simply be behind the times.
> This is the oldest code generator in GHC and is generally not included any
> more having been deprecated around GHC 7.0. Select it with the -fvia-C flag.
CoffeeScript is deliberately tied to JavaScript by design. Porting it to work with Erlang or C would be rather awkward. Outside the context of a JavaScript environment, CoffeeScript doesn't seem to offer enough benefits over, say, Python to be worth the massive amount of work this would entail. If you mean you want another language that can interact with Erlang or C code, those already exist (in fact, there are a lot of langauges that are C-compatible since it's the lingua franca of modern computing).
By “CoffeeScript for C“, I think Onr means not supporting all of CoffeeScript’s features in C, but rather making a language that is very much like C, but better. So CoffeeScript for C wouldn’t try to implement `@foo` to mean `this.foo`, since there is no `this` in C. Rather, it would look at the common idioms in C that are more verbose than they need to be and shorten them.
CoffeeScript for C would probably use semantic whitespace, like normal CoffeeScript. Maybe it would make writing types easier – it would support a syntax for types that doesn’t require the use of http://www.cdecl.org/. It would still try to be “just C”, so it wouldn’t support much higher-level features like function closures.
I’m writing a simple “CoffeeScript for C” right now for my CS 283 Systems Programming class’s final project. It’s due in two weeks, but my work so far is on GitHub now: https://github.com/roryokane/cs283-final-project. It won’t do much – it will just compile three kinds of syntactic sugar – but I hope to make it composable enough to extend it in the future.
The three syntactic sugars I’m including are these: allow indents instead of {}; automatically add semicolons; remove parentheses from if/while/for conditionals. I’m trying to make my compiler robust enough to not cause problems like JavaScript’s automatic semicolon insertion does.
This project is just CoffeeScript for C for now, but I’m aiming in the future to make a generic “CoffeeScript for C-like languages”, that can be adapted to work with languages like with ActionScript and Java with only minor tweaking.
The hard part for me to understand is that I've got way more than just a single file. I've got hundreds of coffee script files for a rather complex nodejs/express app.
I start it up with something like this:
nodemon -w . lib/start/web.coffee
or in production:
coffee lib/start/web.coffee
That web.coffee file then require's a chain of files.
If I try to compile the source maps for all of my files first, using something like this:
In the .compile folder, there is a few oddly named subdirectories (d, b, rands, sc) with the compiled .js files in there and the respective .map files. This seems to totally break my require chain.
Since I don't normally pre-compile all my coffee script files, I just run them directly using nodemon or coffee, how can I work the maps into my dev process?
$ coffee --version
CoffeeScript version 1.6.1
$ coffee --compile static/test.coffee
$ coffee --compile --map static/test.coffee
TypeError: In static/test.coffee, Cannot call method 'indexOf' of undefined
at Object.count (~/.npm/lib/node_modules/coffee-script/lib/coffee-script/helpers.js:33:29)
at Object.compile (~/.npm/lib/node_modules/coffee-script/lib/coffee-script/coffee-script.js:72:30)
at ~/.npm/lib/node_modules/coffee-script/lib/coffee-script/command.js:171:33
at ~/.npm/lib/node_modules/coffee-script/lib/coffee-script/command.js:141:18
at [object Object].<anonymous> (fs.js:123:5)
at [object Object].emit (events.js:64:17)
at Object.oncomplete (fs.js:1181:12)
(Paths were full path names, I replaced my $HOME with ~ in the output for clarity and some security through obscurity)
In TypeScript it works out-of-the-box, plus TypeScript compiles to idiomatic JavaScript and what you write is much closer to what you get, and the transition is much easier understandable.
Please direct all thanks for this over to http://github.com/jwalton. He's been toiling away on these for a couple of months now, originally as a bit of a skunkworks. Managing to get them merged in cleanly to an oft-changing code generation codebase was no small feat.
Edit: If you're having any trouble getting these to work, `npm cache clean` and reinstall. I screwed up the initial publish.