This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-07-03
Channels
- # aws (3)
- # babashka (46)
- # bangalore-clj (2)
- # beginners (89)
- # cider (1)
- # clojure (57)
- # clojurescript (4)
- # conjure (6)
- # duct (3)
- # fulcro (2)
- # graalvm-mobile (41)
- # introduce-yourself (1)
- # lsp (12)
- # malli (11)
- # off-topic (37)
- # pathom (3)
- # pedestal (6)
- # podcasts-discuss (5)
- # polylith (17)
- # releases (2)
- # sci (2)
- # shadow-cljs (8)
- # specter (1)
- # tools-deps (10)
Hello, we cannot push libraries to clojars under libraryname/libraryname
anymore? (sorry if this is not the proper channel to ask this)
Here's an FAQ that covers some of the rationale https://github.com/clojars/clojars-web/wiki/Verified-Group-Names
per https://github.com/clojars/clojars-web/wiki/Verified-Group-Names#how-does-this-impact-existing-libraries-published-to-clojars, I thought it shouldn't impact new versions of existing libraries. Is this a new library?
I think the main idea is to make clojars more secure and the clojars team has been proactive about supporting a better approach.
It is a new library yes, that's why it caught me off guard, I have no problem with the requirement I was just surprised I couldn't simply deploy anymore 😛
I've changed the group ID of my most popular libraries to satisfy the VGN policy (from seancorfield
to com.github.seancorfield
) and all my READMEs link to the Clojars wiki (and my CHANGELOGs explain the group ID change).
antq
seems to detect old groups/new groups so it can recommend upgrading a library across the group ID change, which is really nice.
I know the read-eval is frowned upon, but out of curiosity, can someone explain the semantic context of what it evals? Shouldn't one of these work?
(def foo 1)
#=foo
#='foo
#=(deref (resolve foo))
Perhaps you already know what follows and are interested only in why evaluation in the context of read
and read-string
is different from eval
. Alas, I don't know the answer to that, and I can only describe the difference itself.
Evaluation done by read
and read-string
is very limited and supports only the following cases:
• The form is a symbol naming a Java class, (read-string "#=java.lang.String")
• The form is a list and the first symbol is a symbol
◦ that is var
and the next one is a fully qualified symbol, (def x) (read-string "#=(var user/x)")
◦ that denotes a constructor calling, (read-string "#=(java.lang.String. \"x\")")
◦ that denotes a static member calling, (read-string "#=(java.lang.Integer/parseInt \"1\")")
◦ that names something in the current NS, and the rest are quoted entities, (read-string "#=(inc 1)")
As you can see, everything after the first symbol is left untouched - foo
in your example is just a symbol and (resolve foo)
is just a list. This makes read[-string]
eval extremely limited by itself in comparison to eval
, but you can use eval
there to circumvent that: (def x 1) (read-string "#=(eval x)")
Hello is there a way to get the symbol/number/strings (all the literal parts) from a nested form that can contain any type of form ?
(get-members (assoc {"a" (:a m)
"b" #{"a" "b" (f 1 2)}}))
To return something like
[assoc "a" :a m "b" "a" "b" f 1 2]
If you have access to the actual form it’s fine. There are also some tricks that you can do with metadata if you don’t have access to the form as data. Macros like source do some neat tricks
is there a standard way to do it? i can access the form,for example get-members could be a macro,and parse the form
postwalk + an atom has served me well over the years https://github.com/nedap/formatting-stack/blob/16d29f6448b81157d9849becc29e1f17f26e486c/src/formatting_stack/formatters/trivial_ns_duplicates.clj#L104-L109
I think this is pretty standard
user=> (filter (complement coll?) (tree-seq coll? seq '(assoc {"a" (:a m) "b" #{"a" "b" (f 1 2)}})))
(assoc "a" :a m "b" "a" "b" f 1 2)
you could use a fn
instead of complement
but I'd be suspicious of any solution other than a filter / tree-seq combo
Yeah check out tree-seq for getting the nodes. Gives you a depth first lazy sequence of the nodes of the tree. You could also just walk it yourself
This looks like you want flatten
but working on maps as well. That’s a small change from the defn for flatten
to use seqable?
instead of sequential?
:
(defn flatten2
[x]
(filter (complement seqable?)
(rest (tree-seq seqable? seq x))))
My first thought was to use flatten
, but I’d never tried it on maps before, and I discovered that it didn’t work. So I looked at the source to flatten
, saw that it did the tree-seq
(good call @U11BV7MTK!) but used sequential?
, which maps don’t match.
That will also screw with string keys/values btw:
user=> (flatten2 {:a "foo"})
(:a \f \o \o)
Yes, I’m rushing about like a headless chook right now (family is yelling at me to get out the door). It’s a terrible time to try to write a bit of code :rolling_on_the_floor_laughing:
seqable?
+ strings is a common pitfall, I wish it didn't handle strings most of the time
While it may be a “gotcha”, I appreciate being able to process strings as seqs. And seqable?
is the function that tells us that we can do that. So I like it as-is. I just have to remember not to do silly things 🙃
It's sometimes not recommended to treat strings as seqs if you want performance, but this isn't always important.
@takis_ fwiw, we had a conversation about your question in a thread, not sure if you missed that ;)
Usually I use (constantly nil)
for 1-arg noop functions, but recently I realized I can use {}
for that 🤯
I did some serious benchmarking using dotimes
and came to the scientific conclusion that #{}
is objectively better.
user=> (time (dotimes [i 100000000] ({} :foo)))
"Elapsed time: 317.749149 msecs"
nil
user=> (time (dotimes [i 100000000] (#{} :foo)))
"Elapsed time: 274.513781 msecs"
nil
But probably nothing beats...
user=> (time (dotimes [i 100000000] ((fn [_]) :foo)))
"Elapsed time: 55.271143 msecs"
In ClojureScript, {}
seems to beat event (fn [_])
in my very similarly thorough benchmarks
hmm, I can't repro that e.g. in http://klipse.app:
(time (let [x {}] (dotimes [i 10000000] (x :foo))))
(time (dotimes [i 10000000] ({} :foo)))
(time (dotimes [i 10000000] (#{} :foo)))
(time (dotimes [i 10000000] ((fn [_]) :foo)))
(time (let [x (fn [_])] (dotimes [i 10000000] (x :foo))))
"Elapsed time: 498.400000 msecs"
"Elapsed time: 573.200000 msecs"
"Elapsed time: 805.800000 msecs"
"Elapsed time: 93.700000 msecs"
"Elapsed time: 208.500000 msecs"
I would have expected (time (let [x (fn [_])] (dotimes [i 10000000] (x :foo))))
to be faster, but perhaps the JS engine optimizes it differently..?
Clojure JVM emits one global function object per anonymous function expression, i.e. it doesn't create new functions in a loop, it re-uses the one global function and passes parameters as needed
I was curious about the timing of #{}
vs. {}
since PersistentHashSet
wraps a PersistentHashMap
. However, {}
is a PersistentArrayMap
and even when it’s empty it goes through several calls to determine that something isn’t in it. It’s wasteful, but I also don’t think it’s used enough for anyone to consider it being worth optimizing
yes i saw it, thank you trying to help. postwalk worked,it does what i want at least for what i tested, i didnt want to try something mine and have un-expected bugs
This might be the best contributor patch I ever saw to Clojure: https://clojure.atlassian.net/browse/CLJ-2637
A desktop link: https://clojure.atlassian.net/browse/CLJ-2637