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