Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Reader conditionals

Reader conditionals allow a single source file to contain code for multiple Clojure platforms. clojurust evaluates the :rust branch.

Syntax

Non-splicing form

#?(:rust   expr-rust
   :clj    expr-jvm
   :cljs   expr-clojurescript
   :default expr-fallback)

Exactly one branch is selected at read time based on the current platform. For clojurust, :rust is matched first. If no :rust key is present, :default is used. If neither is present, the entire form is skipped (reads as nothing).

The selected branch is a single expression; the whole #?(...) form evaluates to that expression.

(def platform #?(:rust   "clojurust"
                 :clj    "JVM Clojure"
                 :cljs   "ClojureScript"
                 :default "unknown"))

Splicing form

#?@(:rust   [a b c]
    :clj    [x y z]
    :default [])

The splicing form #?@(...) selects a vector from the active platform and splices its elements into the surrounding form. It is only valid inside a list, vector, map, or set literal.

;; Adds platform-specific items to a vector
(def features [#?@(:rust   [:gc :cranelift]
                   :clj    [:jvm :hotspot]
                   :default [])])
; => [:gc :cranelift]  (on clojurust)
;; Platform-specific require in an ns form
(ns myapp.core
  (:require [clojure.string :as str]
            #?@(:rust [[:clojurust.system :as sys]]
                :clj  [[:java.lang.System :as sys]])))

File-extension behaviour

ExtensionPlatform dispatch
.cljrsAlways :rust. Reader conditionals are still supported but :rust is always the active branch.
.cljcCross-platform. Reader conditional branches are stored as-is; the evaluator selects :rust.

Notes

  • The reader stores all branches of a #?(...) form; only the evaluator discards non-matching branches. This means reader-conditional forms can be inspected programmatically without losing the other branches.
  • Order within a reader conditional matters: keys are checked left-to-right. :default should come last.
  • Unlike Clojure, there is no :cljr (ClojureCLR) platform; the clojurust key is :rust.