#clojure log - Dec 25 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:05 TimMc: TEttinger: Rodents have pretty mean bites, yeah.

0:06 oooh, and merry Christmas

0:06 I should go to bed.

0:06 justin_smith: I once got jumped by a squirrel

0:06 it lived in a warehouse were I worked, and was semi-tame

0:06 TEttinger: merry ratmas

0:06 sohail: thanks justin_smith, sente looks pretty good

0:06 justin_smith: sohail: it's been pretty easy to use

0:06 as long as you are OK with some core.async to hitch it all up, it works very nicely

0:11 TimMc: justin_smith: Raynes said he doesn't plan on deleting the site, or at least not the data. Phew. But it is going read-only.

0:12 justin_smith: ahh, I must have misread or misremembered

0:13 TimMc: I'm still backing up those pastes. :-P

0:24 justin_smith: TimMc: that's good - it would be cool to have it searchable by function too

0:25 TimMc: Search wouldn't cover the private pastes.

0:28 Grabbed 5303 unique pastes. ^_^

0:30 justin_smith: TimMc: sure, but you can't back up private pastes can you?

0:49 TEttinger: 5303 pastes eh? I'm compressing a large amount of PNG files again. it seems to be done with 736K files so far

0:49 2.3 GB processed

0:49 not even a third of the way done

1:02 kenrestivo: bikeshed time: this double assoc bothers me https://www.refheap.com/113128

1:03 double assoc-in anyway

1:03 justin_smith: kenrestivo: #(if % (inc %) 1) is (fnil inc 0)

1:03 kenrestivo: fnil, thanks!

1:03 justin_smith: ,((fnil inc 0) 1)

1:03 clojurebot: 2

1:04 kenrestivo: yeah, i remember it, i'd forgotten

1:04 justin_smith: ,((fnil inc 0) nil)

1:04 clojurebot: 1

1:06 kenrestivo: the double update-in still bothers me tho

1:06 justin_smith: kenrestivo: maybe something like (update k (comp #(merge % m) update) :count (fnil inc 0))

1:07 that's weird though

1:07 kenrestivo: it is awkward

1:07 but concise

1:07 meh, i guess my double thing is at least easier to read and reason about

1:07 justin_smith: and it nests the ops so the k doesn't get replaced twice

1:08 but yeah

1:08 kenrestivo: there's no rule that says you can't write a proper function for update

1:09 kenrestivo: true, then i could also eliminate the useless merge: in cases where count> 1, the m is the same

1:09 but my bikeshed limit is reached on this :)

1:10 i'm avoiding reading a bunch of javascript docs on react

1:10 justin_smith: hah

1:10 kenrestivo: it'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

1:11 justin_smith: where the clojure project made you need to dive into another language?

1:11 kenrestivo: every single one that deals with the real world :p

1:12 because the real world is made of java and javascript and css and c and such.

1:12 to answer your question, i've been messing around with reagent, which is pretty nice.

1:13 i've come up against a block with how props and such work, so i have to read react docs

1:13 TEttinger: kenrestivo: you need a lisp machine

1:13 kenrestivo: heheh, yeah, the computer museum here has a symbolics

1:14 TEttinger: there's a dude working on one that runs on a beaglebone black (small raspi-like ARM computer)

1:14 kenrestivo: cool. link?

1:14 TEttinger: no idea how far he is on it

1:14 kenrestivo: i have a beaglebone black sitting here

1:14 TEttinger: oh sweet

1:14 kenrestivo: they're great little embedded boards

1:16 justin_smith: I've got a beagle bone black around here somewhere

1:29 TEttinger: I have uh... a tronsmart MK908

1:30 ben_vulpes: kenrestivo: how did you come to be using props with reagent?

1:31 kenrestivo: i want to use :component-did-update, and that requires dealing with props

1:31 ben_vulpes: ah.

1:31 what's the story in the code side driving use of :component-did-update?

1:31 not 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

1:51 kenrestivo: there are a few abstractions: props, lifecycle functions, atoms, and cursors.

1:52 i 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.

1:58 :component-did-update seems to require props

1:59 i'll play around with it tomorrow. it's probably straightforward, i just haven't seen it explained yet.

2:40 ben_vulpes: i have no idea about cursors man

2:40 atoms are enough for me at the moment

2:49 tolstoy: component 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.

2:49 I do think it's an "opportunity" to re-think stuff.

2:50 ben_vulpes: tolstoy: so diddling props directly will also trigger a re-render?

2:51 tolstoy: Oh, I think I might have used it to update "component local state" based on changes.

2:51 ben_vulpes: I don't think so.

2:51 They're immutable.

2:51 ben_vulpes: kk

2:51 i'm avoiding component local state like the plague

2:51 tolstoy: But you can get the old and the new and compare the two.

2:51 ben_vulpes: how do you use that and still get interactive development?

2:52 tolstoy: Local state or component-did-update?

2:53 When I used local-state (om.prev) it was for forms, mostly. I didn't care if things got cleared out with Figwheel, or whatever.

2:57 ben_vulpes: local state

2:57 ah

2:57 yeah that drives me a bit batty

2:58 tolstoy: This 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.

2:59 I never have more than one form at a time, so ... it feels like a register in assembly programming.

3:00 Feels kinda like a dynamic-var, but in a single-threaded, single-user app, it turns out to be far less spaghetti than anything else.

4:07 geirby: hey there. what is the best leiningen cljs template to start with? With figwheel and stuff?

4:08 ridcully_: the figwheel one

4:37 geirby: ridcully_ oh, ok, makes sense :) thanks

8:27 TimMc: justin_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.

8:31 justin_smith: Maybe I misunderstand private pastes, though.

9:36 j-pb: how would you deal with a cyclic deftype dependency? declare doesn't seem to work

9:37 I 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:39 justin_smith: j-pb: hint the protocol it implements, not the type

10:41 j-pb: justin_smith: you can't type hint protocols afaik

10:41 or you mean put the type into the protocol?

10:50 sohail: justin_smith: what's the difference between the websocket impl for sente and http-kit?

10:51 ah it's server-side only, I think.

10:54 justin_smith: sohail: sente uses http-kit's websockets

10:54 it's an abstraction

10:55 sohail: it's so straightforward

11:07 justin_smith: j-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:07 j-pb: justin_smith: yeah, that's a good point :)

11:07 justin_smith: j-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:08 j-pb: I don't really get sente

11:08 's api though

11:08 I'd either go with callback only or channel only, but it has this weird mix

11:08 justin_smith: j-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:09 j-pb: you only need to use one - I never use the callbacks myself

11:09 (though I have code I could simplify if I used the callback feature...)

11:10 j-pb: justin_smith: sending is done though a funciton though

11:11 justin_smith: yes

11:11 j-pb: this could also be a channel

11:11 justin_smith: nothing stops you from implementing that channel

11:12 but 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:12 it's already async

11:44 sohail: Is there some reason why this lein configuration does not seem to use my handler? http://pastebin.com/VuskVAZz

11:45 weird 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:45 justin_smith: sohail: why are you asking figwheel to run your handler?

11:46 sohail: justin_smith: I want to be able to debug the client and server in concert

11:46 so I just want one server running

11:46 justin_smith: OK, that might work, but I've never done it that way

11:47 I wouldn't be surprised if it worked perfectly; I also wouldn't be surprised if it didn't work at all

11:47 sohail: well... it's clearly NOT working :) how do you do it?

11:47 justin_smith: sohail: I start up a normal server, and let figwheel do its own thing

11:47 I don't need to debug the figwheel server

11:47 it's already a finished product

11:47 sohail: what about the cljs repl?

11:47 justin_smith: figwheel

11:48 sohail: what does your project.clj look like?

11:48 justin_smith: sohail: can't share it, sorry.

11:48 I 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:48 sohail: do you use emacs?

11:49 justin_smith: yes, but no repls inside emacs

11:49 sohail: ah that's probably it then

11:50 so you do lein figwheel in one window and lein ring server-headless (or whatever) in another

11:50 ?

11:50 noncom: sohail: i do just that

11:50 justin_smith: sohail: yes

11:50 noncom: never had to type anything into the figwheel repl really

11:50 justin_smith: sohail: in my case I run lein repl, and start the server inside the repl

11:50 sohail: but that sweet repl and code completion

11:51 noncom: i guess first you have to justify using figwheel repl?

11:51 an interesting topic for me, since i never found a use in it

11:51 so i'd like to know

11:51 if you do

11:51 sohail: the code completion works inside emacs

11:51 noncom: ah i see

11:51 i don't use it then

11:52 turneds out it was not essential

11:52 but of course, it's nice to have i guess..

11:52 justin_smith: sohail: 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:52 sohail: I've never actually used code completion before, but having eldoc work is helpful.

11:53 justin_smith: I was just reading the docs. I'm probably doing something wrong

12:01 justin_smith: FYI the "chestnut" runs both the web server and figwheel in the same repl

12:01 the chestnut template, just tested it and it worked. Now to understand it.

12:30 ah I see they use profiles to execute stuff in the repl to do the work. Works for me.

12:31 pigoz: hello 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:33 justin_smith: pigoz: looks OK, though using update is sneaky :)

12:34 pigoz: you think it makes the exercise too easy?

12:38 justin_smith: pigoz: no, it's just funny because historically update-in was implemented first, and only later we got update

12:38 pigoz: of course using assoc instead of update would be simple

12:50 ,(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:50 clojurebot: 364

14:10 troydm: I have some deftype, is it possible for it to implement CharSequence Java interface?

14:11 justin_smith: ,(deftype Dum [] CharSequence (charAt [_ _] \d))

14:11 clojurebot: sandbox.Dum

14:11 justin_smith: ,(.charAt (Dum.) 88)

14:11 clojurebot: \d

14:12 justin_smith: troydm: I guess if I was feeling less lazy I could have implemented the other three methods on the interface too

14:12 troydm: justin_smith: ic, that's what I was asking

14:12 justin_smith: thx

14:17 justin_smith: say I have (deftype A [a b c]) how do I access fields of that deftype outside of deftype method declaration?

14:18 justin_smith: ,(deftype T [a])

14:18 clojurebot: sandbox.T

14:18 justin_smith: ,(.a (T. 0))

14:18 clojurebot: 0

14:19 troydm: oh, with a dot just like java methods

14:19 justin_smith: ic, thx

14:19 justin_smith: troydm: in fact, it is a method

14:22 sohail: does 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:24 troydm: justin_smith: can you explain what is (charAt [_ _] \d) <- the [_ _] part? it has two arguments

14:24 justin_smith: every method takes the object as the first argument

14:24 j-pb: troydm: there is no implicit this as in java

14:25 troydm: justin_smith: ohh

14:25 justin_smith: ic, ic

14:32 amalloy: except in proxy, har har

14:34 troydm: strange I'm trying to access field of deftype using .fieldName and it says no matching field found

14:35 justin_smith: troydm: 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:35 troydm: justin_smith: yeah, also field is volatile

14:36 ^:volatile-mutable

14:36 also that deftype extends a Protocol

14:38 justin_smith: troydm: it's not mentioned in the docs but it makes sense - no accessor is generated if the field is not immutable

14:38 you are free to make an interface or protocol with a getA method

14:41 troydm: justin_smith: ah, ic, thx

14:43 justin_smith: troydm: 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:43 which feels like a heavy thing to be doing

14:44 troydm: justin_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:45 justin_smith: troydm: 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:45 troydm: the difference is that an unsynchronized-mutable can change without guaranteeing that the change is immediately visible in all threads

14:46 so 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:46 troydm: justin_smith: well the thing I'm building won't be used in multiple threads simultaneously

14:47 justin_smith: then 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:48 troydm: 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:50 troydm: justin_smith: I've read it, and I know, thx for a hint

14:51 also when you write #"abc" does Clojure compile the regexp pattern or you need to explicitly compile it?

14:51 justin_smith: #"abc" returns a compiled regex

14:52 there is also re-compile if you want to do it by hand, or from a string generated at runtime

14:53 troydm: justin_smith: thx, ic

15:02 rhg135: re-pattern it's called

15:19 Bronsa: justin_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:19 with mutable fields those fields are private, that's why you can't access them

15:30 justin_smith: Bronsa: 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:31 Bronsa: but the private thing clarifies that, thanks

16:29 zacts: is Clojure from the Ground Up still good?

16:29 or what are the recommended resources for a complete Clojure newbie?

16:29 my main initial goal is to do Overtone music synth with Clojure

16:29 MJB47: i quite liked "the joy of clojure"

16:29 zacts: cool

16:29 MJB47: is this good for a complete newbie?

16:30 MJB47: yup, it assumed you know nothing about lisp

16:30 zacts: oh nice

16:30 perhaps I'll start there

16:30 pigoz: zacts: I am going through http://www.braveclojure.com/ but have used used lisp/clojure a bit before

16:31 zacts: pigoz: and you like it

16:31 pigoz: yes, the writing style is very fun and informal

16:31 good for my attention span :)

16:32 zacts: ok

16:32 cool

16:32 thanks!

16:34 perhaps 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:34 justin_smith: 4clojure.com is good for exercises

16:34 zacts: oh cool

16:38 pigoz: justin_smith: oh looks a like a great resource, thanks!

16:39 Seylerius: This 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:41 justin_smith: oops!

16:41 should be an easy pr, right?

16:45 Seylerius: Yep. Just need to figure out what they're using for docs and what broke it.

17:20 sohail: Do you have to do anything special to compile cljc besides add it to :source-paths?

17:20 justin_smith: no

17:20 the clojure and cljs compilers use it like they would any other file

17:21 sohail: I thought so, thanks.

17:26 TEttinger: cfleming: thanks for making open source development with cursive still possible on a nonexistent budget!

17:26 this is the best rosh hashanah ever

17:48 Seylerius: justin_smith: Turned out to be a failure of font failover.

17:56 justin_smith: Seylerius: so it just gives you nothing, instead of a default font?

19:38 BRODUS: say i wanted to model digital logic using core async, would a 'mult' be the right thing to use for a clock signal

19:38 stain: BRODUS: hmmm...

19:39 but you would need to make sure the clocks synced up in the other end?

19:39 send (tick,signal) in the channel?

19:40 otherwise the complexity of your modelling function would falsely add delays

19:43 but 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:45 sorry, this is late.. the blocking from the synchronous nature of mult might be enough for your purposes

19:45 as you wouldn't be able to do the next tick before it's all gone through

19:45 BRODUS: its ok, thats what i was thinking

19:46 stain: I'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:46 e.g. an exception

19:47 so 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:47 BRODUS: well i dont think it would work if you had a clocked gate that depended on other clocked gates

19:48 stain: right, it could deadlock very easily, you can only do it with a single system clock (real time clock)

19:48 and then base any frequency generators etc. of that one

19:49 BRODUS: i dont follow what you mean with the dot product

19:49 stain: oh.. if you pass (n,signal) then you need to match on n (e.g. the simulated system time tick)

19:50 so you don't accidentally get offset

19:50 or you would have to set your exception handler to kill the system clock

19:50 have you used Keppler? It has a good tick simulation thingie

19:52 BRODUS: i will check it out

19:53 stain: https://kepler-project.org/

19:53 it's a bit old and awkward

19:53 but hey.. they did a Christmas release!

19:55 BRODUS: cool

20:22 tolstoy: Oy. Make a little screencast using QuickTime, can't edit and export it with ANYTHING that keeps the same fidelity.

20:33 1080p export -> blurry. ProRes -> 5 gigs.

20:34 ridcully_: are you sure, this is the right channel for this?

20:35 tolstoy: Of course it's not.

20:38 I _was_ trying to screencast a feature in a CLJS app ... ;), but hey, maybe #MacOSX might actually help.

22:32 kenrestivo: i vaguely remember there being a way to use compojure destructuring and still get the req too

22:32 i.e. i've got (compojure/GET "/sched/:offset" [offset :<< coerce/as-int] ...) but i want the req too

22:34 justin_smith: kenrestivo: it's been a while, but doesn't compojure use something close to normal destructuring? can't you put an :as in there?

22:44 kenrestivo: yep, that does it, thanks

22:56 jeez, 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:36 i wonder now if this already exists somewhere else: https://www.refheap.com/113147

Logging service provided by n01se.net