Fork me on GitHub
#clojure
<
2018-09-28
>
urzds11:09:24

I have a web programming question regarding migratus. Is there a channel more suitable than #clojure?

urzds11:09:13

@yogthos I get an error Failure: Query returns results in response to a ALTER TABLE ... RENAME COLUMN ... TO ...; query. (https://github.com/yogthos/migratus/issues/149) Any idea what's wrong or how to wrokaround that?

yogthos11:09:42

Not sure off top of my head, will have to take a look when I get a chance

yogthos11:09:11

Are you only seeing the error in migratus?

urzds11:09:10

The only other thing I tried was the sqlite3 CLI program. And there I get no output at all.

urzds11:09:20

i.e no error and no result

yogthos12:09:16

You could try running the query directly via clojure.java.jdbc

urzds12:09:00

k, will have to look up how that works.

urzds12:09:24

In case anyone else wonders whether there is any documentation besides https://clojure.github.io/java.jdbc/ that is more beginner friendly: There is http://clojure-doc.org/articles/ecosystem/java_jdbc/home.html , which seems pretty solid.

urzds12:09:50

Was quite easy. Discovered https://github.com/bhauman/rebel-readline along them way.

yogthos13:09:19

Thanks, I'll take a look

andrea.crotti13:09:32

what could be a nice way to deduplicate a vector of maps based on one of the keywords

andrea.crotti13:09:46

for example this works

user> data
[{:a 1, :b 2} {:a 1, :b 3}]
user> (flatten (map first (clojure.core/vals (group-by :a data))))
({:a 1, :b 2})

souenzzo14:09:11

In my utils namespace there is a distinct-by function, a custom version of distinct that applys a f in the values

souenzzo14:09:57

https://gist.github.com/souenzzo/2a2e74d56fc7bd6e7a35977bfb0939b9 It do the same of distinct Or you can do (def distinct-by #(map (comp first val) (group-by %1 %2)))

andrea.crotti13:09:54

but I wonder if there is a better way to do that

borkdude14:09:56

is there something more stringly for this?

(map #(apply str %) (partition-by #{\. \#} "foo#id.class")) ;;=> ("foo" "#" "id" "." "class")
Could do regex I guess, but str/partition-by would be nice if it existed 🙂

futuro14:09:46

@andrea.crotti you could use reduce and assoc into a new map based on value

futuro14:09:10

Hard to type on a phone, but (fn [dedupemap m] (assoc dedupemap (get m k) m))

futuro14:09:10

You don’t need to group by because any two maps with the same particular k/v pair are considered the same, so just replace whatever was there already.

futuro14:09:47

Then grab the vals from that map and presto.

futuro14:09:51

If you don’t want to build a map, you could have a set of seen values and a seq of maps. If you’ve seen the value before, don’t add the value to the seq of maps.

andrea.crotti14:09:12

uhm yes I don't want to get a map as result

andrea.crotti14:09:43

and yes I could two passes, but I think I prefer the group-by/flatten solution then

futuro14:09:00

user=> (defn dedupe-by [key-fn maps]
  #_=>   (second
  #_=>    (reduce
  #_=>    (fn [[seen-vals deduped-maps] m]
  #_=>      (if (contains? seen-vals (key-fn m))
  #_=>        [seen-vals deduped-maps]
  #_=>        [(conj seen-vals (key-fn m)) (conj deduped-maps m)]
  #_=>        ))
  #_=>    [#{} []]
  #_=>    maps)))

futuro14:09:39

(dedupe-by :a [{:a 1 :b 2} {:a 1 :b 3} {:a 2 :b 3}])

andrea.crotti14:09:46

nice but way too complicated imho

futuro14:09:53

:thumbsup:

jaihindhreddy-duplicate14:09:26

@futuro dedupe-by might not be a good name because clojure.core.dedupe does something different. It only deduplicates consecutive repeating values. distinct-by might be better.

jaihindhreddy-duplicate14:09:09

This is what you get when you add a key-fn to implementation of clojure.core.distinct

futuro14:09:19

That's a good point @jaihindhreddy

jaihindhreddy-duplicate14:09:31

(defn distinct-by
  "Returns a lazy sequence of the elements of coll with duplicates according to key-fn removed.
  Returns a stateful transducer when no collection is provided."
  ([key-fn]
   (fn [rf]
     (let [seen (volatile! #{})]
       (fn
         ([] (rf))
         ([result] (rf result))
         ([result input]
          (let [lookup-key (key-fn input)]
            (if (contains? @seen lookup-key)
              result
              (do (vswap! seen conj lookup-key)
                  (rf result input)))))))))
  ([key-fn coll]
   (let [step (fn step [xs seen]
                (lazy-seq
                  ((fn [[f :as xs] seen]
                     (when-let [s (seq xs)]
                       (let [lookup-key (key-fn f)]
                         (if (contains? seen lookup-key)
                           (recur (rest s) seen)
                           (cons f (step (rest s) (conj seen lookup-key)))))))
                   xs seen)))]
     (step coll #{}))))

👍 8
jaihindhreddy-duplicate15:09:09

@andrea.crotti Your code then becomes

user=> (def input [{:a 1 :b 1} {:a 2 :b 2} {:a 1 :b 99999} {:a 2 :b 99999} {:a 3 :b 4}])
#'user/input
user=> (distinct-by :a input)
({:a 1, :b 1} {:a 2, :b 2} {:a 3, :b 4})
user=> ; Or with a transducer

user=> (into [] (distinct-by :a) input)
[{:a 1, :b 1} {:a 2, :b 2} {:a 3, :b 4}]
user=> 

andrea.crotti15:09:25

hehe we have a list of max 50 elements and 10 keys, I'd rather use the simplest possible solution

basti17:09:01

I’m fairly new to Clojure and I’ve got a question regarding core.async channels. I’m using a http library which returns a channel - Now I want to do two http request at the same time and then “wait” for both to complete. How do I achieve such?

basti17:09:06

moving the question to #core-async .. might be a better place

the2bears17:09:36

If you have multiple channels, look into alts!

the2bears17:09:49

exclamation point in the function name, not my comment 😉

joelsanchez17:09:32

you can also check out alts!!

noisesmith18:09:53

conversation continues in #core-async but since both results are needed for the next step, just calling <!! on each channel suffices

lilactown18:09:26

putting this here as well as #clojure-spec

lilactown18:09:40

I have a map of var-quoted functions that I'm using as a lacinia resolver map. After adding fspecs for all of them and turning on instrumentation, I'm getting this error:

com.fasterxml.jackson.core.JsonGenerationException: Cannot JSON encode object of class: class clojure.spec.alpha$regex_spec_impl$reify__2436: clojure.spec.alpha$regex_spec_impl$reify__2436@29cbdd3c

lilactown18:09:22

removing the var-quoting resolves the error. is there any way I can var-quote a function that's been fspecced?

urzds19:09:01

I am trying to print a LazySeq as (println my-lazy-seq), but Clojure tells me: java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn Any suggestion on what my mistake might be?

noisesmith19:09:30

println won't cause that error, but extra parens around your lazy-seq will

urzds19:09:09

Was rather easy: I used (-> ... (map f)) to create the LazySeq, a mistake that only surfaced when trying to use its elements and thus realising it.

enforser19:09:08

->> will pass ... to the end of (map f) ... (->> ... (map f)) should work

lilactown19:09:13

for those of you that use JDBC, how do you go about automating tests for your queries?

dadair19:09:58

You can use clojure.test fixtures to set up DB state and have it automatically roll-back between tests, then have individual tests run queries

👍 4
benzap00:09:10

I vouch for this, it works surprisingly well for any language

lilactown19:09:50

do you use any sort of embedded DB or special driver?

lilactown19:09:55

e.g. my app talks to Postgres in AWS RDS, but I imagine I could spin up a local Postgres(-ish?) instance and initialize test data in it

jaide22:09:16

breathes Had to go to the django IRC

jaide22:09:42

Fine community but once you get into Clojure & FP having to ask questions like “How I do model this SQL in Django’s QuerySet?” reminds me why I sought refuge elsewhere 🙂

briantrice22:09:47

Django ORM is fairly broken 😕

jaide22:09:18

Hah that doesn’t surprise me! Any specific issues come to mind? Anything that makes a good case to start moving towards Clojure would be much appreciated.