I came across those keywords: :foo, ::foo, ::bar/foo, and :bar/foo
Could you explain differences with examples?
:foo
is a non-fully-qualified keyword. It has no namespace associated with it.
(name :foo) ; => "foo"
(namespace :foo) ; => nil
:bar/foo
is a namespace-qualified keyword. The namespace is bar
, and the name of the keyword is foo
(name :bar/foo) ; => "foo"
(namespace :bar/foo) ; => "bar"
::foo
will associate the current namespace with the keyword, making it fully qualified. Assuming the current namespace is "user":
*ns* ; => #namespace[user]
(name ::foo) ; => "foo"
(namespace ::foo) ; => "user"
::foo ; => :user/foo
::bar/foo
will attempt to expand any aliases to make it fully qualified:
(create-ns 'my.namespace) ; => #namespace[my.namespace]
(alias 'bar 'my.namespace) ; => nil
(name ::bar/foo) ; => "foo"
(namespace ::bar/foo) ; => "my.namespace"
::bar/foo ; => :my.namespace/foo
This article explains it well.
TL;DR:
:foo
is a keyword without a namespace, i.e. an unqualified keyword.:foo/bar
is a qualified keyword with an explicit namespace foo
.::foo
is an automatically qualified keyword. If this keyword occurs within a namespace bar
, it is evaluated to :bar/foo
.::bar/foo
is the same as :baz/foo
if you require the namespace bar :as baz
. In code:
boot.user=> (ns foo)
nil
foo=> (ns bar (:require [foo :as f]))
nil
bar=> (def examples [:foo ::foo ::f/foo :bar/foo])
#'bar/examples
bar=> examples
[:foo :bar/foo :foo/foo :bar/foo]
bar=> (use 'clojure.pprint)
nil
bar=> (print-table (map (fn [example]
{:key example :namespace (namespace example)
:name (name example)})
examples))
| :key | :namespace | :name |
|----------+------------+-------|
| :foo | | foo |
| :bar/foo | bar | foo |
| :foo/foo | foo | foo |
| :bar/foo | bar | foo |
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With