Fork me on GitHub
#clojure
<
2016-11-04
>
bbloom02:11:14

in case you haven’t read it, this thread between alan kay and rich hickey a while back is pretty awesome: https://news.ycombinator.com/item?id=11941656

jrheard05:11:44

"Other than in this conversation apparently, if you say you have some data, I know what you mean"

bfabry06:11:35

it'd be nice to see that discussion in person maybe, I felt like over the internet they were talking in opposite directions. also possible that I'm just too dumb to understand either of them

bfabry06:11:37

¯\(ツ)

credulous09:11:33

I’m not sure where to ask this because it’s library specific… happy to be pointed to the right place.

credulous09:11:16

I’m using hugsql on top of postgresql. I can’t figure out how to deal with optional columns, and searching the docs hasn’t helped me

credulous09:11:13

For example, a user table with optional address1, address2, city etc. columns… in the update SQL, if any of those are missing from my passed-in map, an exception is thrown

credulous09:11:55

But I obviously don’t want to write an update statement for every combination of possible optional column values

credulous09:11:38

All examples and documentation have simple cases where all fields are present in the map arg, and the docs don’t mention nil values as far as I can find.

manutter5111:11:22

@credulous You could write a wrapper function for your hugsql call. This function would generate a defaults map containing all the required keys, with nil values. Then call your hugsql function like (hugsql-fn (merge defaults args)) Then all your required keys will be present, and any that weren’t given in the map you passed in will have nil as the default

curtis.summers14:11:14

@credulous Take a look at Clojure Expressions support in HugSQL, which allows you to conditionally include portions of your SQL and parameters based on their existence during runtime: http://www.hugsql.org/#using-expressions

kah0ona16:11:27

@manutter51 that would however mean that existing values are overwritten during an update For this reason I use a very dynamic update function for update and insert statements. And for more fixed queries I use yesql or honeysql. That's MySQL in my case, but idea should be similar:

kah0ona16:11:15

the thing above is actually a 'normal' clojure.java.jdbc/insert!

michaeldrogalis16:11:42

@jasonjckn @sorenmacbeth FYI, Onyx doesn’t support dynamic topologies. Jobs can be constructed at runtime since they’re data structures, but once submitted they are immutable.

michaeldrogalis16:11:32

Our stuff is extensively Jepsen and property-based tested. We had to go from scratch to solve a number of systemic issues that are present in other runtimes. Not really trying to sell you on it, just giving you the rationale why we had to do it.

manderson19:11:18

So, I realize this question is so 2 years ago, but I've been having a discussion with a colleague about transducers and wondering if anyone can help shed some light... I understand the benefits of transducers in terms of a useful abstraction and reuse via separating the data from the transformation, but I'm still a bit hazy on how they can improve performance. As a contrived example, why would:

(def xform
  (comp
    (map dec)
    (filter even?)
    (filter #(> % 2))))
(transduce xform + [1 2 3 4 5 6 7])
Perform better than:
(->>
  [1 2 3 4 5 6 7]
  (map dec)
  (filter even?)
  (filter #(> % 2))
  (reduce +))

bfabry19:11:47

@manderson because the first one creates no interim data structures, it passes each value through a function that transforms/drops it and then puts it in the final data structure

bfabry19:11:50

the second one creates a lazyseq at each step, which includes the overhead of creating, as well as overhead of caching specific to lazy seqs

bfabry19:11:52

ie, the first one is as if you did everything in a hand-tuned function passed to a single reduce call

manderson19:11:15

interesting, thanks @bfabry. So the laziness of the second example only helps in that we don't have to iterate the whole sequence each time, but we are still instantiating the seqs at each step. Is that right?

bfabry19:11:31

the first example is equivalent to:

(reduce
(fn [acc v]
  (let [v' (dec v)]
    (if-not (and (even? v') (> v' 2))
      acc
      (+ acc v'))))
[1 2 3 4 5 6 7])

bfabry19:11:43

which if you think about what is going on, is a seriously efficient operation

bfabry19:11:29

and it's kinda incredible that you can describe it in that high level and get similar performance to that hand-written pain

manderson19:11:40

Very cool. Yea, that makes sense. I think the "magic" is starting to be revealed to me 🙂

bfabry19:11:04

there's a bug in my hand-written code. probably not giving an initial value for reduce

bfabry19:11:41

no... eh whatever. you get the point

genmeblog19:11:49

the difference is like: seq -> map -> seq -> filter -> seq -> filter -> + ->seq; versus seq-> (all combined) -> seq

bfabry19:11:53

@tsulej in this specific case there's not a final seq, he's transducing to a number, but yes

bfabry19:11:45

oh and yes, I forgot the initial zero in my hand-written reduce

bfabry19:11:17

some very rough benchmarks on the three ways you could define that problem: https://gist.github.com/bfabry/cfed8fe2ab3b2f323c275d9b7efd699b

bfabry19:11:27

transducer ~2x slower than hand written code, interim sequences about an order of magnitude slower

manderson19:11:35

Nice. That's good info.

rauh19:11:58

After 2 years of clojure, I just learnt there is a (while ...) in clojure.

idiomancy20:11:51

Okay, so if I run a ring server using

(jetty/run-jetty (var slack-app) {:port 3000})

idiomancy20:11:26

it doesn't open up a connection to a dev repl

idiomancy20:11:26

like, in my project.clj i have the

:ring {:handler slack-server.handler/slack-app
         :nrepl {:start? true
                 :port 9998}}
bit that lets you open up an nrepl to your server

idiomancy20:11:37

when you run it with lein ring server-headless

idiomancy20:11:20

(I think you can tell I'm stitching together documentation from several different incarnations of ring/compojure)

idiomancy20:11:41

so how do I make it still open up a dev repl on 9998?

loganmhb20:11:50

@idiomancy the lein-ring plugin uses tools.nrepl to do that when you run lein ring server

loganmhb20:11:11

if you’re starting the jetty server manually, I think you’ll need to start the repl server yourself as well

loganmhb20:11:29

tools.nrepl has instructions for that in the readme

idiomancy20:11:50

okay, awesome. thanks, @loganmhb

tmarble23:11:26

Does anyone know who admins http://clojurians.net? We're running a ClojureBridge and can't get students to signup !!!

tmarble23:11:31

...and it's down