Fork me on GitHub
#clojure
<
2016-06-24
>
lwhorton02:06:05

is there a quick way to mark “this entire thing is optional” via plumatic/schema?

lwhorton02:06:37

i.e. I have {:foo 1 :bar 2 :baz 3 … :zzz 26}, but each one of those keys is optional.

lwhorton02:06:55

I would prefer not having to do (schema/optional-key down the line, if possible

gfredericks02:06:26

lwhorton: you could do it programmatically

gfredericks02:06:00

I wrote a function called optionalize-key once

gfredericks02:06:22

you could use it to optionalize all the keys via (reduce optionalize-key map-schema (keys map-schema))

gfredericks02:06:40

any number of similar tactics would work too

cfleming03:06:55

Is there anything like a for loop (allowing iteration over multiple variables) with reduce-like accumulation rather than generating a seq?

cfleming03:06:51

I occasionally end up having to do nested reduces, where each level uses closed-over bindings from outer levels so I can’t easily extract them into reducing functions.

josh.freckleton04:06:06

@cfleming: are you familiar with loop/recur? It sounds like that's what you need, and I've used it before to un-nest multiple reduces.

cfleming04:06:38

@josh.freckleton: I could do that, but it’s a pain having to manage the seq iteration manually.

josh.freckleton04:06:47

what do you mean? loop/recur doesn't need to accumulate to a seq...

josh.freckleton04:06:47

@cfleming: could you be more specific about what you're trying to solve?

cfleming04:06:03

@josh.freckleton: What I mean is that if I use loop/recur, I need to use code like:

(loop [items (some-seq)
       accumulator (some-initial-value)]
  (if-not (seq items)
    accumulator
    (let [item (first items)]
      (recur (rest items) (do-some-processing accumulator)))))

cfleming04:06:23

That’s just one loop level, it gets worse with multi-level.

cfleming04:06:53

Compare that with (reduce do-some-processing (some-initial-value) (some-seq))

josh.freckleton04:06:01

I'm not crystal clear what you're trying to solve, but I've had (what I assume are) similar situations that I've solved in one loop, where the loop keeps track of a few items, and then your conditional can be a cond or case that accounts for the multiple different items... would that help?

cfleming04:06:22

Here’s what I’m working on:

cfleming04:06:16

(WIP, contains bug right now where intermediate map levels are not created correctly, but you get the idea)

cfleming04:06:43

So here I’m iterating over modules, and within modules I’m iterating over namespaces.

cfleming04:06:20

It’s an ideal match for a for loop, except I’d rather not create a potentially large intermediate seq just to do (into {})

cfleming04:06:01

That function is just too big, but I can’t trivially extract the reducing functions because they close over outer values.

josh.freckleton04:06:25

I need to leave soon, so regrettaly dont have time to dig in. But to explain my solution to similar situations, imagine in your loop you have modules and nss, you only exit when both modules, and nss are empty. If nss is not empty, process one, loop on the rest. If nss is empty, then load the next module, fill up nss for the next go-round, and process until both of those seqs are empty.

cfleming04:06:52

This case isn’t too bad, but with another level (which I’ve had from time to time) it gets pretty hairy.

josh.freckleton04:06:23

ya, I think my solution is an elegant way have handling arbitrarily many seqs to loop over

josh.freckleton04:06:30

(if I'm understanding)

cfleming04:06:41

Sure, but like I say, you end up with a lot of manual seq management - I’ll try it, but I suspect that it’ll be a wash.

cfleming04:06:52

Thanks for the suggestion though, I’ll definitely try it.

josh.freckleton04:06:45

no problem, I hope it helps! is my proposal clear? it would look something like this: (working up an example...)

josh.freckleton04:06:31

(let [rr (comp reverse range)]
  (loop [a   (rr 3)
         b   (rr 3)
         c   (rr 3)
         acc []]
    (cond
      (empty? a) acc
      (empty? b) (recur (rest a)
                        (rr (first a))
                        (rr (first a)) acc)
      (empty? c) (recur a (rest b)
                        (rr (first b)) acc)
      :else      (recur a b (rest c)
                        (conj acc (apply str (map first [a b c])))))))

josh.freckleton04:06:07

@cfleming: (not my cleanest code, but it gets my idea across. It effectively looks like one loop, even though the seqs a b c are all getting looped over)

josh.freckleton04:06:56

@cfleming: so you start with 3 seqs, a is the highest level, followed by b then c. When c is empty, it fills up again from b. Same with b from a. When a is empty, you know that there's nothing left to process. The last line of code with conj ... is where you do the work using the relevant parts of a b c.

cfleming04:06:17

@josh.freckleton: Thanks - that does actually look pretty clean. I’ll give that a go, thanks!

bensu05:06:48

if I have a java object that implements an interface (`WebDriver`) and a clojure protocol (`IDriver`) that is extended over that interface (`(extend-type WebDriver IDriver …)`) should the protocol work over any java objects that also implement the interface?

danielcompton05:06:03

@cfleming: is reductions helpful?

agi_underground11:06:50

hello, someone know why when i am try to insert values into postgres like this: (sql/insert! db :users {:email (:email user) :password (:pass user) :username (:username user)}) in db i had field with free spaces? most of columns 100 symbols length according db scheme. but when i try to compare same values from db and (noir.util.crypt/encrypt ourpass) its different, because i think problem if free spaces? db gives me pass like this "somehashingpass " - my pass to compare is "somehashingpass" i use [org.clojure/java.jdbc "0.6.1"] and driver [org.postgresql/postgresql "9.4.1208.jre7"]

berrysoup12:06:21

Hi, I need to use rdf4j repository with lucene index. These all things are provided but it seems it is not thread safety somewhere in deep on the lucene side. So I should assume the pessimistic variant that thread safety is not provided at all. I would like to wrap the repository in one thread and communicate with the rest through the channel. Multiple threads will do input file reading and populate the channel. What do you think about that. Is it possible to implement it in a quick-and-dirty solution?

manutter5112:06:16

@agi_underground: is the password column defined as CHAR or as VARCHAR?

manutter5112:06:59

That’s why then. CHAR always pads out to the full width of the column, use VARCHAR to keep only the actual length of the string

manutter5112:06:42

(I’m hoping that’s right anyway, I haven’t done postgres for a while, but I think that’s standard SQL)

agi_underground12:06:51

@manutter51: yes, thank you, it`s work!

si1415:06:50

hi there! are there any opinions on the new "Professional Clojure" book yet? My google searches came out empty :(

jjfine15:06:47

I find myself doing quite a bit of this: (remove nil? (map :some-key heterogeneous-collection)) Wondering if it's a code smell

m1dnight15:06:47

Read it and be the first? >:)

bronsa16:06:07

@jjfine: keep

bronsa16:06:24

unless you care about false nevermind it actually checks for nil? so you're fine

jjfine16:06:34

nope! thanks!

richiardiandrea17:06:15

What do folk use/suggest in Clojure (or ClojureScript) for mesh manipulation (remeshing, extruding, etc ...) ?

richiardiandrea17:06:44

(I do not need the rendering part, only the processing of it)

danburton22:06:30

I'm curious to know the explanation behind this:

user=> (clojure.set/difference #{"foo" "bar"} ["bar" "foo"])
#{}
user=> (clojure.set/difference #{"foo" "bar"} ["bar" "foo" "quux"])
#{"bar" "foo"}

danburton22:06:07

What I understand is that clojure.set/difference expects sets for all of its arguments.

danburton22:06:21

What I don't understand is why it does what it does when given vectors.

alexmiller22:06:48

That’s just what happens as a result of the implementation (which expects sets) - you can read the impl to understand why. The result you’re seeing won’t make sense as it violates assumptions in the impl.

danburton22:06:20

Oh I see; it uses a different code branch based on the sizes.

danburton22:06:03

If contains? worked on lists in the way I wish it worked, then the set difference algorithm would work with lists as the second argument as well.

bronsa23:06:10

if contains? worked the way you wish it worked, it wouldn't be contains? :)