ClojureCLR v2.2 Release Notes

  • ๐Ÿ‘ Reader Conditionals are a new capability to support portable code that can run on multiple Clojure platforms with only small changes. In ๐Ÿ‘ particular, this feature aims to support the increasingly common case of libraries targeting both Clojure and ClojureScript.

    Code intended to be common across multiple platforms should use a new ๐Ÿ‘Œ supported file extension: ".cljc". When requested to load a namespace, the platform-specific file extension (.clj, .cljs) will be checked prior to .cljc.

    A new reader form can be used to specify "reader conditional" code in cljc files (and only cljc files). Each platform defines a feature identifying the platform (:clj, :cljs, :cljr). The reader conditional specifies code that is read conditionally based on the feature. The REPL also allows reader conditionals.

    Form #? takes a list of alternating feature and expression. These are checked like cond and the selected expression is read and returned. Other branches are read but skipped. If no branch is selected, the reader reads nothing (not nil, but literally as if reading no form). An optional 0๏ธโƒฃ :default branch can be used as a fallthrough.

    0๏ธโƒฃ Reader conditional with 2 features and a default:

    #?(:clj     Double/NaN
       :cljs    js/NaN
       :default nil)
    

    There is also a reader conditional splicing form. The evaluated expression should be sequential and will be spliced into the surrounded code, similar to unquote-splicing.

    For example:

    [1 2 #?@(:clj [3 4] :cljs [5 6])]

    This form would read as [1 2 3 4] on Clojure, [1 2 5 6] on ClojureScript, and [1 2] on any other platform. Splicing is not allowed at the top level.

    โž• Additionally, the reader can now be invoked with options for the features 0๏ธโƒฃ to use and how to interpret reader conditionals. By default, reader conditionals are not allowed, but that can be turned on, or a "preserve" mode can be used to preserve all branches (most likely useful for tooling or source transforms).

    In the preserve mode, the reader conditional itself and any tagged literals within the unselected branches are returned as tagged literal data.

    ๐Ÿ‘€ For more information, see: http://dev.clojure.org/display/design/Reader+Conditionals