CoffeeScript seems to be picking up some momentum these days. No doubt, it is very valuable to help writing cleaner code.
The command-line choices to run CoffeeScript compiler right now are either using Rhino (jcoffeescript) or using NodeJS. While I love NodeJS, seems that it is an overkill to require the entire NodeJS stack/infrastructure/package manager to invoke CoffeeScript compiler.
The solution is to use V8, the powerful JavaScript engine, with a little binding so that it can access file system. This is exactly filejs, something I have shown before, e.g. to invoke JSLint from command line.
Combining filejs and CoffeeScript is terribly easy. Just follow these steps.
Note: filejs does not support Windows yet. Sorry.
First of all, if you have not done it, build filejs. Go to the X2 repository, it is under the javascript/filejs folder. Open the included README.TXT and follow the instructions on how to build V8 and filejs.
After you build it, copy both filejs executable and coffee.js to somewhere in your PATH. Usually I stash that kind of stuff in ~/bin and ensure that ~/bin is in my PATH.
Now get coffee-script.js (the CoffeeScript to JavaScript compiler) and store it somewhere, e.g. ~/bin again.
Create a new file called coffee, which has the following one-line content:
filejs ~/bin/coffee.js $1
Make that file executable and then save it to ~/bin (again).
Open coffee.js and modify the value of the compiler variable to point to your coffee-script.js. Note: this must use the absolute path name.
Now you can do the following:
coffee hello.coffee
If hello.coffee is your script written in CoffeeScript, the converted JavaScript version will be dumped to the standard output.
Feel free to tweak coffee.js so that it understands and passes various CoffeeScript compiler options!
Usually, you would want to use scripting solution, e.g. Perl/Python/whatever, to manipulate file contents. Somehow, it's also fun to use JavaScript instead. After I did the V8-based jsbeautify, I was doing V8-based jslint as well. Then I realized, let's just extend it to be generic. With API loosely modelled after CommonJS, filejs was born. Find it in the usual X2 repository under the javascript/filejs. There are two examples so far, ROT-13 and line counter. If you write more examples, feel free to pass them to me!
Of course, the twist is: use filejs to drive a command-line jslint. This is one way to do it. First build filejs (follow the instructions in the included README), then place the executable in your PATH. Create a simple shell script, which contains one line filejs /path/to/filejs/jslint.js $1 and make it executable. That's it! If you also store this shell script in your PATH, then you just need to run:
jslint source-code.js
If you use vim, jslint can be combined with Quickfix. First of all, associate *.js with the tool by putting this line in your personal .vimrc:
au FileType javascript set makeprg=jslint\ %
Now open a JavaScript file and run :make (or whatever shortcut you map this into), which will launch jslint with the current file. After a while, use :cope to open the quickfix little window, move up and down, and press Enter to bring you back to the main editor and set the cursor at the specified problem. Use standard window navigation, e.g. Ctrl+W W to switch to quickfix pane again. Check the quickfix documentation for details. All in all, you may want to map mostly used commands to some shortcuts for faster access.
Note that since this is dynamic JavaScript, rather than matching errorformat, technically I just tweaked the tool to spit something similar to what a C/C++ compiler would do. Also, if you need different jslint options, simply edit the invocation to suit your needs.
It's been a while since I blogged about vim. The last one was about the project plugin, which is surprisingly still quite popular. Hopefully this one also teaches you a trick or two, especially if you work a lot with JavaScript code.
Note 1: It does not work on Windows yet. No idea if I would have the time to do it, patch is welcomed.
Note 2: This is not a replacement for NodeJS, nor would it grow to include more functions.
Note 3: For the sake of completeness, let me mention that there are already other countless solutions for command-line jslint (using Rhino, SpiderMonkey, JSC, etc), even with vim integration.
If you are using a modern browser, likely you already have the (arguably) most widely deployed scripting environment: JavaScript engine (or ECMAScript, if you insist). There are many things you can do with it (just look at tons of cool web apps out there). However, since it is contained in the browser, there are also things the embedded JavaScript engine can not do for you.
If you are using KDE, you also have two excellent JavaScript engines: KJS and Qt Script. You can embed either of them (i.e. KJSEmbed) and make your application scriptable. In a not-so-strange twist, they both relate (distantly) to each other via JavaScriptCore, WebKit's default JavaScript engine, because
long time ago Apple forked KJS and used it as the base for JavaScriptCore, and Qt Script (for version 4.6 and 4.7) also uses JavaScriptCore as the back-end.
If you are interested in learning, using, and/or dissecting other open-source JavaScript engines, have a look at JavaScript Engines: How to Compile Them I wrote for our Sencha blog, which covers Mozilla's SpiderMonkey, WebKit's JavaScriptCore, and Google V8. The instructions should work on the supported platforms, including ARM, in case (just like me) you want to have and carry around every JavaScript engines in this planet on your Maemo-powered Nokia N900. That is fun.
As the closing, just remember, "Ask not what the JavaScript engine can do for you — ask what you can do for the JavaScript engine".
Unfortunately seems that this page is listed on Digg or reddit (hence the off-topic, bashing, and/or childish comments). Otherwise, I would expect some more cheeky yet insightful and thoughtful remarks.
At my request, Kent kindly changed the initialization of the Qt bindings (from the binding generator project) so that the class wrappers are populated in a single function for every module. This also means, you don't have to compile everything as plugins and then deploy them with your scripted application. You can just include the appropriate .pri file (e.g. generated_cpp/com_trolltech_qt_gui/com_trolltech_qt_gui.pri for Qt Gui bindings) and then build together with your project (or compiled to non-shipped, project-wide static library, if you wish).
Another gem: for each module you will have a source file, e.g. qt_gui_init.cpp for Qt Gui, that is responsible to create the wrapper classes. This means, the two macro tricks would work:
While the first is arguable already useful, the second one is interesting because it allows you to limit the bindings to certain classes only. For example, if you want to extend the look-and-feel of some GUI elements in your cool applications, just offer the user the bindings for QPainter, QBrush, QPen, and other related classes. Neat, isn't it?
On a related note, you should also perform some kind of dance that our QtScript hero has also created the bindings for the Animation and State Machine frameworks slated for Qt 4.6.
These days I am juggling balls. Beside fixing QtWebKit-related bugs, writing more examples on using QtWebKit, I am helping the Kinetic guys with Graphics View optimizations, and working on new Graphics View feature I still can't elaborate (sorry for the teaser :-). On top of that, I already started to work on Qt Script, learning the intricacies of JavaScript along the way, stress-testing Kent's Qt Script binding generators, and surely also playing around with the brand-new Qt Script debugger in Qt 4.5. For the latter, even if you are not really into Qt Script, I highly recommend giving it a try, at least watch the screencast from Kent for a start.
Unless you stayed under the rock for the last few weeks, you already heard about Chrome Experiments. These are some extremely cool demos designed to run in a web browser. Of course, there are already tons of demos out there. Chrome Experiments are however different. It relies on a high-performance browser. The reason: the demo is JavaScript intensive and thus a blazing-fast JavaScript engine will make a different. Coupled with the use of HTML 5 Canvas, some of demos simply show many things which are not possible before. Flash will be still here to stay (due to its authoring tools, advanced features, libraries collections, and so on). But I won't be too surprised if this is going to be a Flash-killer technology. There is O3D but I reckon it tackles a different market segment.
My favorite Chrome Experiment is Monster Evolution, an fantastic demo written by Dean McNamee. Try to launch it in your browser (warning: extremely slow if you don't use state-of-the-art browser). Or just watch the YouTube video. Impressive, isn't it?
When I saw Monster demo for the time, I thought it would be cool to be able to run it as a Qt application. Porting the demo from JavaScript to C++/Qt is one way to do it, but to make the challenge even more painful, I decided to run the monster.js code directly (warning: it's minified, better check Dean's open-source 3-D engine behind the demo). There are tons of ways to do, I almost tried every possible permutations. In the end, I managed to run Monster Evolution smoothly, at more than 25 fps on a fairly modern machine. What was to be just a quick hack turned into a struggling but delirious adventure, resulting in a three-installment series.
In the first part, The QtScript Menace, I used Qt's built-in ECMAScript interpreter to run the demo. The performance was not my main concern (though it gave me the chance of using our work-in-progress Qt Script version that uses JavaScriptCore as the back-end), rather the trick on how to run it with as little code as possible. I ended up with a hackish pure JavaScript implementation of the canvas object, along with few lines of glue code, using Qt Script's feature of making a QObject instance available to the script engine. Surprisingly, it works pretty well. It downloads the JavaScript code from the Internet, setups some stuff and then runs it. For a program comprises 240 lines of C++ and 140 line of JavaScript, I am pretty happy.
For the second attempt, Attack of the SquirrelFish, JavaScriptCore was chosen as the engine that powers the demo, used via QtWebKit. Again the same trick was employed, with the glue code now relies on QWebFrame's addToJavaScriptWindowObject and evaluateJavaScript. This requires only minimal changes, with an improved performance as the result (significant and noticeable), especially when JIT is available.
The saga was closed with the third episode, Revenge of the Cylinders. This time the victim was V8, the JavaScript engine which powers Google Chrome. Again, the code change was minimal, consider that V8 glue code to this little Qt application needs to be written manually. Of course this requires you to build V8, I have included the instructions (works on Linux, Mac, Windows) in the accompanying README on how to do that.
Feel free to try all three methods and let us know the frame-per-second speed-up that you get!
The graph itself is not something new, since I just recreated SquirrelFish Extreme comparison (against its predecessors). The focus is actually the tool which was used to generate that bar chart.
For the code and a little explanation, check out what I wrote on Qt Labs on the topic of
QtScript-based bar chart.