clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
2021-02-19T01:11:59.284400Z

Another drawback of are is the forbidden de-structuring in the args list. During the few hours I have used it (in lieu of are), I have become more comfortable with doseq

2021-02-19T01:25:12.284700Z

I also like the natural flow of listing what I need (params + data), and as I type these the testing code foments..

slipset 2021-02-19T13:20:11.286700Z

So, maybe the wrong thing to do, but why doesn’t

(case (class "lol") String "yay")
Work (it throws “No matching clause: class java.lang.String”) And, can I do this sort of thing with case or would I need to use cond?

jkxyz 2021-02-19T13:21:25.287700Z

I would guess that’s because case evaluates String as the literal symbol String, but it would work with the full symbol, java.lang.String

slipset 2021-02-19T13:22:12.288100Z

Nope, doesn’t help with the full symbol 😕

borkdude 2021-02-19T13:22:58.289300Z

@slipset (case (symbol (.getName (class "lol"))) java.lang.String 1) ;;=> 1

jkxyz 2021-02-19T13:23:02.289400Z

Ah right, because class returns the actual class but case doesn’t resolve the symbol to the class

slipset 2021-02-19T13:24:47.289900Z

Hmm, then there is some trickery involved somewhere since:

user> (defmulti lol type)
;; => #'user/lol
user> (defmethod lol String [s] (println "BLA"))
;; => #multifn[lol 0x244e1571]
user> (lol "yay")
BLA
;; => nil
user> 

slipset 2021-02-19T13:25:15.290300Z

So for case String is not good enough, but it is good enough for defmulti

borkdude 2021-02-19T13:25:37.291200Z

@slipset You should read the case matches as if they are quoted values

borkdude 2021-02-19T13:26:15.292100Z

roughly: (condp = .... 'String ...)

slipset 2021-02-19T13:26:17.292300Z

(reason I came over this was that I was converting a defmulti to a case.)

borkdude 2021-02-19T13:27:51.292700Z

This is a major hack you should probably not use:

(case (class "lol") #=java.lang.String 1)
1

slipset 2021-02-19T13:31:47.293300Z

Continuing:

user> (defmethod lol Number [s] (println "Number" s))
user> (lol 1)
Number 1
but
user> (condp = (type 1) Number "1")
Execution error (IllegalArgumentException) at user/eval457938 (form-init10937619012906002413.clj:17848).
No matching clause: class java.lang.Long
user> 

borkdude 2021-02-19T13:33:35.294Z

yeah, defmethods work with hierarchies, a Long isa? Number, but when you compare the exact types that won't work

borkdude 2021-02-19T13:34:14.294800Z

a cond with predicates will though, number? ?

slipset 2021-02-19T13:37:52.295100Z

ended up with cond and isa?

alexmiller 2021-02-19T13:43:20.295900Z

Case match values must be compile time constants. Classes are not compile time constants.

alexmiller 2021-02-19T13:43:52.296500Z

You can use class name though in this case

vlaaad 2021-02-19T13:46:27.296900Z

you are now banned from hashtag equals club

slipset 2021-02-19T13:46:39.297400Z

actually ended up with cond and number? , string? etc

borkdude 2021-02-19T13:47:41.297500Z

Is there a support group for those who are banned?

p-himik 2021-02-19T13:48:47.297700Z

Why is it a hack though?

p-himik 2021-02-19T13:50:05.297900Z

Hmm, *read-eval* exists which makes that code prone to be broken.

flefik 2021-02-19T14:26:13.302100Z

I recently picked up 97 Things Every Programmer Should Know. I got very excited when I realised one of the 97 chapters are authored by @alexmiller (alongside other giants such as Scott Meyers). Well done, and thanks!

alexmiller 2021-02-19T14:26:27.302300Z

ha, that was a long time ago

flefik 2021-02-19T14:27:09.302600Z

🙂 nevertheless great read!

sveri 2021-02-19T14:41:01.304400Z

Hi, I am looking for the oneliner that every number in a list is smaller then the number before so [5 4 3 2] would return true and [5 4 8 2] returns false. Any ideas?

KJO 2021-02-22T12:13:37.025900Z

(not (some (fn [[f s]] (< f s)) (partition 2 1 target-coll)))

mpenet 2021-02-19T14:41:45.304800Z

@slipset cond/condp and instance? might be quite decent too if you don't care about clj hierarchies

borkdude 2021-02-19T14:41:53.305200Z

(apply > [5 4 3 2]) @sveri

👍 1
👏 2
dharrigan 2021-02-19T14:42:32.305800Z

magic!

sveri 2021-02-19T14:42:41.306100Z

Thanks @borkdude I know there was a function 🙂

alexmiller 2021-02-19T14:44:38.306200Z

well that's what you're getting with the predicate checks he ended up with

mpenet 2021-02-19T14:45:46.306400Z

yes, it's only useful if you need to check something else than string/numbers and other "?" fns

borkdude 2021-02-19T14:45:48.306600Z

@sveri beware of empty collections, they will crash

sveri 2021-02-19T15:03:45.307500Z

yea, no problem, thank you.

deadghost 2021-02-19T19:59:32.311600Z

Anyone get lein test error output integrated with github annotations? Sounds like I want to override clojure.test/report with output like: https://github.com/clj-kondo/clj-kondo/blob/master/doc/ci-integration.md#linter-output-integration. I wouldn't be surprised if this already works or a lib exists.

awb99 2021-02-19T23:22:51.315200Z

I have a function that returns a core.async channel that will only contain one item. I want to map over a collection and get all the results back in a collection. Any ideas?

2021-02-19T23:26:19.316100Z

What do you mean? Is the collection you want to map over the one item in the channel?

2021-02-19T23:28:29.316300Z

async/merge or async/into

awb99 2021-02-19T23:31:50.316500Z

The collection has different parameters. The function downloads data based on the parameters. I want to sequentially make the async download requests. So wait for each result before making the next request.

2021-02-19T23:32:51.316700Z

I think (map (comp <!! my-fn) my-coll) would work for that? (keep in mind it would be lazy by default so you'd need doall or mapv)

awb99 2021-02-19T23:42:10.317Z

This brings me the error <! Was used outside go block.

2021-02-19T23:45:26.317200Z

you need &lt;!! not &lt;!

awb99 2021-02-19T23:45:26.317400Z

(println "init results: " (map (comp status-e <! exec-sync) ops-sniffer)) #_(let [r (<! (client/exec-async! state {:op "describe"}))] (println "describe result: " (status-e r)) (print-eval-result r)) #_(let [r (<! (client/exec-async! state {:op "eval" :code "(require '[pinkgorilla.nrepl.sniffer.middleware])"}))] (println "require middleware result: " (status-e r)) #_(print-eval-result r))

awb99 2021-02-19T23:46:00.317600Z

the 2 commented out blocks are what I want to do with the map above

2021-02-19T23:47:56.317800Z

&lt;!! should work there.

awb99 2021-02-19T23:49:53.318Z

that works!

awb99 2021-02-19T23:50:00.318200Z

Why is that?

awb99 2021-02-19T23:50:13.318400Z

My other code used only <!

2021-02-19T23:52:06.318600Z

&lt;! only works in a go block. You can't wrap the whole thing in a go and then use &lt;! because you can't use &lt;! in anonymous functions even in a go block. You can accomplish it in a go block if you loop/`recur` across the inputs/build up an output

2021-02-19T23:54:56.318800Z

(go 
  (loop [in  op-sniffer
         out []]
    (when-some [x (first in)]
      (recur
        (rest in)
        (conj out (&lt;! (exec-sync x)))))))
this should work with <! or <!! (the go block not being necessary if you use <!!. <!! ties up a real thread while <! in a go does not

awb99 2021-02-19T23:56:41.319Z

Ahhh

awb99 2021-02-19T23:56:48.319200Z

The function part is the Problem

awb99 2021-02-19T23:57:27.319400Z

I guess clojure cannot pass the go block into a function.

awb99 2021-02-19T23:57:54.319600Z

This is where the code Analysis fails then.

awb99 2021-02-19T23:58:29.320Z

Thank you so much @jjttjj

👍 2
😍 1
awb99 2021-02-19T23:58:42.320200Z

Googling for issues with core async is really hard

awb99 2021-02-19T23:58:46.320400Z

Bad naming

awb99 2021-02-19T23:58:52.320600Z

Too many irrelevant results in google.