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

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to