Error formatting macro: pagetree: java.lang.NullPointerException
Skip to end of metadata
Go to start of metadata
You are viewing an old version of this page. View the current version. Compare with Current  |   View Page History

Motivation

It is easy to change the values of compile-time vars like *warn-on-reflection* and *unchecked-math* from a particular point in a file until the end of the file with set!.  You can also change the value of one of these vars for one top-level form by setting it to a desired value before the top-level form, and then setting its value back to the original after that top-level form.

However, there are cases where it would be desirable to change the value of such a var for an individual expression.

  1. For example, you may want *unchecked-math* to be true for part of a function's definition, either a few individual subexpressions, or a larger part of it.
  2. Another is that you want *warn-on-reflection* to be true for most of your library, but there are a few instances of reflection that you are aware of and either they cannot be eliminated, or they are rare enough in practice that they are not a performance problem.  You want to mark the expressions using reflection so that they do not cause a compile-time warning, but you want such warnings enabled everywhere else in that same function in case future changes introduce a new use of reflection.

Proposal

Introduce a new special form in Clojure called compile-time-let that takes a vector of bindings, and makes those bindings active in the textual scope of the compile-time-let expression during compile time.  For example:

 

;; I know it is easy to eliminate reflection in this simple example.
;; Imagine a case where it was impossible or undesirable to eliminate reflection.

(defn recip [x]
(if (ratio? x)
(compile-time-let [*warn-on-reflection* false]
(/ (.denominator x) (.numerator x)))
(/ 1 x)))

 

The following macro known-reflection could also be added to shorten disabling *warn-on-reflection*, if that became a common case:

 

(defmacro known-reflection [& body]
`(compile-time-let [~'*warn-on-reflection* false]
~@body))

 

With such a macro the definition of recip above could be rewritten:

 

(defn recip [x]
(if (ratio? x)
(known-reflection (/ (.denominator x) (.numerator x)))
(/ 1 x)))

 

Discussions on the clojure-dev group:

Thread with subject "Proposal for *warn-on-reflection* to be true by default" begun on Feb 25, 2012:

http://groups.google.com/group/clojure-dev/browse_frm/thread/5053bcb07ab33261

Thread with subject "Arbitrary subexpressions with custom compiler flags" begun on Mar 20, 2012:

http://groups.google.com/group/clojure-dev/browse_frm/thread/d14692f8c825d27f

Labels: