Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between :foo, ::foo, ::bar/foo, and :bar/foo in Clojure?

I came across those keywords: :foo, ::foo, ::bar/foo, and :bar/foo

Could you explain differences with examples?

like image 794
Ertuğrul Çetin Avatar asked Feb 06 '17 14:02

Ertuğrul Çetin


2 Answers

: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
like image 94
Josh Avatar answered Oct 06 '22 19:10

Josh


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.
  • The namespace of ::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 |
like image 39
Michiel Borkent Avatar answered Oct 06 '22 19:10

Michiel Borkent