Fork me on GitHub
#clojure
<
2017-08-20
>
andrea.crotti10:08:03

I started now to use honeysql and write some queries with it, and initially just creating functions like

(->
 (h/select :id)
 (h/from :people)
 (h/where [:= :email-address email])
 (honey/format))

andrea.crotti10:08:09

however I noticed that what's actually used (as jdbc function call) to execute these queries depends on the type of query itself

andrea.crotti10:08:34

so for example I have to use jdbc/query for a select instead of jdbc/execute! so I translated to something like this instead

(defn get-person
  "Lookup someone by email and return its id or nil if not found"
  [email]
  (let [result
        (j/query
         DEFAULT-DB-URL
         (->
          (h/select :id)
          (h/from :people)
          (h/where [:= :email-address email])
          (honey/format)))]

    (when (not= result '())
      (-> result (first) :id))))

andrea.crotti10:08:52

I can still leave the actual pure SQL generation out, but not too sure it's worth since the two things are not actually independent

andrea.crotti10:08:16

any other suggestions about how to do this?

qqq12:08:23

when a runtime error happens inside a block of code generated by a macro, is there anyway to get a location more precise than the line where the macro was called ?

noisesmith14:08:18

@qqq a macro is going to expand to one line though, and I don't think there's a way to get finer grained info about which part of the macro made that happen? Though the stack should show some call in the recursive expansion of that macro of course

qqq15:08:25

@noisesmith : there is no way to attach meta data to the sub expression that the amcro generates to specify other line numbers?

noisesmith16:08:58

hmm... I haven't heard of that - usually the metadata is on the var and is attached by def or defn

qqq16:08:58

I guess clojure really is strongly pushing "don't use a macro when a function suffices" 🙂

laujensen19:08:14

I see that not all users are assigned a ring session id when they access a page through a handler. What could be the reason for ring not assigning a session id ?

val_waeselynck19:08:19

I think the middleware waits for something to be written in the session

noisesmith19:08:41

right, if you don't attach any data to the :session key, it doesn't create a session

noisesmith19:08:44

in my usage that's probably attaching the id for that user in the db, but it could just be an incremental index if you are tracking users without auth

laujensen19:08:35

I always have some info in the session, just missing the session id for about 10% of the users

laujensen19:08:51

(or (get-in r [:cookies "ring-session" :value]) "No session")

laujensen19:08:57

ie. this is No Session for 10% of users

laujensen19:08:44

Oh sorry gentleman. In the case of a 301 redirect the session is not prepopulated. Thanks for the help!

olfal20:08:49

Hello! I have a seq of hash maps and I’m looking for the most Clojurian way of looping through every maps and adding a new key/value pair based on the map at the previous index… For example, I want to add a new :b key which value would be the :a key of the previous map. I initially have [{:a 2} {:a 7} {:a 1} ...] and the output should be [{:a 2, :b 0} {:a 7, :b 2} {:a 1, :b 7} ...] So we could say B(x_i) = A(x_i-1). Using a loop + recur is super easy, but implies a lot of boilerplate… Is there a cleaner way?Thanks!

noisesmith20:08:13

@olfal that would be a reduce

noisesmith20:08:48

something like (reduce (fn [[acc b] m] [(conj acc (assoc m :b b)) (:b m)]) [] maps)

noisesmith20:08:13

you could also use map over partition

noisesmith20:08:48

(map (fn [[m0 m1]] (assoc m1 :b (:b m0))) (partition 2 1 maps))

noisesmith20:08:24

you might want (cons {} maps) instead of just maps with the partition version

olfal20:08:56

Interesting! Thanks, I’ll test this out

noisesmith20:08:11

another version with map is (map (fn [b m] (assoc m :b b)) (cons nil (map :b maps)) maps)

noisesmith20:08:19

that might be the nicest one actually

olfal20:08:28

That’s clever 😄

noisesmith20:08:35

but my usual first instinct is reduce for anything that could be represented as a carried state over a collection processed in order

didibus20:08:53

Does anyone actually use lazy evaluation in a useful way?

seancorfield20:08:53

We use it to wrap a pagination external search so we can treat it as a (potentially) infinite stream of search results.

martinklepsch21:08:16

I have a sorted list of dates and want to bucket them in intervals for which I have a lazy seq of intervals that expose a within? method — but I’m now struggling to figure out a way to do the actual partitioning. I could use partition-by and return the interval but then would need to check each date against multiple intervals (except for the ones belonging to the first interval). Does anyone have some better ideas?

carocad10:08:27

@martinklepsch not sure if I understand you correctly but I guess you could use the same principle as the R-Tree algorithm for spatial points. Basically create a tree of intervals (initially empty) and create subintevals as you receive more dates. The 2 months condition would then be the minimum size of an interval and retrieving the dates for a specific interval would be querying the tree. Hope it helps 🙂

martinklepsch10:08:01

(defn partition-interleave*
  [pred interleave-seq to-partition]
  (reduce (fn [acc interleave-item]
            (let [[in-partition rst] (split-with #(pred interleave-item %)
                                                 (:to-partition acc))]
              ;; (prn ‘in-partition-cnt (count in-partition))
              ;; (prn ‘rst-cnt (count rst))
              (if (seq rst)
                (-> acc
                    (update :partitioned conj interleave-item)
                    (update :partitioned conj in-partition)
                    (assoc :to-partition rst))
                (reduced (conj (:partitioned acc)
                               interleave-item
                               in-partition)))))
          {:to-partition to-partition
           :partitioned []}
          interleave-seq))

martinklepsch10:08:22

Ended up with this which gets the job done but isn’t too pretty 😛

carocad10:08:42

well it totally depends on the case. If your seq isnt too big then there is no need to care for perf. I just had a similar case a while ago which needed to execute very fast so the Rtree approach was better for that.

martinklepsch11:08:16

@U0LJU20SJ thanks, I added a note to my code so that I remember when/if I run into perf issues

carocad11:08:27

@martinklepsch coincidentally I just stumble into this right now 😄 https://github.com/Breinify/brein-time-utilities

martinklepsch11:08:06

oh that looks nice indeed

carocad12:08:02

@martinklepsch sorry to keep posting but I just got hanged into reading about this 🙂. I just found out that Clojure itself has support for this built in: https://clojuredocs.org/clojure.core/subseq. Check the second example and replace :a and :b with :start-time :end-time and you got yourself a working sorted-tree with lookup for free !

martinklepsch21:08:59

If the description above isn’t clear enough I hope this bit of code and the example might help: https://gist.github.com/martinklepsch/bcabc82bd2da32d66a89c1235ff914cf

martinklepsch21:08:26

I guess reduce will do the job in the end but just wondering if anyone has any clever or particularly elegant approaches to offer 🙂

hmaurer21:08:54

Hi! I keep getting NullPointerExceptions without stack traces when debugging an app running in Lein repl. A warning notifies that I should disable OmitStackTraceInFastThrow to get a full stack trace but not sure how to do that (top google results don’t seem to work)

didibus21:08:17

I feel like as cool as laziness is, it turns out to be more of a hassle 99% of the time. I'd have preferred eager sequences to be default, and lazy to have maybe an isolated library for it when you absolutely need it. I didn't think this at first, but the more time goes on, I feel like I'm not seeing much value.

didibus21:08:17

STM are the same, but STM are nicely opt-in. I'd have preferred lazy sequences to be opt-in also.

hmaurer21:08:33

@martinklepsch mmh, I quote: > If you’re using Clojure with Leiningen, you don’t have to do anything in development - this optimization is off by default.

hmaurer21:08:44

I am getting this error when running code in lein repl though 😕

martinklepsch21:08:59

Fair point 😼

hmaurer21:08:05

ah, actually I am getting the stacktrace now

hmaurer21:08:08

not sure what happened before

hmaurer21:08:21

really odd; I did get the warning about OmitStackTraceInFastThrow in lein’s repl

hmaurer21:08:49

I’ll look into it later.. thanks!

hmaurer21:08:54

it looks like I don’t get this error on startup (just after starting lein repl)

hmaurer21:08:00

but I do get it after a few runs

hmaurer21:08:02

> Stack trace of root exception is empty; this is likely due to a JVM optimization that can be disabled with -XX:-OmitStackTraceInFastThrow.