#clojure logs

2015-12-25

00:05TimMcTEttinger: Rodents have pretty mean bites, yeah.
00:06TimMcoooh, and merry Christmas
00:06TimMcI should go to bed.
00:06justin_smithI once got jumped by a squirrel
00:06justin_smithit lived in a warehouse were I worked, and was semi-tame
00:06TEttingermerry ratmas
00:06sohailthanks justin_smith, sente looks pretty good
00:06justin_smithsohail: it's been pretty easy to use
00:06justin_smithas long as you are OK with some core.async to hitch it all up, it works very nicely
00:11TimMcjustin_smith: Raynes said he doesn't plan on deleting the site, or at least not the data. Phew. But it is going read-only.
00:12justin_smithahh, I must have misread or misremembered
00:13TimMcI'm still backing up those pastes. :-P
00:24justin_smithTimMc: that's good - it would be cool to have it searchable by function too
00:25TimMcSearch wouldn't cover the private pastes.
00:28TimMcGrabbed 5303 unique pastes. ^_^
00:30justin_smithTimMc: sure, but you can't back up private pastes can you?
00:49TEttinger5303 pastes eh? I'm compressing a large amount of PNG files again. it seems to be done with 736K files so far
00:49TEttinger2.3 GB processed
00:49TEttingernot even a third of the way done
01:02kenrestivobikeshed time: this double assoc bothers me https://www.refheap.com/113128
01:03kenrestivodouble assoc-in anyway
01:03justin_smithkenrestivo: #(if % (inc %) 1) is (fnil inc 0)
01:03kenrestivofnil, thanks!
01:03justin_smith,((fnil inc 0) 1)
01:03clojurebot2
01:04kenrestivoyeah, i remember it, i'd forgotten
01:04justin_smith,((fnil inc 0) nil)
01:04clojurebot1
01:06kenrestivothe double update-in still bothers me tho
01:06justin_smithkenrestivo: maybe something like (update k (comp #(merge % m) update) :count (fnil inc 0))
01:07justin_smiththat's weird though
01:07kenrestivoit is awkward
01:07kenrestivobut concise
01:07kenrestivomeh, i guess my double thing is at least easier to read and reason about
01:07justin_smithand it nests the ops so the k doesn't get replaced twice
01:08justin_smithbut yeah
01:08justin_smithkenrestivo: there's no rule that says you can't write a proper function for update
01:09kenrestivotrue, then i could also eliminate the useless merge: in cases where count> 1, the m is the same
01:09kenrestivobut my bikeshed limit is reached on this :)
01:10kenrestivoi'm avoiding reading a bunch of javascript docs on react
01:10justin_smithhah
01:10kenrestivoit's funny, i have a bunch of clojure projects that i've dropped at the moment where i have to dive into some other language, because at that point is ceases being fun
01:11justin_smithwhere the clojure project made you need to dive into another language?
01:11kenrestivoevery single one that deals with the real world :p
01:12kenrestivobecause the real world is made of java and javascript and css and c and such.
01:12kenrestivoto answer your question, i've been messing around with reagent, which is pretty nice.
01:13kenrestivoi've come up against a block with how props and such work, so i have to read react docs
01:13TEttingerkenrestivo: you need a lisp machine
01:13kenrestivoheheh, yeah, the computer museum here has a symbolics
01:14TEttingerthere's a dude working on one that runs on a beaglebone black (small raspi-like ARM computer)
01:14kenrestivocool. link?
01:14TEttingerno idea how far he is on it
01:14kenrestivoi have a beaglebone black sitting here
01:14TEttingeroh sweet
01:14kenrestivothey're great little embedded boards
01:16justin_smithI've got a beagle bone black around here somewhere
01:29TEttingerI have uh... a tronsmart MK908
01:30ben_vulpeskenrestivo: how did you come to be using props with reagent?
01:31kenrestivoi want to use :component-did-update, and that requires dealing with props
01:31ben_vulpesah.
01:31ben_vulpeswhat's the story in the code side driving use of :component-did-update?
01:31ben_vulpesnot that i don't believe that you need it, i'm just trying to peer down the road a bit and get out ahead of any leaky abstraction pain
01:51kenrestivothere are a few abstractions: props, lifecycle functions, atoms, and cursors.
01:52kenrestivoi get atoms, i think i understand cursors, and the lifecycle functions are similar to other frameworks that have those. it's just props that have me confused.
01:58kenrestivo:component-did-update seems to require props
01:59kenrestivoi'll play around with it tomorrow. it's probably straightforward, i just haven't seen it explained yet.
02:40ben_vulpesi have no idea about cursors man
02:40ben_vulpesatoms are enough for me at the moment
02:49tolstoycomponent did update is for when the component gets new "state". You might want to do something as a consequence, perhaps directly to the dom, or drop something in a channel, or whatever. You get the old props and the new props. But "props" in OM is the basic state that triggers rendering. Something like that, anyway.
02:49tolstoyI do think it's an "opportunity" to re-think stuff.
02:50ben_vulpestolstoy: so diddling props directly will also trigger a re-render?
02:51tolstoyOh, I think I might have used it to update "component local state" based on changes.
02:51tolstoyben_vulpes: I don't think so.
02:51tolstoyThey're immutable.
02:51ben_vulpeskk
02:51ben_vulpesi'm avoiding component local state like the plague
02:51tolstoyBut you can get the old and the new and compare the two.
02:51ben_vulpeshow do you use that and still get interactive development?
02:52tolstoyLocal state or component-did-update?
02:53tolstoyWhen I used local-state (om.prev) it was for forms, mostly. I didn't care if things got cleared out with Figwheel, or whatever.
02:57ben_vulpeslocal state
02:57ben_vulpesah
02:57ben_vulpesyeah that drives me a bit batty
02:58tolstoyThis app I have now, I just have a :form key in my app-state. When I switch to a form, I clear it. Then the component reconfigures it as necessary.
02:59tolstoyI never have more than one form at a time, so ... it feels like a register in assembly programming.
03:00tolstoyFeels kinda like a dynamic-var, but in a single-threaded, single-user app, it turns out to be far less spaghetti than anything else.
04:07geirbyhey there. what is the best leiningen cljs template to start with? With figwheel and stuff?
04:08ridcully_the figwheel one
04:37geirbyridcully_ oh, ok, makes sense :) thanks
08:27TimMcjustin_smith: I can back up private pastes because I have their URLs, but I wouldn't want to index them -- some of them probably came from privmsg sessions.
08:31TimMcjustin_smith: Maybe I misunderstand private pastes, though.
09:36j-pbhow would you deal with a cyclic deftype dependency? declare doesn't seem to work
09:37j-pbI have a deftype A which might return objects of deftype B. However, B holds a reference to A and I'd like to type-hint it.
10:39justin_smithj-pb: hint the protocol it implements, not the type
10:41j-pbjustin_smith: you can't type hint protocols afaik
10:41j-pbor you mean put the type into the protocol?
10:50sohailjustin_smith: what's the difference between the websocket impl for sente and http-kit?
10:51sohailah it's server-side only, I think.
10:54justin_smithsohail: sente uses http-kit's websockets
10:54justin_smithit's an abstraction
10:55sohailit's so straightforward
11:07justin_smithj-pb: sorry, still waking up. If you call the protocol methods that the deftype implements, you don't need type hints on those calls.
11:07j-pbjustin_smith: yeah, that's a good point :)
11:07justin_smithj-pb: if you absolutely need to type hint usage of each type inside the other, use extend / extend-type to add the methods after both are in scope
11:08j-pbI don't really get sente
11:08j-pb's api though
11:08j-pbI'd either go with callback only or channel only, but it has this weird mix
11:08justin_smithj-pb: it gives you some handlers that set up the websocket / ajax fallback, and some channels that give you core.async messages, and functions to send to the other side
11:09justin_smithj-pb: you only need to use one - I never use the callbacks myself
11:09justin_smith(though I have code I could simplify if I used the callback feature...)
11:10j-pbjustin_smith: sending is done though a funciton though
11:11justin_smithyes
11:11j-pbthis could also be a channel
11:11justin_smithnothing stops you from implementing that channel
11:12justin_smithbut really on a root level it needs to be a function, and has no need to be a channel, so it's a function
11:12justin_smithit's already async
11:44sohailIs there some reason why this lein configuration does not seem to use my handler? http://pastebin.com/VuskVAZz
11:45sohailweird thing is even if I include a typo in server.clj and type 'lein compile', I don't get any error messages which seems to be a symptom of something more messed up
11:45justin_smithsohail: why are you asking figwheel to run your handler?
11:46sohailjustin_smith: I want to be able to debug the client and server in concert
11:46sohailso I just want one server running
11:46justin_smithOK, that might work, but I've never done it that way
11:47justin_smithI wouldn't be surprised if it worked perfectly; I also wouldn't be surprised if it didn't work at all
11:47sohailwell... it's clearly NOT working :) how do you do it?
11:47justin_smithsohail: I start up a normal server, and let figwheel do its own thing
11:47justin_smithI don't need to debug the figwheel server
11:47justin_smithit's already a finished product
11:47sohailwhat about the cljs repl?
11:47justin_smithfigwheel
11:48sohailwhat does your project.clj look like?
11:48justin_smithsohail: can't share it, sorry.
11:48justin_smithI start lein figwheel, I start my webserver, then I go to the page in the browser and my cljs code connects to the figwheel server
11:48sohaildo you use emacs?
11:49justin_smithyes, but no repls inside emacs
11:49sohailah that's probably it then
11:50sohailso you do lein figwheel in one window and lein ring server-headless (or whatever) in another
11:50sohail?
11:50noncomsohail: i do just that
11:50justin_smithsohail: yes
11:50noncomnever had to type anything into the figwheel repl really
11:50justin_smithsohail: in my case I run lein repl, and start the server inside the repl
11:50sohailbut that sweet repl and code completion
11:51noncomi guess first you have to justify using figwheel repl?
11:51noncoman interesting topic for me, since i never found a use in it
11:51noncomso i'd like to know
11:51noncomif you do
11:51sohailthe code completion works inside emacs
11:51noncomah i see
11:51noncomi don't use it then
11:52noncomturneds out it was not essential
11:52noncombut of course, it's nice to have i guess..
11:52justin_smithsohail: I've never seen someone try to run their own handler from the figwheel process. Not that it can't be done, but I definitely have not seen it.
11:52sohailI've never actually used code completion before, but having eldoc work is helpful.
11:53sohailjustin_smith: I was just reading the docs. I'm probably doing something wrong
12:01sohailjustin_smith: FYI the "chestnut" runs both the web server and figwheel in the same repl
12:01sohailthe chestnut template, just tested it and it worked. Now to understand it.
12:30sohailah I see they use profiles to execute stuff in the repl to do the work. Works for me.
12:31pigozhello I am kinda new to clojure and following the braveclojure book. I reimplemented assoc-in and update-in in the exercises. Do these look idiomatic enough? http://sprunge.us/RGYN
12:33justin_smithpigoz: looks OK, though using update is sneaky :)
12:34pigozyou think it makes the exercise too easy?
12:38justin_smithpigoz: no, it's just funny because historically update-in was implemented first, and only later we got update
12:38justin_smithpigoz: of course using assoc instead of update would be simple
12:50justin_smith,(let [days-of-christmas (range 12 0 -1) total-presents (reduce #(+ % (apply + %2)) 0 (take-while seq (iterate rest days-of-christmas)))] total-presents)
12:50clojurebot364
14:10troydmI have some deftype, is it possible for it to implement CharSequence Java interface?
14:11justin_smith,(deftype Dum [] CharSequence (charAt [_ _] \d))
14:11clojurebotsandbox.Dum
14:11justin_smith,(.charAt (Dum.) 88)
14:11clojurebot\d
14:12justin_smithtroydm: I guess if I was feeling less lazy I could have implemented the other three methods on the interface too
14:12troydmjustin_smith: ic, that's what I was asking
14:12troydmjustin_smith: thx
14:17troydmjustin_smith: say I have (deftype A [a b c]) how do I access fields of that deftype outside of deftype method declaration?
14:18justin_smith,(deftype T [a])
14:18clojurebotsandbox.T
14:18justin_smith,(.a (T. 0))
14:18clojurebot0
14:19troydmoh, with a dot just like java methods
14:19troydmjustin_smith: ic, thx
14:19justin_smithtroydm: in fact, it is a method
14:22sohaildoes sente detect client disconnects on the server? Say the user quits the browser without clicking "quit" or whatever. I'm sure it must, but I don't see it.
14:24troydmjustin_smith: can you explain what is (charAt [_ _] \d) <- the [_ _] part? it has two arguments
14:24justin_smithevery method takes the object as the first argument
14:24j-pbtroydm: there is no implicit this as in java
14:25troydmjustin_smith: ohh
14:25troydmjustin_smith: ic, ic
14:32amalloyexcept in proxy, har har
14:34troydmstrange I'm trying to access field of deftype using .fieldName and it says no matching field found
14:35justin_smithtroydm: are you sure it's an instance of the same deftype? changing the deftype definition doesn't change old objects to the new type
14:35troydmjustin_smith: yeah, also field is volatile
14:36troydm^:volatile-mutable
14:36troydmalso that deftype extends a Protocol
14:38justin_smithtroydm: it's not mentioned in the docs but it makes sense - no accessor is generated if the field is not immutable
14:38justin_smithyou are free to make an interface or protocol with a getA method
14:41troydmjustin_smith: ah, ic, thx
14:43justin_smithtroydm: so when do you use volatile fields? I'm scared of them because the vm is forced to synchronize every update with every thread
14:43justin_smithwhich feels like a heavy thing to be doing
14:44troydmjustin_smith: err, well I didn't needed it to be volatile, just mutable only, so I had no idea actually how to make it only mutable
14:45justin_smithtroydm: check out the docs for deftype " They are for experts only - if the semantics and implications of :volatile-mutable or :unsynchronized-mutable are not immediately apparent to you, you should not be using them."
14:45justin_smithtroydm: the difference is that an unsynchronized-mutable can change without guaranteeing that the change is immediately visible in all threads
14:46justin_smithso on the one side you have to ensure that you aren't mutating from multiple threads, on the other every time you make a change you are slowing down every thread in the vm
14:46troydmjustin_smith: well the thing I'm building won't be used in multiple threads simultaneously
14:47justin_smiththen you could safely use an unsynchronized-mutable, and that will perform better, but the folks who wrote the doc string for deftype think you are in over your head
14:48justin_smithtroydm: Java Concurrency in Practice is a good resource if you want to know how this stuff actually works. And it's scary. Immutability and queues become much more attractive after reading that book.
14:50troydmjustin_smith: I've read it, and I know, thx for a hint
14:51troydmalso when you write #"abc" does Clojure compile the regexp pattern or you need to explicitly compile it?
14:51justin_smith#"abc" returns a compiled regex
14:52justin_smiththere is also re-compile if you want to do it by hand, or from a string generated at runtime
14:53troydmjustin_smith: thx, ic
15:02rhg135re-pattern it's called
15:19Bronsajustin_smith: FYI deftype doesn't create getter methods, with (deftype A [foo]) (.foo (A. 1)) is the same as (.-foo (A. 1)) which is just a getfield call
15:19Bronsawith mutable fields those fields are private, that's why you can't access them
15:30justin_smithBronsa: yeah, I knew it was a direct access and not a getter - I was suggesting with something mutable he would probably want a getter
15:31justin_smithBronsa: but the private thing clarifies that, thanks
16:29zactsis Clojure from the Ground Up still good?
16:29zactsor what are the recommended resources for a complete Clojure newbie?
16:29zactsmy main initial goal is to do Overtone music synth with Clojure
16:29MJB47i quite liked "the joy of clojure"
16:29zactscool
16:29zactsMJB47: is this good for a complete newbie?
16:30MJB47yup, it assumed you know nothing about lisp
16:30zactsoh nice
16:30zactsperhaps I'll start there
16:30pigozzacts: I am going through http://www.braveclojure.com/ but have used used lisp/clojure a bit before
16:31zactspigoz: and you like it
16:31pigozyes, the writing style is very fun and informal
16:31pigozgood for my attention span :)
16:32zactsok
16:32zactscool
16:32zactsthanks!
16:34zactsperhaps I'll start with brave clojure to get a feel for the flavor of clojure, and then I'll progress to the Joy of Clojure
16:34justin_smith4clojure.com is good for exercises
16:34zactsoh cool
16:38pigozjustin_smith: oh looks a like a great resource, thanks!
16:39SeyleriusThis is fun: the generated documentation for play-clj has some broken CSS causing the text to fail to render in Firefox, Chromium and Conkeror.
16:41justin_smithoops!
16:41justin_smithshould be an easy pr, right?
16:45SeyleriusYep. Just need to figure out what they're using for docs and what broke it.
17:20sohailDo you have to do anything special to compile cljc besides add it to :source-paths?
17:20justin_smithno
17:20justin_smiththe clojure and cljs compilers use it like they would any other file
17:21sohailI thought so, thanks.
17:26TEttingercfleming: thanks for making open source development with cursive still possible on a nonexistent budget!
17:26TEttingerthis is the best rosh hashanah ever
17:48Seyleriusjustin_smith: Turned out to be a failure of font failover.
17:56justin_smithSeylerius: so it just gives you nothing, instead of a default font?
19:38BRODUSsay i wanted to model digital logic using core async, would a 'mult' be the right thing to use for a clock signal
19:38stainBRODUS: hmmm...
19:39stainbut you would need to make sure the clocks synced up in the other end?
19:39stainsend (tick,signal) in the channel?
19:40stainotherwise the complexity of your modelling function would falsely add delays
19:43stainbut yes, I think a mult would work.. but you would either have to collect all the final channels before you tick the clock signal again (e.g. what you feed into the mult) or do as I say.. which would make your simulation asynchronous (you would probably still want to wait up if the delay is too big)
19:45stainsorry, this is late.. the blocking from the synchronous nature of mult might be enough for your purposes
19:45stainas you wouldn't be able to do the next tick before it's all gone through
19:45BRODUSits ok, thats what i was thinking
19:46stainI'm just thinking that in a digital logic circuit you would do a lot of gates meeting up again, and then you don't want any one of those to do a off-by-one for whatever reason
19:46staine.g. an exception
19:47stainso I would want to basically do a dot product when you meet up so that you match on the clock tick (I guess any delay in the digital logic circuit would be part of the modelling)
19:47BRODUSwell i dont think it would work if you had a clocked gate that depended on other clocked gates
19:48stainright, it could deadlock very easily, you can only do it with a single system clock (real time clock)
19:48stainand then base any frequency generators etc. of that one
19:49BRODUSi dont follow what you mean with the dot product
19:49stainoh.. if you pass (n,signal) then you need to match on n (e.g. the simulated system time tick)
19:50stainso you don't accidentally get offset
19:50stainor you would have to set your exception handler to kill the system clock
19:50stainhave you used Keppler? It has a good tick simulation thingie
19:52BRODUSi will check it out
19:53stainhttps://kepler-project.org/
19:53stainit's a bit old and awkward
19:53stainbut hey.. they did a Christmas release!
19:55BRODUScool
20:22tolstoyOy. Make a little screencast using QuickTime, can't edit and export it with ANYTHING that keeps the same fidelity.
20:33tolstoy1080p export -> blurry. ProRes -> 5 gigs.
20:34ridcully_are you sure, this is the right channel for this?
20:35tolstoyOf course it's not.
20:38tolstoyI _was_ trying to screencast a feature in a CLJS app ... ;), but hey, maybe #MacOSX might actually help.
22:32kenrestivoi vaguely remember there being a way to use compojure destructuring and still get the req too
22:32kenrestivoi.e. i've got (compojure/GET "/sched/:offset" [offset :<< coerce/as-int] ...) but i want the req too
22:34justin_smithkenrestivo: it's been a while, but doesn't compojure use something close to normal destructuring? can't you put an :as in there?
22:44kenrestivoyep, that does it, thanks
22:56kenrestivojeez, i wrote a library a few years ago, completely forgot the name of it. had to look it up on github to find out.
23:36kenrestivoi wonder now if this already exists somewhere else: https://www.refheap.com/113147