max is built in by the Clojure compiler for arities greater than 1, so there is no reference to Var #'clojure.core/max in the compiled code and there is no way to change the behavior of code fragments that use #'max by changing the root binding. For arity 1, this does not happen:
(defn my-max [& args] :foo) (with-redefs [clojure.core/max my-max] (max 0)) ;= :foo (with-redefs [clojure.core/max my-max] (max 0 1)) ;= 1 (with-redefs [clojure.core/max my-max] (max 0 1 2)) ;= 2 ;; and so on
This is controlled by the entries on the keys :inline and :inline-arities in the max source; see (source max) .
clojure.core has quite a few automatically built-in functions - basically simple arithmetic operations. Client code is free to define new ones (by adding explicit metadata :inline and possibly :inline-arities or using definline ). The expected effect is similar to the definition of a macro, except that the built-in function is still available to use a higher order. It is important to note that the current implementation has its surprises (see CLJ-1227 in Clojure JIRA, for example, and the latest problems associated with it), so at the end of the day for the client code, careful use of regular macros and functions of the concurrent user is likely to be preferable on this moment. In the future, built-in functions may be replaced by regular functions related to compiler macros - this is the ClojureScript model.
MichaΕ Marczyk
source share