Fork me on GitHub
#clojure
<
2017-05-31
>
danielsz00:05:10

Hi everybody, I'm announcing a Clojure client for letsencrypt. https://github.com/danielsz/certificaat/

jeff.terrell00:05:17

@danielsz Nice. 👍 Maybe also announce in #announcements?

danielsz00:05:06

Will do. Sure. Thanks!

stephenmhopper00:05:58

Hey everybody, I have a quote about Clojure and FP in my head that goes something to the tune of, “With functional programming, you define the problem, you define data structures that solve that problem, and then you write functions to operate on those data structures” or something like that. I think it was in a Clojure talk. Anybody know where this is from?

mikera01:05:25

Any nREPL experts here? I have a quick question on #nrepl

clj.max02:05:18

@stephenmhopper was it the talk about modeling domain first? with a computer game as an example?

clj.max02:05:41

anyone have an idea how I could refactor this code?

(defn average-numeric [series]
  (let [limited (take average-days series)
        length (count limited)]
    (->> limited
         (map :value)
         (reduce +)
         (* (/ length)))))

clj.max02:05:06

It used to be all lets for each of the steps in between, both the */ (because thread-last) and re-using limited feel weird

clj.max02:05:20

but I like using threading in general, very nice to read

mikera02:05:56

I prefer lets when you are doing multiple transformations. Makes the meaning of your intermediate values explicit if you give them good names.

clj.max02:05:14

i guess that's true

clj.max02:05:25

it just read weird, a 4 line let statement, and the function body was just avg

clj.max02:05:22

(btw is this the right channel for a question like this?)

clj.max03:05:54

I remember that talk, pretty cool. Especially because I've played that game before 😉

clj.max03:05:05

Really interesting how easy it is to capture the entire game mechanics

tianshu04:05:55

Is there a good way to do leader election?

kevinludwig04:05:18

Im wondering what might be a decent way to execute code based on matching namespaced keywords. For example, in some cases I want to execute based on a namespace match, sometimes based on namespace+name, and other times just on name.

Oliver George04:05:08

Is there a way to stop pprint from putting commas in the output?

Oliver George04:05:20

e.g. {:a 1, :b: 2}

pradyumna06:05:38

Has anyone tried running lein repl in azure kudu console. I managed to launch the repl but then it kind of stuck and not responding to my input. After sometime the console gets reset.

iku00088807:05:37

Is there a way to look up implementors of a protocol?

mpenet08:05:50

@iku000888 there's a (half) broken way to do it looking up (:impls IFoo)

mpenet08:05:08

this wont work for inline defs tho, I wouldn't rely on that stuff at all

mpenet08:05:45

"inline" would be stuff like this: (defrecord Prout [] IFoo (foo [x] 42))

matan09:05:12

Is there any clojure.core macro or workaround usage pattern, for referring to one map key while initializing another, all in a single map-initialization form?

matan09:05:47

e.g. to do accomplish something like {:a 3 :b (+ :a 3)}

mpenet09:05:49

@iku000888 satisfies? would be the clean way to get around this, but I don't know your use case

rauh09:05:15

@matan (as-> ...) with using assoc

matan09:05:43

@rauh care to briefly demonstrate that in context?

rauh09:05:39

(as-> {:a 3} X
      (assoc X :b (:a X)))

matan09:05:01

@rauh thanks, but I think I'd rather write a macro, perhaps one wrapping around such an as-> impelmentation

matan09:05:59

how does as-> effectively defer from a let statement? looks like the only difference is it returns only its last computation. Am I mostly right in that?

mpenet09:05:31

as-> is just useful in threading "chains"

rauh09:05:32

It's just implemented as a long let. But plumbing is exactly what you want and much faster.

mpenet09:05:38

in that case let actually reads nicer imho

rauh09:05:17

Agreed, I would just use a straight forward and easy let. (and not the as->)

matan09:05:25

well going back to my original use case, I already have a let where one value is built from the other, the problem is I wish to write them all into a map in the end. that map looks very silly, it has the form {:a a :b b :c c ....}

matan09:05:46

very ceremonial....

rauh09:05:53

Did you check the link I posted? It's exactly what you're asking for. Building maps with dependencies in between

matan09:05:35

@rauh must have missed it, will do

pasi09:05:20

out of curiosity, why are clojure let bindings syntactically vectors and not maps? Is it just "lisp convention" or is there a practical reason?

pasi09:05:31

they're always pairs after all, aren't they?

leonoel09:05:46

@pasi because ordering matters

pasi09:05:41

ah yes, obvious now that you say it.

matan09:05:02

well, thanks for the help! will complete writing a macro

rauh09:05:25

I've never used it, no

matan09:05:49

well, seems heavily starred on github 🙂 yet kind of a DSL on top core clojure. thanks again 🙂

rovanion11:05:45

Does anyone here happen to know how to change the locale when using format? https://stackoverflow.com/questions/44281495

misha12:05:06

is there an easy way to redefine defmulti in repl? (update dispatch function)

misha12:05:08

@robert-stuttaford yeah. reading into that right now, thanks. Though, "workflow" never sounds easy

weavejester13:05:29

@misha the tools.namespace library has a refresh REPL function that clears out namespaces before reloading.

pesterhazy13:05:07

@misha, another trick is to def the same symbol just before defining the defmulti, for reloading

pesterhazy13:05:42

(def foo nil)
(defmulti foo :type)
(defmethod foo ..)

misha13:05:07

@pesterhazy @jfigueroa nice, both require to re-eval defmethods after, so those are ok, if all defmethod are in the same place, thanks

pesterhazy13:05:14

right, that's (part of) the reason why multimethods don't have the same reloading semantics as defns

paragmedsinge13:05:07

is there any codecamp kind of stuff which help me start with Clojure

sgerguri14:05:36

@paragmedsinge http://www.braveclojure.com/ might be a good resource. Not a codecamp but has examples for you to code along with.

misha14:05:39

is there a way to force transit to cache a certain value (certain = 5th in this vector)?

misha14:05:55

this is snippet of datascript db's transit string as of now:

[94,"^A",28,536870913]],["^N",[94,"^C",3,536870913]],["^N",[94,"^2",100,536870913]],["^N",[94,"^K",4,536870913]],["^N",[94,"^<",3,536870913]],["^N",[94,"^E",10.5,536870913]],["^N",[95,"^A",18,536870913]],["^N",[95,"^C",3,536870913]],["^N",[95,"^2",100,536870913]],["^N",[95,"^K",77,536870913]],["^N",[95,"^<",3,536870913]],["^N",[95,"^E",1,536870913]],["^N",[96,"^A",24,536870913]],["^N",[96,"^C",3,536870913]],["^N",[96,"^2",100,536870913]],["^N",[96,"^K",6,536870913]],["^N",[96,"^<",7,536870913]],["^N",[96,"^E",116,536870913]],["^N",[97,"^A",16,536870913]],["^N",[97,"^2",1,536870913]],["^N",[97,"^K",78,536870913]],["^N",[97,"^<",3,536870913]]

misha14:05:49

caching 536870913 in this case would make it half as long

misha15:05:25

it seems I can do (str tx) on transit-write, and (int tx-str) on-transit-read. need to run some perf and length benchmarks

misha15:05:11

yeah, @ghadi based my str assumption above on that. Thank you

michaellindon15:05:11

Hi Guys, I have memory issues, I'm running out of memory doing (take 1000 (iterate update-state initial-state)), this is because state is pretty large. If i were to thin the iterates, by doing say, (take 100 (take-nth 10 (iterate update-state initial-state))) do I use 1/10 of the memory space? Or does it still store the whole 1000 iterations in memory and return every 10'th one

captainlexington15:05:09

@michaellindon How does update-state work?

michaellindon15:05:25

it just maps a map to another map

michaellindon15:05:49

initial-state is a map

captainlexington15:05:54

Based on what? Does it take in user input or something?

michaellindon15:05:21

no it just contains some different data structures, no user input

captainlexington15:05:07

If update-state returns the predictable input based on the iterator and the state, then you probably don't need to take any except the last piece of state

dpsutton15:05:44

just make it an infinite lazy sequence and take what you want?

michaellindon15:05:09

so for my application, im doing markov chain monte carlo, i need all the iterated values, if thats not possible i can thin the chain, and take every n'th one

michaellindon15:05:42

@dpsutton i thought iterate was a lazy sequence, to some extent

captainlexington15:05:17

iterate is lazy, but if you need to calculate n-1 to get n, then it all n still get calculated

dpsutton15:05:19

yes it is. I guess i was thinking (def states (iterate update-state initial-state))

dpsutton15:05:36

so it was a dumb suggestion 🙂

dpsutton15:05:58

what's the size of the map?

michaellindon15:05:13

@captainlexington i do indeed need to n-1 to get n... however cant some of these be garbage collected if n modulo 10 is not zero?

captainlexington15:05:52

Oh I see - you don't want to skip the calculations, you just don't want to store all that data after they've been calculated?

michaellindon15:05:17

i need the 9th state to get the 10th state, but after that i dont need 9 any more

dpsutton15:05:30

(take x (drop (- 1000 x) states)) ?

captainlexington15:05:30

Then I think your original snippet would do what you want

michaellindon15:05:56

ok, thanks for clarifying, i take it then that only the iterates divisible by 10 get stored in memory, and the other iterates get garbace collected after they've been used.

ghadi15:05:00

you can use (nth 1000 (iterate ...)), or (drop 1000 .... )

ghadi15:05:18

your original example was using take 1000, then retaining all the taken states

michaellindon15:05:26

@ghadi i need more than just the last one 🙂

michaellindon15:05:36

its motivated by the application

michaellindon15:05:48

im generating autocorrelated samples from a probability distribution

michaellindon15:05:42

but because they are correlated, i can take every n'th one, and not lose a lot of information

michaellindon15:05:24

i think my question has been answered. Thank you. I understand the (take 100 (take-nth 10 approach to use 1/10th of the heap than (take 1000

michaellindon15:05:30

im going to check this empirically, it doesnt seem to be the case when i am checking the heap usage by visualVM

dpsutton15:05:54

can you increase the memory of your jvm and see if that alleviates the problem? not that this is the best solution but this could confirm that its just the size of the maps

michaellindon15:05:02

maybe after the whole thing is executed, the other iterates get garbage collected, but while the iterations are running i think they are all still in memory

michaellindon15:05:34

i can try increasing the heap size too

michaellindon15:05:15

because the line hasn't finished executing, im not sure if the other states aren't getting garbage collected. I think they may get garbage collected once (take 100 (take-nth 10.... completes

michaellindon15:05:50

i was hoping that the 9th iterate would get garbage collected as soon as the 10th iterate was computed. but it looks like its building up all the iterates in memory and then when it completes it will garbage collected the unwanted iterates

michaellindon15:05:04

ill let you know if theres a dramatic decrease in heap usage when the iteration has fininshed

dpsutton15:05:33

maybe try drop?

noisesmith17:05:30

@michaellindon btw there is a sample transducer for making fair samples of a lazy-seq

noisesmith17:05:41

=> (doc random-sample)
-------------------------
clojure.core/random-sample
([prob] [prob coll])
  Returns items from coll with random probability of prob (0.0 -
  1.0).  Returns a transducer when no collection is provided.
nil

john17:05:46

@michaellindon You may also be better served by a reduce, since you don't' need the results of every iteration.

john17:05:27

Then sprinkle on some transduction too

hiredman17:05:46

iterate was a chunked seq until 1.7 if I recall, which has memory usage implications

hiredman17:05:33

you might want to check your state stepping function to ensure you are taking advantage of structural sharing

john17:05:59

oh, nevermind: " im doing markov chain monte carlo, i need all the iterated values,"

michaellindon20:05:54

@noisesmith I think this is along the right track, can you perhaps elaborate a little please?

noisesmith20:05:05

it’s a function / transducer meant for collecting a sample, like a randomized take-nth

michaellindon20:05:13

I'll look into it, thanks

seancorfield20:05:21

Saw this posted on the Clojurians Discord and figured I’d re-post here — as a good talk about introducing new technology (e.g., Clojure) into a company: https://www.youtube.com/watch?v=GCsxYAxw3JQ

ghadi20:05:08

@olikasg Fundamentally map is lazy. You only see the error because the repl tries to print the list, which is not lazy.

dpsutton20:05:28

i believe it is laziness. the debugger forces realization of the whole list inside the scope of the try catch. In non-interactive mode, you are not actually computing those values until you are consuming them, far away from the try catch.

ghadi20:05:53

The try block you have written exits immediately, then the repl tries to realize the list in order to print it, and it blows up, because it's calling #(Integer/parseInt %) and that is not in a try/catch

wiseman20:05:50

i wonder if any of the clojure linters warn about this scenario.

noisesmith20:05:39

the easy fix to this in general is to put the try directly on the thing that errors, inside the lazy-seq

olikasg20:05:33

So if I understand correctly (try (anything-lazy) (catch ...)) does not catches any exceptions…

hiredman20:05:26

(let [f (fn [] (throw (Exception.)))] ((try f (catch Exception _))))

bfabry20:05:37

@olikasg not if (anything-lazy) successfully produced its (presumably) LazySeq no

ghadi20:05:46

that's right @olikasg -- specifically when you realize the lazy thing later

olikasg20:05:34

I see… a bit confusing, but makes sense if I count in lazyness

hiredman20:05:59

exceptions happen when you execute code, laziness defers code execution, a try catch has to be around the execution to catch an exception

olikasg20:05:56

Thanks for the help. I used (vec (map ...)) to realise to list. I need a vector anyway. But @hiredman’s solution seems more generic for the future. And it raises another question: is the bindings vector lazy in let?

hiredman20:05:12

that isn't a solution

hiredman20:05:20

that is an illustration

dpsutton20:05:56

no vector is lazy

hiredman20:05:17

a function is also a suspended execution, and similarly, you can use it as a value without getting an exception until you invoke it

hiredman20:05:20

saying 'map is lazy' is something of a misnomer, map returns a lazy sequence

hiredman20:05:18

clojure is a strict language (the evaluation semantics are not lazy) but, as in most strict languages, you can construct values that represent computations

hiredman20:05:52

a function is one sort of value that represents a computation, a lazy sequence is another

olikasg20:05:46

yes, of course… Sorry it is a bit late for me. Thanks for the clarification.

hiredman20:05:50

sure, I know I can be someone pedantic about these things, but I don't know your background or experience level with this sort of thing, so I am trying to make it as clear as possible and relate it to other concepts typically encountered

olikasg21:05:41

clarifications are always welcome… I am not new to functional programming, but there are no laziness in Erlang 🙂

bfabry21:05:59

@olikasg just for the record using mapv or transducers when you know what the shape of your output should be and you know you don't want lazy computation will be both more efficient and read a little better

olikasg21:05:07

Anyway, a small clarification to your example:

(let [f (fn [] (throw (Exception.)))] (try (f) (catch Exception _)))

hiredman21:05:36

forcing a lazy value is equivalent to function invocation. so moving the function invoke inside the try/catch is like calling dorun on a lazy sequence inside a try/catch

hiredman21:05:56

http://chrisbriones.com/posts/getting-lazy-with-erlang seems like a blog post creating something like lazy seqs in erlang

olikasg21:05:43

Nice. Although it is worth mentioning that eager evaluation was one of the design principles of erlang, because it makes reasoning about the program very easy. You need to work hard to get laziness. But I do not want to spam here.