Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Zero penalty runtime assertions for Clojure.
Clojure Emacs Lisp Java
Latest commit 0949ef7 @pjstadig Fix typo in README.
Failed to load latest commit information.
src/pjstadig Initial commit.
.dir-locals.el Initial commit.
.gitignore Initial commit.
LICENSE.txt Initial commit. Fix typo in README.
project.clj Initial commit.


Zero penalty runtime assertions for Clojure.

Clojure’s built in assert macro is a compile-time construct that will eliminate assertions if *assert* is set to false. However, there isn’t a good way to set *assert* to false. You cannot set! it in your namespace, because that will fail when your code is loaded in any context where there isn’t an established binding for *assert* (AOT’ed code for one). Otherwise you could try to alter-var-root *assert* in a user.clj file, but that does not compose well. You can set a Java system property to configure some features of the Clojure compiler, but there doesn’t exist a property for disabling assertions.

Even if you could work that all out, what you have is still a compile-time assertion construct. Java’s assertions have the property that they can be enabled/disabled at runtime without any performance penalty.

My assertions work similar to Java’s. There is a pjstadig.Assertions class with a static final field that is initialized by calling desiredAssertionStatus for that class. When this static final field set to false and it is used in a conditional, then the body of that conditional (i.e. the assertion) is eliminated as dead code by the JIT.

To use this for a Leiningen project

[pjstadig/assertions "0.1.0"]

Or for a Maven project



(ns pjstadig.assertions.test
  (:refer-clojure :exclude [assert])
  (:require [pjstadig.assertions :refer [assert]]))

(defn -main [& [flag]]
  (assert (not= flag "fail")))

When you run the program with assertions enabled it throws an AssertionError:

~/src/assertions$ JVM_OPTS=-ea lein run -m pjstadig.assertions.test fail
Exception in thread "main" java.lang.AssertionError: (not= flag "fail")
        at pjstadig.assertions.test$_main.doInvoke(test.clj:14)
        at clojure.lang.RestFn.invoke(
        at clojure.lang.Var.invoke(
        at user$eval33.invoke(NO_SOURCE_FILE:1)
        at clojure.lang.Compiler.eval(
        at clojure.lang.Compiler.eval(
        at clojure.lang.Compiler.eval(
        at clojure.core$eval.invoke(core.clj:2852)
        at clojure.main$eval_opt.invoke(main.clj:308)
        at clojure.main$initialize.invoke(main.clj:327)
        at clojure.main$null_opt.invoke(main.clj:362)
        at clojure.main$main.doInvoke(main.clj:440)
        at clojure.lang.RestFn.invoke(
        at clojure.lang.Var.invoke(
        at clojure.lang.AFn.applyToHelper(
        at clojure.lang.Var.applyTo(
        at clojure.main.main(

When you run it with assertions disabled no AssertionError is thrown, and there is no penalty for including assertions in your code:

~/src/assertions$ lein run -m pjstadig.assertions.test fail

You can also enable/disable assertions specifically for the pjstadig package (e.g. -ea:pjstadig...), or the pjstadig.Assertions (e.g. -ea:pjstadig.Assertions) class. However, doing so will enable/disable assertions globally for any namespace that is using these assertions. There is currently no way to enable/disable assertions for individual Clojure namespaces.


Copyright © 2013 Paul Stadig. All rights reserved.

This Source Code Form is subject to the terms of the Mozilla Public License,
v. 2.0. If a copy of the MPL was not distributed with this file, You can
obtain one at

This Source Code Form is "Incompatible With Secondary Licenses", as defined
by the Mozilla Public License, v. 2.0.
Something went wrong with that request. Please try again.