Fork me on GitHub
Alex Miller (Clojure team)16:10:21

“doesn’t work” == ?


disregard, being stupid again. 😞


i was getting compiler errors and it was mostly unrelated (missing spec definition further up the chain)


:foo/1 won't read; using a bare number as the name part in a keyword literal is a bad idea


that it works at all is an historical accident, and it wasn't fixed because it was noticed too late


is ::1 equally a bad idea?


yes, so is :1


think "would this be a readable symbol if I chopped off the initial :s?"


well, isn’t {:1 true} a valid map?


I'm just talking about literals


hm, i have to digest this because it’s not making sense. are you saying that ::1 ultimately just becomes my.namespace/1 and thus {1 true}?


:thumbsup: thanks


I am saying clojure does not have a strict formal grammar for keywords and symbols, only human descriptions and implementations; using numbers is a greyer, edgier case that risks you falling into implementation-specific behavior


but that's just my opinion


no core member has confirmed or clarified to my knowledge


Clojure 1.9.0
user=> {::1 1}
#:user{:1 1}
user=> {:1 1}
{:1 1}
user=> #:user{:1 1}
#:user{:1 1}
user=> {:user/1 1}
RuntimeException Invalid token: :user/1  clojure.lang.Util.runtimeException (
RuntimeException Unmatched delimiter: }  clojure.lang.Util.runtimeException (

😂 4

I think this started it all

Alex Miller (Clojure team)16:10:04

well I’m a core member and I wrote that ticket and patch

Alex Miller (Clojure team)16:10:28

the original intent was that keywords follow the same constraints as symbols

Alex Miller (Clojure team)16:10:38

symbols cannot start with a leading digit

Alex Miller (Clojure team)16:10:08

the regex for keywords is subtly incorrect and allows keywords to have a leading digit

Alex Miller (Clojure team)16:10:33

by “fixing” that we discovered that people were using such things (at the time java.jdbc made result set keywords like that for example)

Alex Miller (Clojure team)16:10:04

there did not seem to be any good reason to break people’s existing working code so we rolled that back

Alex Miller (Clojure team)16:10:06

so it’s possible to read and use :1 and ::1 and we have no plans to make that stop working


it's deliberately not specifically allowed, however?


by specifications

Alex Miller (Clojure team)16:10:45

I would say that’s never been resolved

Alex Miller (Clojure team)16:10:20

CLJ-1527 is the ticket to do so


> Keywords - Keywords are like symbols, except: > They can and must begin with a colon, e.g. :fred. > They cannot contain '.' or name classes.

Alex Miller (Clojure team)16:10:35

“resolving” means making that reference page and the code in sync

Alex Miller (Clojure team)16:10:52

but the first question is what should be allowed

Alex Miller (Clojure team)16:10:10

there are plenty of other open areas for characters that are allowed in the reader but not explicitly allowed in the reference docs


two things: 1) "are like symbols" seems to cause confusion about whether what follows includes or does not include the initial colons. that was what my comment in cljs-667. 2) keywords can't have '.'? even in the ns part? (I know putting them in the name part is discouraged because that looks like class names). That's definitely wrong?

Alex Miller (Clojure team)16:10:09

keywords can definitely have dots in the namespace part


any way to fix those docs short of a jira patch?


"They cannot contain '.' after the first '/' or name classes" suggested edit

Alex Miller (Clojure team)16:10:19

It says “or in namespace names” ?


"keywords are like symbols, except: They cannot contain '.' or name classes." is what it says now

Alex Miller (Clojure team)16:10:13

oh, sorry I was looking at the symbol part


"are like symbols" is the handwavy part that I think causes most of the confusion

Alex Miller (Clojure team)16:10:16

I’ll look at an edit to that, but the intent again is to be similar to symbols and allow dots in namespaces

Alex Miller (Clojure team)16:10:06

agreed - the question is whether to describe two things as similar and then indicate differences or to restate, obscuring the differences

Alex Miller (Clojure team)16:10:18

I don’t feel that there is any ambiguity in intent that keyword namespaces should allow .


specifically "Symbols begin with a non-numeric character" combined with "keywords are like symbols" causes one to wonder, "does a keyword begin with : or the char after that"?

Alex Miller (Clojure team)16:10:38

well that is exactly the bug in the regex

Alex Miller (Clojure team)16:10:49

but I would say after the colon


the intent of the spec being: "expand ::, chop off the first :, and you should have a valid symbol literal"

Alex Miller (Clojure team)16:10:33

if you ask for the namespace and name parts of a keyword, you don’t see a colon. the colon is syntactical

Alex Miller (Clojure team)16:10:08

I don’t think that’s a semantically meaningful operation, so I wouldn’t describe it that way


what I mean is the intuitive sense of a valid keyword was intended to be "does it look like a symbol if the colons that make it a keyword were removed"


or at least thats how I am interpreting what you are saying.

Alex Miller (Clojure team)16:10:31

I understand what you mean. I just wouldn’t describe it that way


I think that's a little better than "keywords are like symbols," but still inappropriate for a capital-S "specification"


but I am glad I've discovered the authorial intent behind that phrase


That :a/b.c reads is an accident of history/implementation?


That isn't supposed to work?!

Alex Miller (Clojure team)17:10:19

I’d say that’s not supported in either symbols or keywords. whether it reads is a separate question


expound question: I try to make a custom print function:

(alter-var-root #'s/*explain-out*
                   {:show-valid-values? false
                    :value-str-fn my-value-str
                    :print-specs? true}))
but I get:
Unhandled clojure.lang.ExceptionInfo
   Unknown data:

   {:data #function[clojure.spec.test.alpha/spec-checking-fn/fn--3026]}
what up?


hmm, no matter what options I give, custom-printer doesn’t work


thanks 😉


ha, I didn’t really do anything 😉


Just keep in mind that alter-var-root will appear to not work if you are within a clojure REPL (you’ll want set! in that case)


it appears that expound is working, but I don’t see my function being used in the output:

(alter-var-root #'s/*explain-out*
                  (constantly (expound/custom-printer
                               {:show-valid-values? false
                                :value-str-fn my-value-str
                                :print-specs? true
                                }) #_expound/printer)


oh wait, it does


@bbrinck in my custom function I want to say: if this is a com.stuartsierra component map, I want to print only the keys (else I’m flooded with pages of information), else I want to do whatever is the default in expound


@bbrinck can I do the else branch in a nice way?


@borkdude Hm, unfortunately it’s not super easy to do the else part right now, but if you create an issue I’ll think more about how to make it nicer. Right now, I think the best you could do is to use the private function value-in-context or grab the value of the private var *value-str-fn* and call that.


Not exactly pretty 😞


What’s the best way to make clojure.spec.alpha not print the entire component system map. We are using (s/assert ::system system). Even when making a custom expound printing function, clojure.spec still barfs my entire console with output.


I’m not sure exactly what you mean. Can you provide an example of the output?


I’m curious to know which part of the output is showing the entire map - I would think if you provide a custom printer, you could in principle hide it entirely (or show as much as you like), but maybe it’s printing somewhere else?


until line 124 it’s ok, there I only print the keys of the system map. afterwards, still the whole system is printed.


@borkdude Ah, right, so this isn’t actually spec - the issue is that the program is printing out all the exception data from the assertion


Is this running in boot? I wonder if the error printer is configurable? I can see why this is the default (you want to see the data for an assertion exception)


but in the context of spec, it will put all of the detailed explain-data into the exception


yes, it’s boot


I can see why that’s how boot works and I can see why spec adds a lot of info to the exception (might be useful), but when they work together, it’s definitely a lot of output.


I also tried this:

(try (rr/reset)
        (catch Exception e
          (throw (component/ex-without-components e))))


but that doesn’t work, because the assert exception already has the entire system in it :-s


hm, not sure what you mean. Why can’t you alter the exception data in ex-without-components?


is it already in the string message?


if it’s just in the data, I presume you could just dissoc it


or just construct a new error that has less info, using the message from the exception


hmm, I have to inspect the exception in the REPL to see what to dissoc, but good idea


If that doesn’t work, the code for assert isn’t too long, might be possible to just use a custom one:


basically just omit line 1964 and 1965


ah, right, that’s easier 🙂

👍 4

@bbrinck so what I wanted was actually not a custom :value-str-fn function, but a way to transform my value before it’s printed by expound. would it make sense to have a :transform (fn [v] ...) option in expound on the custom printer?


Hmm, good question.


Can you talk more about why a transform fn would be preferable to customizing the way it prints?


Maybe we should move this to #expound since we’re talking about potential features