-
Notifications
You must be signed in to change notification settings - Fork 15
Differences from Clojure
What follows is a section-by-section review of the sections on the left nav 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.
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 alphas 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
.
- 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 or STM
- the user experience of binding is similar to Clojure, but the implementation details are different
- there are no Vars
- def produces ordinary JS variables
- binding works on ordinary JS variables
- agents may be implemented in the future
- vars are not reified at runtime (i.e. no Vars)
- many development time uses of reification are obviated by access to Clojure data structures via the analyzer
- 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.
-
main
support TBD
- ClojureScript has the same evaluation rules as Clojure
- load and load-file work as in Clojure (TODO ?)
- runtime eval is not supported in ClojureScript
- vars are not reified at runtime, and the var special form is not implemented
- def produces ordinary JS variables
- monitor-enter, monitor-exit, and locking are not implemented
The following ClojureScript special forms are identical to their Clojure cousins: if, do, let, quote, loop, recur, throw, and try.
- def differences
- No runtime metadata is placed on vars: there are no vars in ClojureScript
-
:private
is not yet enforced by the compiler - if differences
- the section about Java's boolean boxes is irrelevant in ClojureScript
- var special form does not exist in ClojureScript
- fn differences
- currently no runtime enforcement of arity when calling a fn
- TODO pre- and post- conditions?
- monitor-enter and monitor-exit do not exist in ClojureScript
Macros are Clojure macros, and are available only during compilation.
- printing
- TODO is there an out?
- regex support
- TODO is there a difference to document here?
- Numbers
- In the first release, numbers are just JavaScript numbers.
- Later releases will provide more Clojure-equivalent numeric types.
- Coercions are not implemented, since there are no types to coerce to (yet).
- Characters
- JavaScript has no character type. Clojure characters are represented internally as strings.
- Collections
- In the first release, some immutable collections are copy-on-write.
- Later releases will have Clojure-equivalent persistent collections.
- Most but not all collection fns are implemented. See the "Not Implemented" section below.
Seqs have the same semantics as in Clojure, and almost all Seq library functions are available in ClojureScript.
The apply
function works but does not correctly handle lazy sequences. To be fixed; see #11
Transients are not implemented at this time.
Multimethods are not implemented at this time.
-
defprotocol
anddeftype
,extend-type
,extend-protocol
work 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
, andextend
are not implemented yet.
Works as in Clojure
- You must use
ns
form. - Namespace
:use
is not supported. - You must use the
:as
form of:require
. - The only option for
:refer-clojure
is:exclude
. - Macros are written in Clojure, and are referenced via the new
:require-macros
option to ns.
Existing Clojure libs will have to conform to the ClojureScript subset in order to work in ClojureScript.
-
def
andbinding
work 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.
- TODO What about doc and find-doc?
Refs and tranasactions are not currently supported.
Agents are not currently supported.
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 different is in calling no-argument functions. 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 et al are unnecessary and unimplemented in ClojureScript.
ClojureScript currently includes the following non-core namespaces ported from Clojure:
- clojure.set
- clojure.string
ClojureScript is the same (at a Lisp level) as Clojure.
Clojure and ClojureScript share the same Contributor Agreement and development process.
TODO: link to list in repos