On Nov 10, 2009, at 9:08 PM, John Harrop wrote:
(ns foo.bar.baz (:use [clojure.contrib.core :only (seqable?)]))(and thus violates the usual clojure rule of using vectors rather than lists for groupings that are not invocations -- that is, function calls, macro calls, or special form calls).
I agree it's too complicated and that examples would help.Rich has also encouraged a look at simplifying the whole thing in the past and I would like to work on that.
Here are some of the ideas I've liked best for how to do it.- replace :use, :require, and :load with one common thing with good conventions and easy ways to configure away from convention
- maybe call it :uses- require that each "libspec" (reference to a lib) be a vector, disallowing naked symbols and prefix extraction via prefix lists. This would mean that everything after :uses will be a vector which is known to be a complete specification of the dependency's name and how this lib uses it. (This regularity would help humans understand and outside- of-Clojure tools have an easier time parsing.)
- don't "refer" any names from the target namespace into the current namespace by default
- support ":only []", ":rename {}", ":exclude []", and ":refer-all true" options
(:refer-all true is not strictly necessary as it's a synonym for :exclude [], but the latter is much less clear to the human reader)
- automatically alias the leaf name of the lib as a reference to the lib:
- (:uses [clojure.contrib.jmx]) would allow referring to the names in clojure.contrib.jmx by prefixing them with jmx/
- disallow conflicts in leaf names, requiring one or the other lib to have an ":as" option giving another alias
- open question as to whether using :only, :rename, :exclude, or :refer-all would suppress the automatic alias and require an explicit :as if an alias is also desired.
- remove the special ":refer-clojure" clause in favor of an optional "[clojure.core]" within :uses that changes the default for clojure.core away from ":refer-all true"
- (based on this thread) require that all seqs within :uses be vectors rather than lists.
Here is a portion of an ns form before and after these changes:
Before:
(:refer-clojure :exclude [read])
(:require (clojure.contrib [graph :as graph] [fcase :as fcase])
[clojure.contrib.stream-utils :as su])
(:use [clojure.contrib def except server-socket]
clojure.contrib.lazy-xml
[clojure.contrib.java-utils :only [as-str]]
[clojure.stacktrace :only (root-cause)]
[clojure.walk :only [postwalk]])
After:
(:uses [clojure.core :exclude [read])
[clojure.contrib.graph]
[clojure.contrib.fcase]
[clojure.contrib.stream-utils :as su]
[clojure.contrib.def :refer-all true]
[clojure.contrib.except :refer-all true]
[clojure.contrib.server-socket :refer-all true]
[clojure.contrib.lazy-xml :refer-all true]
[clojure.contrib.java-utils :only [as-str]]
[clojure.stacktrace :only [root-cause]]
[clojure.walk :only [postwalk]])
(Over time I would expect many ":refer-all true" options to become
more selective references once this change makes referencing in
everything slightly more difficult.)
I'd appreciate hearing ideas and critiques. --Steve
smime.p7s
Description: S/MIME cryptographic signature
