-
Notifications
You must be signed in to change notification settings - Fork 1
Differences from Clojure
What follows is a section-by-section review of the sections on the left-hand navigation panel of http://clojure.org, enumerating what is different in ClojureScript.
The rationale for ClojureScript is much the same as for Clojure, with JavaScript in the role of platform, and additional emphasis on the reach of JS, as it is obviously not as rich a platform.
A deeper discussion on ClojureScript's rationale can be found elsewhere on this site.
Same as Clojure. Clojure's identity model is simpler and more robust than mutable state, even in single threaded environments.
ClojureScript's REPL can be launched from within the Clojure REPL. See Quick Start for details.
ClojureScript has the same immutable collections, but the alpha versions are not necessarily persistent. Persistent versions will be added over time.
ClojureScript's macros are written in Clojure, and are referenced via
the refer-macros keyword in namespace declarations:
(ns my.namespace
(:refer-macros '[my.macros :as my])
The :as prefix selector is required in :refer-macros. One point of note is that the code generated by ClojureScript macros must target the capabilities in ClojureScript.
- ClojureScript protocols have the same semantics as Clojure protocols.
- Multimethods are not yet implemented, but are on the development Roadmap.
Clojure's model of values, state, identity, and time is valuable even in single-threaded environments.
- Atoms work as in Clojure
- No Refs nor STM
- The user experience of
bindingis similar to that in Clojure- There are no Vars
- not reified at runtime
- many development time uses of reification are obviated by access to Clojure data structures via the analyzer
-
defproduces ordinary JS variables
- There are no Vars
- Agent implementation is on the development Roadmap
- ClojureScript is hosted on JavaScript VMs
- Optionally, it may use Google's Closure compiler for optimization
- It is designed to leverage Google's Closure library, and participates in its dependency/require/provide mechanism
See Quick Start
TODO
- See Quick Start for instructions the ClojureScript REPL.
-
mainsupport on the development Roadmap
- ClojureScript has the same evaluation rules as Clojure
-
loadandload-fileare on the development Roadmap - Runtime
evalis not supported in ClojureScript
- Vars are not reified at runtime, and the
varspecial form is not implemented -
defproduces ordinary JS variables -
monitor-enter,monitor-exit, andlockingare not implemented, nor are they planned
The following ClojureScript special forms are identical to their Clojure
cousins: if, do, let, quote, loop, recur, throw, and try.
-
defnotes- No runtime metadata is placed on vars since there are no vars in ClojureScript
-
:privatemetadata is not yet enforced by the compiler
-
ifnotes- the section about Java's boolean boxes is irrelevant in ClojureScript
-
varspecial form does not exist in ClojureScript -
fnnotes -
monitor-enter,monitor-exit, andlockingare not implemented, nor are they planned
Macros are Clojure macros, and are available only during compilation (i.e. they are compiler macros, similar to those found in Common Lisp)
- printing
- TODO is there an
*out*? - regex support
- TODO is there a difference to document here?
- Numbers
- Characters
- JavaScript has no character type. Clojure characters are represented internally as single-character strings
- Collections
- In the first release, some immutable collections are copy-on-write
- Later releases will have Clojure-equivalent persistent collections
- Support for this in on the development Roadmap
- Most but not all collection fns are implemented
- Seqs have the same semantics as in Clojure, and almost all Seq library functions are available in ClojureScript.
- The
applyfunction works but does not correctly handle lazy sequences- Support for this in on the development Roadmap and more information can be found on ticket #11
Transients are not implemented at this time (Support for this in on the development Roadmap)
Multimethods are not implemented at this time (Support for this in on the development Roadmap)
-
defprotocolanddeftype,extend-type,extend-protocolwork as in Clojure - Protocols are not reified as in Clojure, there are no runtime protocol objects
- Some reflective capabilities (
satisifies?) work as in Clojure-
satisfies?is a macro and must be passed a protocol name
-
-
defrecord,reify, andextendare not implemented yet- Support for this in on the development Roadmap
Works as in Clojure
- You must currently use the
nsform only with the following caveats-
:useis not supported - You must use the
:asform of:require - The only option for
:refer-clojureis:exclude
-
- Macros are written in Clojure, and are referenced via the new
:require-macrosoption to ns
Existing Clojure libs will have to conform to the ClojureScript subset in order to work in ClojureScript
-
defandbindingwork as in Clojure- but on ordinary js variables
- Atoms work as in Clojure
- Refs and Agents are not currently implemented
- Validators work as in Clojure
-
docandfind-doc- Support for this in on the development Roadmap
Refs and tranasactions are not currently supported.
Agents are not currently supported. (Support for this in on the development Roadmap)
Atoms work as in Clojure.
The host language interop features (new, /, ., etc.) work as in Clojure where possible, e.g.:
goog/LOCALE
=> "en"
(let [sb (goog.string.StringBuffer. "hello, ")]
(.append sb "world")
(. sb (toString)))
=> "hello, world"
The one important difference is in calling no-argument methods. In Java (. x toString), where toString is a method, would unambiguously mean "call the toString method of x". JavaScript is more flexible, separating "method" lookup from invocation. So in ClojureScript you have to make a choice:
(. sb toString) => returns a function
(. sb (toString)) => calls the function
Note the latter form is supported in standard Clojure, but rarely used.
Compilation is different from Clojure:
- All ClojureScript programs are compiled into (optionally optimized) JavaScript.
- Individual files can be compiled into individual JS files for analysis of output
- Production compilation is whole-program compilation via Google Closure compiler
-
gen-class,gen-interface, etc. are unnecessary and unimplemented in ClojureScript
ClojureScript currently includes the following non-core namespaces ported from Clojure:
clojure.setclojure.stringclojure.walkclojure.zip
ClojureScript is the same (at a Lisp level) as Clojure except for the absence of runtime evaluation.
Clojure and ClojureScript share the same Contributor Agreement and development process.