Mercurial > lasercutter
diff src/clojure/contrib/macros.clj @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/clojure/contrib/macros.clj Sat Aug 21 06:25:44 2010 -0400 1.3 @@ -0,0 +1,84 @@ 1.4 +;; Various useful macros 1.5 +;; 1.6 +;; Everybody is invited to add their own little macros here! 1.7 +;; 1.8 +;; The use and distribution terms for this software are covered by the 1.9 +;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) 1.10 +;; which can be found in the file epl-v10.html at the root of this 1.11 +;; distribution. By using this software in any fashion, you are 1.12 +;; agreeing to be bound by the terms of this license. You must not 1.13 +;; remove this notice, or any other, from this software. 1.14 + 1.15 +(ns 1.16 + ^{:author "Konrad Hinsen" 1.17 + :doc "Various small macros"} 1.18 + clojure.contrib.macros) 1.19 + 1.20 +;; By Konrad Hinsen 1.21 +(defmacro const 1.22 + "Evaluate the constant expression expr at compile time." 1.23 + [expr] 1.24 + (eval expr)) 1.25 + 1.26 +;; By Konrad Hinsen 1.27 +; This macro is made obsolete by Clojure's built-in letfn. I renamed it to 1.28 +; letfn- (to avoid a name clash) but leave it in for a while, since its 1.29 +; syntax is not quite the same as Clojure's. Expect this to disappear 1.30 +; in the long run! 1.31 +(defmacro letfn- 1.32 + "OBSOLETE: use clojure.core/letfn 1.33 + A variant of let for local function definitions. fn-bindings consists 1.34 + of name/args/body triples, with (letfn [name args body] ...) 1.35 + being equivalent to (let [name (fn name args body)] ...)." 1.36 + [fn-bindings & exprs] 1.37 + (let [makefn (fn [[name args body]] (list name (list 'fn name args body))) 1.38 + fns (vec (apply concat (map makefn (partition 3 fn-bindings))))] 1.39 + `(let ~fns ~@exprs))) 1.40 + 1.41 + ;; By Konrad Hinsen 1.42 + 1.43 + (defn- unqualified-symbol 1.44 + [s] 1.45 + (let [s-str (str s)] 1.46 + (symbol (subs s-str (inc (.indexOf s-str (int \/))))))) 1.47 + 1.48 +(defn- bound-var? 1.49 + [var] 1.50 + (try 1.51 + (do (deref var) true) 1.52 + (catch java.lang.IllegalStateException e false))) 1.53 + 1.54 +(defn- fns-from-ns 1.55 + [ns ns-symbol] 1.56 + (apply concat 1.57 + (for [[k v] (ns-publics ns) 1.58 + :when (and (bound-var? v) 1.59 + (fn? @v) 1.60 + (not (:macro (meta v))))] 1.61 + [k (symbol (str ns-symbol) (str k))]))) 1.62 + 1.63 +(defn- expand-symbol 1.64 + [ns-or-var-sym] 1.65 + (if (= ns-or-var-sym '*ns*) 1.66 + (fns-from-ns *ns* (ns-name *ns*)) 1.67 + (if-let [ns (find-ns ns-or-var-sym)] 1.68 + (fns-from-ns ns ns-or-var-sym) 1.69 + (list (unqualified-symbol ns-or-var-sym) ns-or-var-sym)))) 1.70 + 1.71 +(defmacro with-direct-linking 1.72 + "EXPERIMENTAL! 1.73 + Compiles the functions in body with direct links to the functions 1.74 + named in symbols, i.e. without a var lookup for each invocation. 1.75 + Symbols is a vector of symbols that name either vars or namespaces. 1.76 + A namespace reference is replaced by the list of all symbols in the 1.77 + namespace that are bound to functions. If symbols is not provided, 1.78 + the default value ['clojure.core] is used. The symbol *ns* can be 1.79 + used to refer to the current namespace." 1.80 + {:arglists '([symbols? & body])} 1.81 + [& body] 1.82 + (let [[symbols body] (if (vector? (first body)) 1.83 + [(first body) (rest body)] 1.84 + [['clojure.core] body]) 1.85 + bindings (vec (mapcat expand-symbol symbols))] 1.86 + `(let ~bindings ~@body))) 1.87 + 1.88 \ No newline at end of file