3 ms·
Clojure deals with this by having strict namespaces. Every function and "global" variable belongs to a namespace. At any time, you can refer to a function by it
by arohner 18y ago
Clojure deals with this by having strict namespaces. Every function and "global" variable belongs to a namespace. At any time, you can refer to a function by it's fully qualified name. At the top of a namespace declaration, you can import other namespaces and alias (rename) other namespaces. It's a compile error if your declarations create an ambiguous name. i.e.
(ns :foo
(:use classifier)
(:use active-support))
Use allows you to call all of the functions in the namespace without a fully qualified name. In this case, there would be a compile error, because both use statements try to alias a function sum in the current namespace. The alternative would be to use require, which doesn't bring the functions into the current namespace:
(ns :foo
(:require classifier)
(:require [active-support :as as]))
Then you call the two sum functions like
(classifier/sum [1 2 3 4])
(as/sum [1 2 3 4])
The huge advantage is that since there are only functions, there are no methods on objects and every function is subject to namespacing.
If you want to monkey patch, there is a function called binding, which changes the value of a variable, but only within the calling scope, in the current thread. i.e.
(def x 3)
(println "x = " x)
(binding [x 5]
(println "x = " x))
(println "x = " x)
will return
=> 3
=> 5
=> 3
Since named functions are just anonymous functions stored in variables, you can use the binding trick to monkey patch. It's very clean because you can't interfere with any other code.
Binding affects fully qualified vars, which makes it very difficult to stomp on someone else's function.