Fork me on GitHub
#clojure
<
2021-07-03
>
Nazral01:07:04

Hello, we cannot push libraries to clojars under libraryname/libraryname anymore? (sorry if this is not the proper channel to ask this)

Nazral01:07:18

Ok thank you!

phronmophobic01:07:53

I think the main idea is to make clojars more secure and the clojars team has been proactive about supporting a better approach.

Nazral01:07:43

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 😛

simple_smile 2
👍 2
seancorfield02:07:47

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).

seancorfield02:07:28

antq seems to detect old groups/new groups so it can recommend upgrading a library across the group ID change, which is really nice.

👍 2
lread20:07:25

fwiw, there is also the #clojars channel if you have more questions on clojars.

didibus06:07:53

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))

p-himik07:07:10

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)")

👌 2
👏 2
didibus07:07:29

That's exactly what I wanted, thanks!

Carlo14:07:07

Is there a clojure/cljs formatting tool that splits long lines in the code?

Carlo16:07:05

thank you @U45T93RA6!

🙌 2
Takis_14:07:10

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]

dpsutton14:07:30

Looks like a depth first walk through a tree

dpsutton14:07:53

And it’s possible depending on if you have access to the form itself.

dpsutton14:07:40

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

Takis_14:07:10

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

noisesmith15:07:13

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)

noisesmith15:07:39

you could use a fn instead of complement but I'd be suspicious of any solution other than a filter / tree-seq combo

Takis_14:07:38

but i was wondering if there is a standard library i can use for this

dpsutton14:07:28

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

Takis_14:07:20

thank you dpsutton : )

quoll15:07:09

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))))

quoll15:07:57

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.

borkdude15:07:54

That will also screw with string keys/values btw:

user=> (flatten2 {:a "foo"})
(:a \f \o \o)

👍 2
borkdude15:07:20

perhaps coll? is a better default than seqable?

💯 3
borkdude15:07:32

(I just checked, it also returns true for MapEntry...)

👍 2
quoll15:07:26

Cool. 🙂

quoll15:07:19

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:

borkdude15:07:28

seqable? + strings is a common pitfall, I wish it didn't handle strings most of the time

quoll15:07:34

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 🙃

quoll15:07:28

(If only…)

borkdude15:07:19

It's sometimes not recommended to treat strings as seqs if you want performance, but this isn't always important.

👍 2
Takis_15:07:10

i used postwalk,seems to do what i need

borkdude15:07:58

@takis_ fwiw, we had a conversation about your question in a thread, not sure if you missed that ;)

vlaaad16:07:52

Usually I use (constantly nil) for 1-arg noop functions, but recently I realized I can use {} for that 🤯

delaguardo16:07:34

#(#_ %)
another mind bending variant )

clojure-spin 5
vlaaad17:07:41

What the...

borkdude17:07:33

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

👍 2
borkdude17:07:25

But probably nothing beats...

user=> (time (dotimes [i 100000000] ((fn [_]) :foo)))
"Elapsed time: 55.271143 msecs"

didibus20:07:08

In ClojureScript, {}seems to beat event (fn [_])in my very similarly thorough benchmarks

borkdude20:07:44

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"

borkdude20:07:10

The (time (dotimes [i 10000000] ((fn [_]) :foo))) is the fastest of the bunch there

borkdude20:07:05

I would have expected (time (let [x (fn [_])] (dotimes [i 10000000] (x :foo)))) to be faster, but perhaps the JS engine optimizes it differently..?

borkdude20:07:10

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

borkdude21:07:11

but CLJS emits JS source code, which is obviously different

didibus21:07:51

Interesting, I tested it on Replete android self-host cljs repl app 😜

quoll21:07:46

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

Takis_18:07:23

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

didibus20:07:02

This might be the best contributor patch I ever saw to Clojure: https://clojure.atlassian.net/browse/CLJ-2637

didibus21:07:50

Ya changed my link to that, much better