Fork me on GitHub
Jakub Holý (HolyJak)14:09:13

Is there a way to check that a string is valid as a keyword? Currently I can do (keyword "a,b") which creates a keyword that cannot be represented as literal, i.e. :a,b is not accepted (rightly so). Before I call keyword on a string, how can I check / ensure it only contains valid characters? 🙏 says little... I guess I could write a manual check for the rules described under and Literals / Keywords little more down?


are you serializing data to edn?

Jakub Holý (HolyJak)14:09:30

No, generating Datomic attributes from customer-defined "custom fields" with a string name


The reader pattern is defined at clojure.lang.LispReader#symbolPat.


static Pattern symbolPat = Pattern.compile("[:]?([\\D&&[^/]].*/)?(/|[\\D&&[^/]][^/]*)");

🙏 2
Jakub Holý (HolyJak)14:09:29

I have tried it, but

(def p (java.util.regex.Pattern/compile "[:]?([\\D&&[^/]].*/)?(/|[\\D&&[^/]][^/]*)"))
(-> p (.matcher "abc,b") .matches)
; => true
x I expect false


tools.reader is more strict about keywords (among other things), you can either use it or inspect its source for inspiration

👍 2

Ah, it reads tokens. And commas are treated as whitespace that, of course, separates tokens. Also a few other chars are important, but you wanna check the implementation for that yourself - it's not that easy to describe succinctly.

Jakub Holý (HolyJak)14:09:45

Thank you. For the time being I will be very strict and follow what describes and check for (re-matches #"[\w*+!-'?<>=]+" name)


you could always round trip it and see if it changes ...

(let [x (keyword "a,b")]
    (= (clojure.edn/read-string (str x)) x))

👍 2

it still allows "illegal" kws like :a.b


Why would :a.b be illegal?


> Keywords - Keywords are like symbols, except: > They cannot contain '.' in the name part, or name classes. > Like symbols, they can contain a namespace, :person/name, which may contain '.'s.


from my understanding that would mean :a.b is not ok


Huh! Found this: And yeah, I've been seeing them for years, both in CLJ and in CLJS. Would never have guessed the docs explicitly disallow it for some reason.

❤️ 2

user=> :
at least one widely used clojure lib uses keyword literals like this, I wouldn't expect a change to the clojure reader that prevents it working


(like any normal person I find that painful to see)

🙏 2

Oh wow. :) I was thinking about plain keywords like (which a user of HoneySQL, at least v1, might use) or :div.login-form (when using Hiccup).


Is there some blocking function for pulling values from async channel into a collection that’s supplied with the library? I haven’t spotted one. I can <!! in a loop, I know, but I am wonder if there’s one already.


Not sure what you mean by "a collection that’s supplied with the library". But maybe a/into?


but that isn’t what I was looking for, it returns a channel


but I can <!! on that

👍 2

Given the following code

(defmacro reg-fn [k f] ...)

(defn some-fn [] ...)

(reg-fn :my-fn some-fn)
Is there a way to get to the name of f passed into the macro (`some-fn` in this case). I want to check if the name conforms to a certain convention, and throw an exception if it does not. I’d also be happy with some-namespace$some-fn or even better the metadata of some-fn Thanks


Inside the macro, f is bound to the symbol that you pass to it. Just use (name f) somewhere in the unquoted part of the macro.


facepalm thanks. should have asked sooner. 😄

👍 4