For some deeper rationale of why ClojureScript over other neat compile to JS languages like CoffeeScript, Dart (via dart2js), and TypeScript check out a talk I gave recently at the Norwegian Developers Conference, ClojureScript: Lisp's Revenge http://vimeo.com/68334908
I think the arrival of core.async makes ClojureScript an even more compelling option as it has the potential to eliminate an incredible amount of incidental complexity.
I'm already a big fan and advocate of both Clojure and ClojureScript, and although I've had great success convincing friends and coworkers to give Clojure a try (and even get excited about it), unfortunately ClojureScript has been a different animal entirely.
Thus far, everyone I've taught Clojure concepts to really appreciates the functional bend of the language, immutable values, and of course the elegant sequence/collection abstractions/persistant data structures that Clojure provides. But semantics are almost never a convincing argument (for most for programmers I know) for spending the time to pick up another language.
What really pushes people over the edge in my experience from thinking of Clojure as "just another Lisp" or a parentheses laden toy, are the amazing concurrency primitives that Clojure provides out of the box. Once my colleagues realize how trivial (and fun!) both concurrent and parallel computation becomes with Clojure, they're hooked and want to dive in.
The talk you gave is probably the most concise manifesto I've yet to come across of just how much better Clojure's semantics are for, well, pretty much any complex problem I can think of. You did an absolutely fantastic job with your assemblage of example functions which definitely shows off the language.
But I know that if I want to convince the company I work at to adopt ClojureScript as a JS replacement for our client side applications, an argument for superior semantics is almost never going to get very far.
Clojure (in combination with libraries like Incanter, JVM interop, etc.) allows me to completely replace R & Python for both exploratory data analysis, machine learning, and building a powerful backend for any distributed application with a double whammy of awesome - I get a much better language for expressing a lot of ideas AND it's fast as hell. I can scale my Clojure code to a cluster of CPUs for training some model without a second thought. I can write really powerful software and never feel limited in what I can accomplish and in the end, project managers/execs just can't argue. Simply nothing else exists in this class with this combination of agility, functional elegance, and "enterprise" class power.
Okay, this comment began as a thank you for making a great appeal for ClojureScript and has unexpectedly turned into... I'm not even sure.
So, TLDR? We need a killer feature that goes beyond semantics for ClojureScript that fixes something broken and practical in JavaScript. Is this a seamless and powerful Web Workers VM or abstraction that just works? Is it a mature core.async in tandem with full featured promises? Is it a new core lib that makes having to think about client/server interaction a problem of the past? I just don't know.
Very well stated. A few months ago I wrote a post on my company's blog pushing Clojure, and the ideas just seemed to flow. Now I'm getting around to writing a specific post on ClojureScript, and even though I love writing cljs code, I'm having a hard time making a convincing argument to others.
There are however a few things that still stand out about ClojureScript I think, but I don't think they are mature enough to qualify as a killer app, but mostly just something to pique the interest of a certain class of programmers.
One is the port of core.logic. AFAIK there is not a comparable Javascript logic library, although the ClojureScript port does not have all the features of the Clojure base.
Another novel feature is integration with nrepl via the piggieback library[1]. This allows you to evaluate ClojureScript code directly in your running web app if your editor has nrepl connectivity. Again, I don't know of a way to do this with current Javascript tools. But here again, the solution still feels like it lacks maturity.
I don't understand enough of core.async to really comment, but the excitement around it seems to point to another rather exclusive bit of ClojureScript functionality.
That feature is bound to be functional reactive programming which extends into the server.
The two easiest ways to think of FRP are to either a) imagine it as declarative data binding with the ability to add function transformations or b) think of Excel cells and their functions and dependencies.
Pedestal [1] seems to be an attempt at getting there but it's still incredibly convoluted compared to its Common Lisp equivalent Cells [2]
P.S. If you combine FRP with Clojure's purely functional data structures you also get an amazing 'replay' feature since your UI is nothing more than your (client + server) data models materialized into a view through a graph of FRP functions.
I think this is insightful. Benefits of ClojureScript like namespacing, functional primitives and client/server code sharing can be attained via other, easier (though not necessarily better) tools in the JS ecosystem.
Of the things that you mentioned, I'd wager that core.async will be the captivating feature for ClojureScript. David Nolen's excitement is a good gauge. If that increases adoption significantly, it's my hope that ClojureScript's other benefits keep the fire burning.
I went into irc's #clojure to ask if I should use clojurescript for developing a html canvas based game. Most of the people in the chatroom dissuaded me. Their main concerns were:
1) there's no source maps. IE: a browser stack trace does not map exactly to your clojurescript code so it can make things hard to debug.
2) finding and fixing performance issues in your clojurescript would be very challenging, especially if you're not an expert in javascript already (which I'm not)
I took their advice but a personal issue I had along the way was, where the hell is the "hello world" getting started guide!? I was never able to find documentation that said, "write this simple file and type this simple command and now you've just built your first clojurescript example". Keep in mind I cut my research short, but I did put at least 2 hours into it.
So I decided to use coffeescript instead. I think it's closer to the raw javascript but it's more concise. I haven't had any performance issues and even though coffeescript is supposed to have source maps, I haven't needed to use them yet.
It's giving me confidence to try clojurescript for my next project. I think it'll be an even better experience than coffeescript. The ability to write your program in one language, front and backend, is really appealing.
We already had have rudimentary support for source maps - in fact it seems people have already used it to successfully debug their programs. It's not good enough yet for step-by-step debugging - we're getting there.
RE: performance. I don't know who you talked to, but they are misinformed we spend a ridiculous amount of time on performance. It's certainly possible to do an HTML 5 canvas game in ClojureScript - http://swannodette.github.io/2013/06/10/porting-notchs-minec.... It is true that if you want to do a computationally intensive game you need to know something about JavaScript performance - but that's to be expected.
I'm finding Three.js with an idiomatic Clojure veneer to be quite enjoyable. I find one of the biggest "wins" of any Lisp is how natural it is to build a DSL for whatever your problem domain happens to be.
For example, right now I'm toying around with a declarative syntax for specifying arbitrarily complex mesh animations in terms of partial functions. To illustrate, instead of having a render loop where conceptually you are modifying something globally in a once per frame, iterative fashion, instead you would feed your rendering context a hash-map that both specifies animatables to be animated, and applies these partial functions onto the specified properties of the animatable object.
Anyway, I suppose my advice is to not give up on using ClojureScript here because the potential for making the development of your game a thoroughly enjoyable experience is, for one, a huge win. Aren't we supposed to be enjoying this stuff at the end of the day?
Take advantage of the language and be creative. I have never run into a situation where ClojureScript has somehow bottlenecked performance in any way, and I honestly can't really imagine that being a real concern. This is doubly true in a WebGL graphical context where most of the potentially awesome looking stuff (www.shadertoy.com) is being offloaded to the GPU and has absolutely nothing to do with Javascript or ClojureScript.
My last piece of advice: figure out how often you want to deal with native javascript objects instead of Clojure data structures early on, and stick to it as a convention. The little differences in how the language treats the two (in a collection/sequence sense) will drive you (or me) crazy. I personally prefer to take any JS object I'm going to make considerable use of and turn it into a full fledged Clojure object until I'm finished with it. Obviously this advice doesn't apply to short lived objects, or simple method calls.
I wanted to try out ClojureScript a while ago, but found the tooling around it very complex since I also didn't have any experience with Clojure and Leiningen.
Is there a straightforward starter guide around?
ClojureScript Up and Running is actually pretty good. Lein I've gotten to know simply by using it, getting snippets from blogs here and there. Once I get better with it, I'm curious to see if I could use it for Java builds. It's the build tool Java ppl have been waiting for I think.
I'm going through "ClojureScript Up and Running" right now, and I'd also recommend it.
However, for folks who just want to give cljs a try, lein-cljsbuild does make it pretty easy at this point. Once you have lein and the lein-cljsbuild plug-in installed, the basic information on how to get a project up and running is here:
It used to be a PITA, it's still not perfect but much better. take a look at lein-cljsbuild (https://github.com/emezeske/lein-cljsbuild) to create you project, there you can just create an html and add the resulting js in the html, so you can test in the browser. No need for web servers or anything.
I am expecting the author to mention the single most important factor that worries most cljs users: the interfacing problem with other JS libraries that cause by google closure compiler. But apparently he does not use other JS libs.
And yes, we need Closure advanced compiled mode when ClojureScript ships with a standard library nearly 7500 lines long.
Interfacing with other JS libraries isn't really a problem - that has been relatively pleasant for a long time now (:foreign-libs compiler option allows you integrate arbitrary JS libraries).
Also note that the most popular JS libraries like Underscore.js and jQuery add little value to ClojureScript given the rich standard library and pure ClojureScript solutions like Domina.
Not sure what angular buys you when the power of clj is available - way too low level imo. I wouldn't mind a cljs version of seesaw though, I don't think something like that is out there yet.
Getting out of the insanely dumb naive DOM smashing pattern is more important than having macros in your frontend language. I am experimenting with Angular + ClojureScript via Clang right now, but if I am forced to make a choice between the two, ClojureScript isn't going to win and I do Clojure on the backend if I'm given a choice of what to use.
Angular is still a nice way to do your DOM manipulation declaratively. https://github.com/pangloss/clang extends angular to work with the the built in clojurescript data structures. Or https://github.com/zcaudate/purnam has some angular helpers that work with regular javascript objects.
sure there are many ways to make foreign lib works. I use externs.js to stop google closure compiler from changing my var names.
but if clojurescript could make this kind of "hacks" integrated: i.e allow (:use [js/Foreign_lib :only lib.method]) instead of externs.js, then it will be way easier to attract newcomers.
I agree that using google closure will save a lot of work, for now. But I also think that clojure guys should come up with their own(and better) compiler that has awesome compiled asm.js code as killer feature.
I think the arrival of core.async makes ClojureScript an even more compelling option as it has the potential to eliminate an incredible amount of incidental complexity.