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

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

Could you explain the differences with examples?

+5
source share
2 answers

:foo is a keyword that is not fully qualified. It does not have a namespace associated with it.

 (name :foo) ; => "foo" (namespace :foo) ; => nil 

:bar/foo is the keyword matching the keyword. Namespace bar and keyword name 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 a "user":

 *ns* ; => #namespace[user] (name ::foo) ; => "foo" (namespace ::foo) ; => "user" ::foo ; => :user/foo 

::bar/foo will try to expand any aliases to make it fully accessible:

 (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 
+10
source

This article explains this well.

TL DR:

  • :foo is a keyword without a namespace, i.e. unskilled keyword.
  • :foo/bar is a keyword with an explicit namespace foo .
  • ::foo is an automatically assigned keyword. If this keyword occurs in the bar namespace, it evaluates to :bar/foo .
  • The namespace ::bar/foo same as :baz/foo if the namespace bar :as baz is required.

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 | 
+3
source

Source: https://habr.com/ru/post/1263881/


All Articles