Fork me on GitHub
#clojure
<
2018-03-23
>
qqq06:03:09

I have the following setup: 1. there is a LAN 2. on this LAN, there is: server: running http-kit (w/ websocket), port 8000 boot reload node https forwarding forwards 8443 to 8000 using https://github.com/nodejitsu/node-http-proxy laptop: can reach server:8000 and server:8443 chromebook, ipad: can reach server:8000 , but NOT server 8443 3. what tests should I be running to debug this?

benzap06:03:14

Is the laptop on LAN and the tablets on WLAN?

qqq06:03:21

laptop, chromebook, ipad are all on WLAN solved issue: as it turns out: 1. I have a self signed SSL certificate. 2. laptop has the *.cer installed, chromebook/ipad do not 3. chromebook/ipad: instead of asking me if I want to trust the self signed certificate, just decides to say: network reset error

šŸ‘ 4
matan07:03:03

Say I have a side-effecting thing which I need to serialize access to.. I manage serializing access to it through an atom holding a state ā€• :idle or :in-use. Does that make sense to you too? Would you rather use an old-school java lock idiom or something else more clojuresque?

šŸ‘ 4
leonoel07:03:46

the problem with this strategy is you need to make producers actively poll the atom when the consumer is busy

leonoel07:03:32

you can't really solve this problem without some kind of queue

leonoel07:03:20

I would look at agents, or core.async if you need backpressure

matan07:03:31

right, it's really a lazy hack avoiding a queue solution

matan07:03:59

I assume agents will only help as part of a queue solution, unless I'm missing something

leonoel07:03:35

the use case you describe is pretty much idiomatic for agents

šŸ‘ 4
benzap08:03:40

Yeah, I believe agents were included in the language in order to tackle this issue, if you're interested in resources, the o'reilly clojure programming book has a chapter which goes over how the data is accessed concurrently in each scenario, and when to use each concurrency type (atom, ref, agent, var)

matan08:03:15

thanks guys :thumbsup:

matan08:03:38

I guess a java locking idiom would actually do the same as the atom approach, I mean hog the CPU while waiting, or would it be more like the agent approach in its implementation and impact?

benzap08:03:59

I guess it depends on if whether or not you want to use the Java way of dealing with the issue, the tools suggested are just safer to use. I'm sure you could use a lock between two threads

benzap08:03:19

agents take a function similarly to a thread, i've never attempted to use them, I tend to stick to core.async with channels

matan11:03:30

Quite frankly, using clojure's locking, was 3 lines of code to touch and serves well as a stop-gap solution until I have time to fiddle with core.async. This makes sense, as clojure's basic idioms aren't geared toward side effects, side effects are a second-class citizen.

jumar12:03:06

Why isn't delay an instance of IBlockingDeref? The blocking aspect of calling deref on an unrealized delay is not mentioned in deref's documentation and the variant of deref with timeout (3-arity function) cannot be used with delay. I don't see any conceptual difference between e.g. promise and delay in this case, so I think that 3-arity deref should work.

val_waeselynck13:03:49

Maybe because the deref-ing does not happen in another thread, which is necessary for timeout to be possible?

šŸ‘ 4
leongrapenthin13:03:08

Realizing a (delayed) calculation is usually not considered a blocking operation

jumar13:03:49

That's interesting. Thanks!

borkdude16:03:03

Congrats with your post on http://clojure.org @val_waeselynck! Amazing job: https://clojure.org/guides/repl/introduction

šŸ‘ 44
šŸ˜Š 8
šŸŒø 4
šŸ™Œ 12
mfikes17:03:04

This will be a great resource. šŸ™‚

noisesmith17:03:30

@borkdude @val_waeselynk that's great - I'd suggest one more trick for the "troubleshooting" entry - if you accidentally end up in a namespace created by in-ns (typo or forgot to require), you can get back to a semi-sane state by calling (clojure.core/refer-clojure) - after that you can do what you need to get into the ns you needed (require it, fix a typo, whatever)

val_waeselynck18:03:13

@U051SS2EU already explained in Ā«navigating namespacesĀ»

noisesmith18:03:48

oh, I missed that, thanks

schmee17:03:59

@kingcode I use spyscope all the time, it's great

kingcode17:03:12

@schmee I am trying it out with the latest version, and keep getting the following error #spy/p (+ 1 2 3) ;;=> 6 ;;=> 6 #spy/d (+ 1 2 3) ;;=>ClassCastException java.io.StringWriter cannot be cast to clojure.lang.Associative clojure.lang.RT.assoc (RT.java:778)

schmee17:03:31

seems the maintainer doesn't update the project anymore

schmee17:03:15

the fix is in master but the jar hasn't been released

kingcode18:03:37

@schmee Thanks! Will try your fix. I forgot to mention that it works fine with clojure 1.7.0 and spyscope 0.1.5, but would like to use clojure 1.9.0 if possible..Thanks again.

šŸ‘ 4
spei19:03:35

I was trying to understand how to make a reducible collection for a reader following this gist: https://gist.github.com/borkdude/ddc9433c396b1ff43a091cf2901b9dc7#file-text_xform-clj-L15-L26 however, I don't understand the line (recur (f state line)). Where does f come from? Where does state come from?

kingcode19:03:10

@spei f is the argument fn passed to the top call to reduce (line 17). ā€™state is the loop local which becomes (f state line), and is initialized to the value of ā€™init, itself another top level argument to reduce. So essentially, invoking ā€™lines-reducible with the requested BufferedReader will yield an object which is reducible: each element is taken from reading a line in the closed-over reader.

spei19:03:43

@kingcode But the function is called as #(lines-reducible (io/reader %)), no where is f and state ever given

kingcode19:03:01

@spei correct. f is provided by the client code (you?) and state is built up at each step, starting with ā€™init

kingcode19:03:19

@spei just like you would with (reduce + 20 {1 2 3]) replace [1 2 3] with your buffered reader, + with f and init with 20.

kingcode19:03:47

@spei state is the final result returned by reduce

spei19:03:27

maybe i'm misunderstanding how reify works. I just don't see any code that calls the reduce

jumar19:03:28

@spei that's the transduce

jumar19:03:13

if you're talking about the example you referenced

spei19:03:40

i am. thanks!

jumar19:03:38

([xform f init coll]
     (let [f (xform f)
           ret (if (instance? clojure.lang.IReduceInit coll)
                 (.reduce ^clojure.lang.IReduceInit coll f init)
                 (clojure.core.protocols/coll-reduce coll f init))]
       (f ret))))

jumar19:03:34

this is the source of clojure.core/transduce

kingcode19:03:41

@spei example: (def my-reducible (lines-reduce (BufferedReader. (FileReader. (File. <somepath>))))) (reduce my-reducible my-own-func ā€œā€)

kingcode19:03:15

@spei donā€™t worry about ā€™reify. It simple means ā€œIā€™m giving you something that can reduce itselfā€. Try the example I typed in a repl with a real file, and youā€™ll see it works. Use conj and [] for f and init

spei19:03:33

@kingcode i see, that makes sense

kingcode19:03:41

@spei (or somthing similar, I probably made typosā€¦)

spei19:03:16

is there a way to turn the line-seq into a IReduceInit? is that even a valid question? does the lines-reduce function return an IReduceInit?

kingcode19:03:58

@spei ā€œI donā€™t see any code that calls the reduceā€ That is not the point of reify. Reify prepares something for you to make your call(s) on it, using your own function (f) and initialized value (init)..Hope this helps..

kingcode19:03:07

Have you tried it with an example? I think it will help you it you try itā€¦

jumar20:03:12

@kingcode I think it can be confusing when you look at the example in the gist - there's nothing that call reduce; because there's just transduce which calls .reduce internally

kingcode20:03:46

@jumar Aw OKā€¦sorry, will try it myself

kingcode20:03:59

@spei Here is a 2-line code example you can try with the gist code (def br (BufferedReader. (StringReader. ā€œLine 1\nLine 2\nLine 3\nLine4ā€))) (.reduce (lines-reducible br) conj []) ;;=>[ā€œLine 1" ā€œLine 2ā€ ā€œLine 3" ā€œLine4ā€]

spei20:03:10

that kinda makes sense

kingcode20:03:02

@spei Here is the same example using a transducer instead: (def br (BufferedReader. (StringReader. ā€œLine 1\nLine 2\nLine 3\nLine4ā€))) (transduce (mapcat #(lines-reducible %)) conj [] [br])

kingcode20:03:08

@spei you could add more sources (make br1 ,br2 and shove them as last input arg to (transduce ā€¦[br br1 br2])ā€¦

kingcode20:03:49

@spei Good luck and thanks for sharingā€¦

spei20:03:54

@kingcode @jumar thanks for the help, it makes quite a bit more sense now.

arrdem20:03:13

Is there any documentation around regarding writing custom test.check generators? Iā€™m trying to write a generator to sample a collection with a non-level distribution.

schmee21:03:41

I'm guessing you've seen the stuff in the GitHub repo?

arrdem21:03:28

Yeah scanning through all of it atm.

jmckitrick21:03:05

Is there a Clojure equivalent to Scalaā€™s Slick DB?

arrdem22:03:19

Nothing I know of thatā€™s released and really tries to take Clojureā€™s native datastructures and make them transparently durable besides hitchiker-tree. Iā€™m trying to build something like that but itā€™s very much experimental.

arrdem22:03:18

ztellmanā€™s new bifurcan libraries are working towards offering durable models of data which can be round-tripped efficiently but I donā€™t know how much of that works yet.

arrdem22:03:50

clojureā€™s own datastructures are all Java serializable, so you could go put something like this together yourself using say datascript or one of the other in-memory datalogs as a frontend.

arrdem22:03:23

Datomic is probably the closest thing to a database for Clojure out of the box, but it isnā€™t part of Clojure itā€™s a separate product.

gfredericks22:03:23

@arrdem re: generators, did you see my conj talk?

arrdem22:03:06

@gfredericks I donā€™t think so, but after some digging I concluded that test.check just isnā€™t appropriate for the generator semantics I want since I just want to kick out random examples with a known distribution and no shrinking so really I just want to hand-roll my own sampling machinery for this one special case.

arrdem22:03:47

Will definitely check it out tho!

jmckitrick23:03:53

@arrdem Ugh, that stinks. I have a colleague whoā€™s insisting on NOT using HoneySQL/YeSQL style, which I think works fine for scoped micro-services.

qqq23:03:42

is there a builtin function which does truthy -> true falsey -> false ? input: arbitrary object, output: boolean

qqq23:03:55

i.e. (if x true false)

arrdem23:03:56

@qqq clojure.core/boolean

arrdem23:03:29

user> (boolean nil)
false
user> (boolean false)
false
user> (boolean 1)
true
user> (boolean (Object.))
true
user> 

āœ”ļø 4
arrdem23:03:19

@jmckitrick šŸ˜• thatā€™s definitely the common path AFAIK

arrdem23:03:42

I havenā€™t worked with any of the three personally but it feels like Iā€™ve heard more negative experience reports about Korma than the other two.