such.casts

“Be conservative in what you send, be liberal in what you accept.”
(Postel’s Robustness Principle)

Some Clojure functions require specific types of arguments, such as a symbol representing a namespace. You can use the following functions to convert from what you’ve got to what Clojure requires. Or you can use them to build more accepting variants of those Clojure functions.

as-namespace-and-name-symbols

(as-namespace-and-name-symbols val)

val is something that can be thought of as having namespace and name parts. This function splits val and returns those two parts as symbols, except that the namespace may be nil. Accepts symbols, keywords, vars, and strings containing at most one slash.

(as-namespace-and-name-symbols 'clojure.core/even?) => ['clojure.core 'even?]
(as-namespace-and-name-symbols :foo) => [nil 'foo]

(as-namespace-and-name-symbols #'even) => ['clojure.core 'even?]

(as-namespace-and-name-symbols "even?") => [nil 'even?]
(as-namespace-and-name-symbols "clojure.core/even?") => ['clojure.core 'even?]
(as-namespace-and-name-symbols "foo/bar/baz") => (throws)

as-ns-symbol

(as-ns-symbol arg)

Returns a symbol with no namespace. Use with namespace functions that require a symbol (find-ns, etc.) or to convert the result of functions that return the wrong sort of reference to a namespace. (For example,(namespace 'a/a) returns a string.)

The argument must be a namespace, symbol, keyword, or string. In the latter three cases, arg must not have a namespace. (But see extract-namespace-into-symbol.) (Note: strings have “namespaces” if they contain exactly one slash. See as-namespace-and-name-symbols.)

The result is a symbol with no namespace. There are two cases:

  1. If arg is a namespace, its symbol name is returned:

    (as-ns-symbol ns) => ’such.casts

  2. Otherwise, the arg is converted to a symbol:

    (as-ns-symbol "clojure.core") => 'clojure.core
    (as-ns-symbol 'clojure.core) => 'clojure.core
    (as-ns-symbol :clojure.core) => 'clojure.core
    

as-string-without-namespace

(as-string-without-namespace arg)

The argument must be a symbol, string, keyword, or var. The result is a string name that omits the namespace:

 (as-string-without-namespace 'clojure/foo) => "foo"      ; namespace omitted
 (as-string-without-namespace #'even?) => "even?"
 (as-string-without-namespace :bar) => "bar"              ; colon omitted.
 (as-string-without-namespace :util.x/quux) => "quux"     ; "namespace" omitted
 (as-string-without-namespace "util.x/quux") => "quux"  ; "namespace" omitted

as-symbol-without-namespace

(as-symbol-without-namespace arg)

The argument must be a symbol, string, keyword, or var. In all cases, the result is a symbol without a namespace:

(as-symbol-without-namespace 'clojure.core/even?) => 'even?
(as-symbol-without-namespace #'clojure.core/even?) => 'even?
(as-symbol-without-namespace :clojure.core/even?) => 'even?
(as-symbol-without-namespace :even?) => 'even?
(as-symbol-without-namespace "even?") => 'even?
(as-symbol-without-namespace "core.foo/bar") => 'bar

Use with namespace functions that require a symbol (ns-resolve, etc.)

extract-namespace-into-symbol

(extract-namespace-into-symbol arg)

Extract the namespace from arg.

The argument must be a namespace, symbol, keyword, or string. In the latter three cases, arg must have a namespace. (Note: strings have “namespaces” if they contain exactly one slash.)

The result is a symbol with no namespace. There are two cases:

  1. If arg is a namespace, its symbol name is returned:

    (extract-namespace-into-symbol ns) => ’such.casts

  2. Otherwise, the “namespace” of the arg is converted to a symbol:

    (extract-namespace-into-symbol "clojure.core/even?") => 'clojure.core
    (extract-namespace-into-symbol 'clojure.core/even?) => 'clojure.core
    (extract-namespace-into-symbol :clojure.core/even?) => 'clojure.core
    

has-namespace?

(has-namespace? arg)

arg must satisfy named? (string or clojure.lang.Named). Returns true iff the arg has a non-nilnamespace. For a string, “has a namespace” means it contains exactly one slash - the part before the slash is considered the namespace.

(has-namespace? :foo) => false
(has-namespace? ::foo) => true
(has-namespace? 'clojure.core/even?) => true
(has-namespace? "clojure.core/even?") => true