How to Programmatically Create Unqualified Keywords?

169 views
Skip to first unread message

Nick Mudge

unread,
Mar 21, 2018, 9:15:43 AM3/21/18
to Clojure
I want to programmatically create some keywords without namespaces?  Or are we not supposed to do that?

I can't use the "keyword" function because that only creates keywords with a namespace.  

For example doing this:
(keyword (str "something" "-empty"))
Creates this: 
::something-empty
But I want this:
:something-empty


Alex Miller

unread,
Mar 21, 2018, 9:32:53 AM3/21/18
to Clojure
I believe you are mistaken as the keyword function will create :something-empty in this case. 

::something-empty is really a reader syntax for :user/something-empty btw (where user is your current namespace), so it's not even possible to "create" a keyword like ::something-empty.

Nick Mudge

unread,
Mar 21, 2018, 9:42:11 AM3/21/18
to Clojure
Hi Alex,

Yes, you are right. I was mistaken. The "keyword" function does produce what I want. 

I didn't realized that in my code I was actually doing this: (keyword (str ":something" "-empty"))

The colon in front of "something" was making me make a namespaced keyword.  Removing the colon fixed my issue.

Thanks!

Nick Mudge

unread,
Mar 21, 2018, 9:48:31 AM3/21/18
to Clojure
I see what you mean.  All keywords are namespaced, so there really is no such thing as a no-namespaced keyword. Thank you.


On Wednesday, March 21, 2018 at 6:32:53 AM UTC-7, Alex Miller wrote:

Matteo Moci

unread,
Mar 21, 2018, 10:49:58 AM3/21/18
to clo...@googlegroups.com
Don't know about older clojure versions, but running your code in the 1.9 repl I got this: 
$ clj
Clojure 1.9.0
user=> (keyword (str "something" "-empty"))
:something-empty


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Matteo Moci
http://mox.fm

Mauricio Aldazosa

unread,
Mar 21, 2018, 11:10:12 AM3/21/18
to clo...@googlegroups.com
On Wed, Mar 21, 2018 at 7:48 AM, Nick Mudge <mud...@gmail.com> wrote:
I see what you mean.  All keywords are namespaced, so there really is no such thing as a no-namespaced keyword. Thank you.

You can have keywords without a namespace:
 
user> (clojure-version)
1.9.0
user> (keyword "bar" "foo")
:bar/foo
user> (namespace (keyword "bar" "foo"))
bar
user> (keyword "foo")
:foo
user> (namespace (keyword "foo"))
nil

Gary Verhaegen

unread,
Mar 22, 2018, 4:52:28 AM3/22/18
to clo...@googlegroups.com
I think there's some confusion here between the keyword and its textual representation.

The root issue is that the keyword function is, in a way, too lenient in its error checking: it will allow you to create keywords that are not valid according to the language definition. The Clojure reader is a bit more restrictive, though it too will allow a number of exceptions to the official definition on the main Clojure website.

For example, the reader will accept keywords with # or . in their name, which is used by some libraries to represent css ids and classes. These two characters are not valid in the name of a keyword as per the language definition.

The keyword function will let you create a keyword whose name starts with a colon, or whose name contains a space. These are not accepted by the reader and definitely do not match the language definition.

When you manually write ::hello in a Clojure file, the reader will interpret that as :user/hello, i.e. a keyword with user as its namespace and hello as its name. Neither the slash nor the colon are part of the keyword itself; they are just part of the syntax Clojure uses to represent keywords in a textual form.

With the keyword function, if you call (keyword ":hello"), you get a keyword that has ":hello" as a name. That is not valid data for that function, but it can be created in memory. There is, however, no syntax in Clojure that can correctly represent that keyword textually. If you try to print it, you will see ::hello, but that is fundamentally different from you writing ::hello. In other words you have created a keyword that does not roundtrip: if you print it and then read it, you will not get the same value again.

Similarly if you use the keyword function to create a keyword with a space, you will not be able to read it back as its textual representation will look like a keyword and a symbol.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to

For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.

Francis Avila

unread,
Mar 22, 2018, 5:38:50 AM3/22/18
to Clojure
keyword has two arities:

(keyword x) will attempt to parse "x" into a keyword with name and namespace parts.

(keyword namespace-part name-part) will make a keyword with name and namespace set explicitly.

So to create a keyword dynamically (i.e. not using literal syntax) and be absolutely sure namespace is nil, use (keyword nil "something-empty") in your example.

Note that the keyword function will happily create keywords whose printed form is either not readable (e.g. include a space, a digit in the wrong place, a bad character, etc) or would be read a different way (include a slash in the name part for e.g.). 

On Wednesday, March 21, 2018 at 8:15:43 AM UTC-5, Nick Mudge wrote:
Reply all
Reply to author
Forward
0 new messages