Fork me on GitHub
#clojure
<
2020-04-30
>
yedi01:04:52

hey yall, lil help? i think im missing something obvious here:

(defn response-for [& args]
  (log/info (apply io.pedestal.test/response-for args)))

;; fails with 
Syntax error macroexpanding log/info at (example.clj:20:3).
No value supplied for key: (apply io.pedestal.test/response-for args)

noisesmith01:04:29

"no value supplied for key" means that log/info uses keys destructuring, so it always needs an even number of args

noisesmith01:04:39

which log lib is that?

yedi01:04:09

oh i think i just need to add :msg

noisesmith01:04:00

keys destructuring is much less popular these days, so you run into it less often

šŸ’Æ 4
Nassin06:04:33

you mean key de-structuring of rest sequences correct?

noisesmith11:04:41

oh, right, yes I mean keys of rest sequences, not keys generally,

yedi01:04:29

yea usually i just pass a map of opts or args

potetm01:04:35

good riddance, I say

yedi01:04:44

but yea, adding the :msg solved it, thanks @noisesmith

Tim Smart07:04:55

Getting a bunch of Unknown symbol errors with clojure-lsp. Is this the right channel to ask about it?

sogaiu09:04:50

@tim.smart just a guess but you might get answers sooner at editor-specific channels, e.g. #emacs or #vim or other

Ramon Rios15:04:37

Hello everybody. I have a map, witch i need to check if the value of one key contains the value of i need. {:nameĀ :test-tableĀ :col-specsĀ {(containsĀ {:idĀ anything})}Ā :extra-specsĀ nil} No success with this approach. Any insight?

noisesmith15:04:42

what is the consumer of that hash map? also, I'd expect something like {:id (contains anything)} because the current nested map isn't valid

Ramon Rios15:04:30

This is a test that i'm adapting. Previously it receive multiple arguments and now i'm adopting a config map instead so i won't need change arity again

noisesmith15:04:54

is the map literal above a pseudo-code?

Ramon Rios15:04:11

Let me show you the test

Ramon Rios15:04:06

(create-table-sqlĀ ..db..Ā :test-tableĀ (as-checkerĀ (containsĀ {:idĀ anything}))
That was before i change the arity

noisesmith15:04:40

so I wold turn that into {:name :test-table :col-specs [(as-checker (contains {:id anything}))]}

Ramon Rios15:04:35

Il'l Check that . thanks

pseud15:04:49

has anyone been using luminus with the +graphql profile? If so, can you direct me to how to actually test it out ? Looking over the code, I see a /graphql route, but no mention of GraphiQL. Connecting to localhost:3000/graphsql via GraphiQL (as a separate electron app), nothing seems to happen. No errors, but also no editor suggestions. Admittedly I have no experience with GraphQL so that doesnā€™t make things easier. If anyone knows of talks given, preferably where example code is also made available, that would be great. (FWIW, Luminus uses Walmartā€™s Lacinia)

Vishal Gautam15:04:53

(lp/service-map {:graphiql true})

Vishal Gautam15:04:05

lp = com.walmartlabs.lacinia.pedestal

pseud15:04:22

I cannot see the project :S

Vishal Gautam15:04:38

you need to enable it by passing the config above

Vishal Gautam15:04:25

Sorry I posted my work link LOL

Vishal Gautam15:04:31

it should work now

pseud15:04:15

Yup. I see it šŸ™‚ It also seems like a good place to start is the lacinia tutorial on this page

Vishal Gautam15:04:17

Yes, the tutorial is fantastic! Highly recommended. If you are looking for a client library then I would suggest looking at re-graph library - https://github.com/oliyh/re-graph

pseud15:04:38

Cool šŸ™‚ Will definitely keep in mind. A bit rusty on clojure, but Iā€™ll manage. The major new thing is GraphQL, possibly getting the tooling stuff working (ClojureScript was somewhat temperamental at times when I last did Clojure). But the combined solution seems awesome

jaide18:04:42

Is there a clojure function to search through a seq or vec with a predicate and return the first result that matches without processing the rest? In JS it would be like the .find array method.

(->> my-list (filter my-pred) (first)) 
Is close but even if a match is found, it will keep searching the rest of the list.

phronmophobic18:04:19

I use the following idiom: (some (fn [x] (when (pred x) x)) xs)

bfabry18:04:21

(->> my-list (filter my-pred) (first)) will not keep searching the rest of the list. filter returns a lazy sequence

āž• 4
aisamu18:04:23

some is what you're looking for, but > even if a match is found, it will keep searching the rest of the list. Just that rest of that chunk, since filter is lazy

bfabry18:04:24

user=> (first (filter #(do (println %) (= 5 %)) (range 10)))
0
1
2
3
4
5
6
7
8
9
5
user=>

seancorfield18:04:54

user=> (first (filter #(do (println %) (= 5 %)) (range 100)))
0
1
2
3
4
5
6
...
26
27
28
29
30
31
5
user=> 
usually up to 32 elements.

bfabry18:04:55

yeah good point

noisesmith18:04:20

this version prints once, and is efficient, you'd want to wrap it in something much less weird looking though

(transduce (filter (fn [x]
                     (println x)
                     (even? x)))
           (completing (fn [acc el]
                         (reduced el)))
           :invalid
           (range 100))

noisesmith18:04:58

maybe better?

(eduction (comp (filter (fn [x]
                          (println x)
                          (even? x)))
                (take 1))
          (range 100))

jaide18:04:26

Oooh I like that.

noisesmith18:04:20

of course you'd put it in a function where you plug in the fn and the coll (and maybe call first on the result too), because in my experience collaborators go to a dark place when they see things like eduction

4
jaide18:04:37

Of course

jaide18:04:48

Although on one hand, I'm working with a list < 32 items long on the other filter feels like the wrong tool for the job.

jaide18:04:43

(some #(do (println %) (= 5 %)) [1 2 3 4 5 6 7 8 9 10])
1
2
3
4
5
It looks like some doesn't go through all the items once it finds a match

noisesmith18:04:17

oh, I thought some returned a boolean instead of your item

noisesmith18:04:28

maybe that's OK in your domain, if so I missed that

jaide18:04:35

It does, but you can wrap it in a when

jaide18:04:40

to get the original value

jaide18:04:58

I think someone mentioned some goes through all values.

bfabry18:04:25

šŸ˜›

(loop [xs (range 100)]
  (if (and (first xs) (even? (first xs)))
    (first xs)
    (recur (rest xs))))

jaide18:04:39

At this point I'm just considering options. Personally I think that eduction very explicitly describes the intended behavior.

bfabry18:04:31

probably the end condition should be empty? rather than truthiness of the head

jaide18:04:22

(defn find-first
  [f xs]
  (->> xs
       (reduce #(if (f %2) (reduced %2) %1) nil)))

(find-first #(do (println %) (= % 5)) [1 2 3 4 5 6 7 8 9 10])
=> 
1
2
3
4
5
5
Another option leveraging reduced

bfabry18:04:32

oh yeah that's probably the neatest imo

noisesmith18:04:03

reduce shares the property with eduction of utilizing the fast iteration path for supporting collections

jaide18:04:00

(defn find-first
  ([f xs]
   (find-first f nil xs))
  ([f not-found xs]
   (->> xs
        (reduce #(if (f %2) (reduced %2) %1) not-found))))
This one can take an optional not-found value. I'll run this and the eduction solution by my coworkers and see which one they think will be more useful\maintainable.

noisesmith18:04:13

also that function could be #(when (f %2) (reduced %2))

noisesmith18:04:57

but that doesn't respect your not-found

jaide18:04:00

Well, not if I want that default yeah

vemv18:04:21

Can JVM profilers show Clojure locals? (IIRC, the Cursive and CIDER debuggers do. I'm simply gathering knowledge about profilers) ...If that helps I use Yourkit. I feel that I'm always missing out on some of its features šŸŒ€

noisesmith18:04:08

clojure does something called "locals clearing" to prevent massive heap usage with lazy-seqs, and there's a compiler option to turn that off so debuggers can see your locals

noisesmith18:04:24

the local values are intentionally deleted otherwise, so there's nothing for the debugger to find

vemv18:04:47

Yes, I know about the flag Now I wonder where to actually see these locals in a specific profiler's UI

noisesmith18:04:26

oh, carry on

borkdude18:04:17

Why does Clojure re-create a map in map destructuring if it's already a map -- EDIT: missed the question mark, never mind.

user=> (macroexpand '(let [{:keys [:a :b]} {:a 1 :b 2}]))
(let* [map__142 {:a 1, :b 2} map__142 (if (clojure.core/seq? map__142) (clojure.lang.PersistentHashMap/create (clojure.core/seq map__142)) map__142) a (clojure.core/get map__142 :a) b (clojure.core/get map__142 :b)])
Would something break if there was an (if (map? map__142) map__142 ...) there?

noisesmith18:04:06

varargs keys destructuring in function arg lists?

noisesmith18:04:13

that's the big one I can think of

noisesmith18:04:41

oh! you mean the optimization to just use the map if it is one

noisesmith18:04:05

*me hasn't been getting enough sleep

hiredman18:04:13

I think you are misreading the conditional

hiredman18:04:24

it only creates a map if it is a seq

borkdude18:04:43

*me hasn't been getting enough sleep

simple_smile 4
arohner21:04:43

Is there a linter that will catch vertical alignment issues?

vemv21:04:29

Pretty sure not since there's no a JVM-powered formatter that vertically aligns things No formatter -> no linter :)

vemv21:04:25

One could toy with Emacs in batch mode if you really consider it worth the effort. IMO emacs isn't exactly the best canonical formatter (the best being a mixture of cljfmt, cider and hand-tuned things)

arohner21:04:00

i.e. if our team decides to pick one style or another (see https://github.com/bbatsov/clojure-style-guide/issues/10), is there an existing linter that will detect the ā€˜wrongā€™ style?

arohner21:04:32

clojure-mode indent-region appears to accept any existing vertically aligned forms, and doesnā€™t re-indent them