7 ms·
Comparing JavaScript, CoffeeScript & ClojureScript
- grayrest 15y ago> neither JavaScript nor CoffeeScript provide any kind of doesNotUnderstand: hook Feature is Proxies, it's in Harmony. I know v8 has an implementation, having used it in node (takes a command line flag) but not sure what the status is elsewhere.
- Void_ 15y agoThe biggest advantage of CoffeeScript is that it translates directly into JavaScript and it doesn't require any library to run after it's compiled.
- twism 15y agoI thought that this would be an advantage as well but what ended up happening is that I found myself spending a lot of time in the generated javascript. Either I was checking the generated javascript too often to see if it mapped to the coffescript I wrote, or I'm fixing bugs in the generated javascript forgetting that I was using coffescript.
- jlongster 15y agoAs far as I know, ClojureScript works the same way.
- jashkenas 15y agoNo, there's a very sizable and useful ClojureScript standard library: https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs https://github.com/clojure/clojurescript/blob/master/src/clj... ... the idea is that the parts of it you don't use will be optimized away by the Google Closure Compiler.
- raganwald 15y agoBoth CoffeeScript and ClojureScript “transpile” into JavaScript. ClojureScript does come with its own standard library just as you say. However, I don’t know if that’s CoffeeScript’s “biggest advantage,” althout it’s related. The way I would put it is that while the author claims that ClojureScript is “OO, the Good Parts,” CoffeeScript is JavaScript, The Good Parts. Meaning, CoffeeScript programming is still very close in mental model to JavaScript programming. This is why it doesn’t require its own library, you are writing JavaScript and can use any abstraction or library you like. Its syntax for OO programming is really sugar for using JavaScript’s built-in semantics in a legible way. Locally namespaced extensions are a wonderful idea, but they aren’t really JavaScript. For better or for worse, CoffeeScript eschews such deep departures from JavaScript. That’s a disadvantage when you want something that’s a big improvement, but it’s an advantage when you are familiar with JavaScript and just want to get things done.
- jlongster 15y agoI don't have any evidence to back this up, but I'm guessing that the only reason CoffeeScript embraces Javascript is for debugging. It firmly places itself as an "improved Javascript" which compiles out to "normal" Javascript -- so that you can sanely debug it, and sanely use the language. ClojureScript doesn't have this problem. It's normal Clojure code that (I assume) can be debugged like normal Clojure. EDIT: I haven't debugged ClojureScript yet, but I assume you can debug it like normal Clojure code.
- swannodette 15y agoWell ... sort of. The Clojure debugging story is still only OK and under development. Any ClojureScript debugging story really should integrate with existing tools - I have some ideas about that brewing here: http://dev.clojure.org/display/design/ClojureScript+Debugger http://dev.clojure.org/display/design/ClojureScript+Debugger
- jlongster 15y agoAh, I see. I'd probably take the route of allowing ClojureScript to be run as normal Clojure, but I guess the problem is that you don't have access to the browser environment. Debugging browser-based apps can be tricky because of that.
- Archos 15y agoBut the great disadvantage of those compilers (CoffeeScript and ClojureScript) is that the generated code doesn't matches up with the lines of the source code so its debugging is much more difficult.
- gtrak 15y agoKnowing no javascript, I didn't have a hard time debugging my first try at compiled-to-js clojurescript. It's pretty easy to see the naming correlations and conventions used by the compiler in the generated source.
- lazerwalker 15y agoI appreciated the look into ClojureScript as someone who's never touched it (and whose interest is definitely piqued now), but I'm baffled by the article's initial hook of 'let's compare how many characters it takes to accomplish the same task'. Is this really a meaningful metric? There's value in comparing the relative clarity and expressibility of each language, but that's not necessarily synonymous with brevity. I get that it's not the heart of the piece, but starting with such pedantry seems to detract from the point.
- Diederich 15y agoGranted, clarity and power aren't necessarily the same thing: http://www.paulgraham.com/power.html http://www.paulgraham.com/power.html
- vannevar 15y agoAnd brevity is not the same as either. I'd argue that the three are actually orthogonal.
- aidenn0 15y agoBrevity is not orthogonal to clarity; it is clear that overly verbose code is not as readable, just because e.g. it doesn't fit on your screen (or in your head) all at once.
- vannevar 15y agoI'd concede that. But it's still possible to have brief code that is less clear than verbose code.
- drostie 15y agoBrevity is a feature of clarity, and clarity usually attends very powerful notions like reuse and application to a new domain. What's truly orthogonal is some notion of "expressiveness" or "teachability" or otherwise being-able-to-read-and-understand. The example that you should think of here is mathematics papers. The ideas are stated in their clearest form, which usually is absurdly brief: lemma, theorem, proof. You can then spend about an hour poring over each line to figure out what the heck it's expressing, before suddenly a moment of clarity dawns on you and you see all of the connections together. Why would they write incomprehensibly? It's not because they don't want to be understood; these are peer-reviewed journals we're talking about here, and someone else must read and OK your work. But it's because when they make the fewest assumptions and the most broad argument, their work maximizes power and usability and robustness.
- jashkenas 15y agoOne man's "reusable abstraction" is another man's "why the hell is this thing being abstracted?" ... perhaps with Lisps more than anywhere else ;) For example, in David's final gist, we have: (defprotocol ISlice (-shift [this])) (deftype Slice [start end] ISlice (-shift [_] (Slice. (inc start) (inc end))) IFn (-invoke [_ x] (cond (string? x) (.substring x start end) (vector? x) (subvec x start end)))) (def s (Slice. 0 5)) (def v ["List Processing" [0 1 2 3 4 5 6]]) (map s v) ;; >> ("List " [0 1 2 3 4]) (map (-shift s) v) ;; >> ("ist P" [1 2 3 4 5]) When I think there's a good case to be made for the clarity of this alternative: slice = (start, end) -> (list) -> if typeof list is 'string' list.substring start, end else list.slice start, end vector = ["List Processing", [0, 1, 2, 3, 4, 5, 6]] vector.map slice 0, 5 # ["List ",[0,1,2,3,4]] vector.map slice 1, 6 # ["ist P",[1,2,3,4,5]] ... but with careful compile-to-JS languages, it's pretty great that each can do it their own way, and the resulting code can play nicely together.
- programnature 15y ago"But when our hypothetical Blub programmer looks in the other direction, up the power continuum, he doesn't realize he's looking up. What he sees are merely weird languages. He probably considers them about equivalent in power to Blub, but with all this other hairy stuff thrown in as well"
- cubicle67 15y agoyeah, I see what you're trying to do here, except you're calling Jeremy a blub programmer when he's anything but. it also comes off as a bit dickish to try and refute a point with (what amounts to) "I have more knowledge than you, and there's no point explaining because you wouldn't understand anyway"
- programnature 15y agoNot trying to refute anything. Just a passage that comes to mind when reading that opening sentence. Especially with the specific reference how that seems to be common occurrence with Lisp. In fact, you might argue that OP and PG are saying the same thing. Programming languages are habits of mind, and until you have real understanding of an abstraction, it's a lot easier to think "that looks weird, why don't I just use this other thing I already know".
- thatmiddleway 15y agoApparently these Clojurescript guys really love parenthesis...
- sukuriant 15y ago'(Really? I couldn\'t tell)
- ricardobeat 15y ago> We've extended all objects including numbers to respond to the bar function.We can provide more specific implementations at anytime, i.e. by using extend-type on string, array, Vector, even your custom types Mimicking that in javascript: Object.defineProperty Object.prototype, 'bar', value: -> 'whatever' 'foo'.bar() (1).bar() [1,2,3].bar() More specific implementations can be defined on the other prototypes. This is totally safe (except for oldIE). Making objects behave as functions (actually the opposite) is also possible: MagicHash = (props) -> f = (key) -> f[key] f[k] = v for k,v of props return f address = new MagicHash street: '1010 Foo Ave.' apt: '1111' city: 'Bit City' zip: '000000000' address.apt #> '1111' ['street', 'zip'].map address #> [ '1010 Foo Ave.', '000000000' ] or map = (fn, arr) -> arr.map fn map address, ['street', 'zip'] #> [ '1010 Foo Ave.', '000000000' ] And no, I have no idea how this could be useful...
- Tuna-Fish 15y ago>> We've extended all objects including numbers to respond to the bar function.We can provide more specific implementations at anytime, i.e. by using extend-type on string, array, Vector, even your custom types >Mimicking that in javascript: >This is totally safe (except for oldIE) No, not in his definition of safe it isn't. That's just monkeypatching -- the new functions are visible everywhere in the program, and it's entirely possible to be stung badly by name collisions. The ClojureScript version doesn't have these problems -- the protocol only exists in the namespaces where it is defined or imported.
- Archos 15y agoI prefer a sintaxis more expressive, concise and clean like Go's: package main type Foo struct { a, b, c int } func (f *Foo) bar(x int) int { return f.a + f.b + f.c + x } func main() { afoo := Foo{1, 2, 3} afoo.bar(3) }
- Archos 15y agoIf I've said that one, it is because there is a compiler from Go to JavaScript under (advanced) development with several advantages over another compilers: + The lines numbers in the unminified generated JavaScript match up with the lines numbers in the original source file. + Generates minimized JavaScript. + Allows many type errors to be caught early in the development cycle, due to static typing. https://github.com/kless/GoScript https://github.com/kless/GoScript