#clojure log - Apr 12 2014

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

0:48 justin_smith: wrap-auth makes sense when you have a heirarchy of paths, and everything below some node should have the same auth

0:48 which is pretty common

0:48 I think function composition is the right abstraction over routes - routes are a tree, you add middleware over branches by composing functions

3:25 whodidthis: reverse routes ooh, someone needs to make that on cljscript

5:41 tomjack: amalloy: so I ended up never trying protobuf reader literals (which read to protobufs), but I did do protobuf fressian handlers

5:41 and you were so right, it's a disaster

5:42 favetelinguis: Where can i find a turtorial on how i can write Clojure code in Lighttable and then run that code connected to LT UI? This is shown in promo videos but i cant find any turtorial on how to do it?

5:43 tomjack: I wasn't actually planning to use that, but it was kind of cool -- the point was to test caching by writing, alongside each message, that messages entire FileDescriptorSet (with the deps)

5:43 message's

5:43 then I learned that if the cache gets cleared and you read a new FileDescriptorSet, you get a new equality partition

5:44 and everything is incompatible

5:44 so now I understand why they generate all of that damn .java code

5:47 I guess you'd have to manage a pool of descriptors and somehow deal with the fact that you may get the same descriptor with different schema, and you have to reverse-engineer the schema changes?

5:49 I printed out descriptor.proto's descriptor and the strange loop was amusing, but it's also disheartening to see the problems with the schema and with the data as the same problems :(

5:49 OK, I used up my quaterly protobuf rant allowance

6:13 Aaimnr: Hi there, how do you work with parens in Lighttable with default keymap? Eg. how do you jump over auto-created closing paren? Thx

6:27 ok, I got it http://stackoverflow.com/questions/22168195/i-cant-find-a-light-table-cheat-sheet

7:25 iXeno: anyone here?

7:29 I have a scala app that loads clojure files for scripting (it's an irc client, and the clojure files are user settings, and some files with bindings/config that are bundled with the client. I put it in src/main/resources, but is it more correct to have it in src/main/clojure? it's not a clojure project, and I fear it will just cause problems, but structure wise it feels better

7:50 gfredericks: iXeno: I think that's up to you; don't know any objective reason to prefer one

7:51 iXeno: yeah, it's all up to which one gives the most trouble :)

7:57 mercwithamouth: .

8:10 pdurbin: iXeno: is this thing open source?

8:16 iXeno: pdurbin: yes, but it's not worth looking at yet

8:16 and I haven't checked in any clojure code past '(+ 1 1)'

8:17 martinklepsch: iXeno what are you talking about?

8:17 iXeno: martinklepsch: I'm writing an irc client in scala, and I'm using clojure as the configuration language

8:17 martinklepsch: ah, ok

8:42 pdurbin: iXeno: if you give us a link I'll look anyway :)

8:59 iXeno: pdurbin: maybe later, when it doesn't look like http://theatrechs.org/wp-content/uploads/2013/07/Les-Mis-Construction-of-the-Barricade.jpg

9:10 pdurbin: heh

9:47 xeqi: is there a lazy map, that won't evaluate values until they are needed?

9:52 Bronsa: xeqi: map as in hash-map or clojure.core/map?

9:53 xeqi: assuming you mean hash-map, no, at least not provided by clojure

9:56 xeqi: Bronsa: as in hash-map

9:57 yeah, I see kotarak wrote one. perhaps I'll check it out

10:26 arkh_: when working with an atom that has some nested structure, e.g. (def state (atom {:foo [] :bar []})), is there a more concise way to conj onto one of the vectors other than (swap! state (fn [x] (assoc x :foo (conj (:foo x) baz)))) ?

10:27 xeqi: (swap! state update-in [:foo] conj)

10:28 (swap! state update-in [:foo] #(conj % baz))

10:29 arkh_: thanks, I figured there had to be something less verbose for that sort of repeatable thing

10:30 xeqi: hmm

10:31 &(update-in {:foo []} [:foo] conj :x)

10:31 lazybot: ⇒ {:foo [:x]}

10:32 xeqi: &(let [a (atom {:foo []})] (swap! a update-in [:foo] conj :x) @a)

10:32 lazybot: ⇒ {:foo [:x]}

10:32 arkh_: I think I just got there, too

10:32 perfect

10:32 xeqi: I forgot update-in would pass along the rest as args for a moment

12:27 benmoss: does anyone know why i’m seeing only one update every 2 seconds with this Om component? https://dl.dropboxusercontent.com/u/14411407/clock/index.html https://github.com/benmoss/om-demos/blob/master/src/om_demos/core.cljs

12:38 hm, seems like will-mount is getting called twice

12:38 Chousuke: e

12:38 whodidthis: probably something about om/build being called multiple times

12:38 benmoss: i dont know how that could be happening

12:39 whodidthis: https://github.com/swannodette/om/wiki/Documentation

12:39 benmoss: i’m getting this “A recent change to React has been found to impact your code” warning too that makes me think i’m doing something quite wrong

12:39 whodidthis: are you referring to the “It's important to understand the my-widget will be called many times.” part?

12:40 whodidthis: yeah, dont know how to fix though

12:55 aaimnr: any idea how to find first local minimum in a lazy sequence (first value smaller than both its neighbours) ?

12:57 bbloom: (doc partition)

12:57 clojurebot: "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In case there are not enough padding elements, return a partition with less than n items."

12:57 bbloom: ,(partition 3 1 (range 10))

12:57 clojurebot: ((0 1 2) (1 2 3) (2 3 4) (3 4 5) (4 5 6) ...)

12:58 bbloom: aaimnr: does that help? :-)

12:58 gfredericks: ,(->> (range 20) (shuffle) (partition 3 1) (filter (fn [[a b c]] (and (< b a) (< b c)))) (first))

12:58 clojurebot: (10 2 6)

12:59 gfredericks: ,(partition 7 4 (range 15))

12:59 clojurebot: ((0 1 2 3 4 ...) (4 5 6 7 8 ...) (8 9 10 11 12 ...))

13:00 aaimnr: on top of that the sequence would be a result of applying a function over consecutive integers and it would be great to eval the fn only once for each integer

13:01 (thanks, just thinking about your examples)

13:02 so with the partition I would be worried about evaling each element 2 or 3 times

13:03 if we would do something with (map fun (iterate inc i))

13:03 gfredericks: aaimnr: you shouldn't need to worry about that with partition

13:04 when you use map the function will only get called once for each element no matter what you do with the resulting sequence

13:04 aaimnr: nice

13:04 whodidthis: benmoss: shit im dumb

13:04 benmoss: we all make mistakes

13:04 whodidthis: if you havent figured out yet the function you got going on in om/root has to be reify instance too

13:05 benmoss: hmm

13:05 whodidthis: has to be om component

13:05 aaimnr: the fun will be provided inline

13:05 it's not unknown in the moment of the call

13:06 btw wouldn't filter..... (first) be replacable with some form of (some .. ) ?

13:06 benmoss: whodidthis: yeah good point, let me see if that fixes things

13:08 whodidthis: benmoss: https://github.com/benmoss/om-demos/pull/1 i just got massively confused by that react error message as i havent seen one before, should have realized earlier

13:18 benmoss: makes some sense

13:18 oddly i can’t switch that update! to a transact! without it stopping reflecting updates in the dom

13:34 whodidthis: benmoss: that's probably because DateTime. is an object and not a value, in transact you are mutating the object and om cant see whether its changed

13:35 update replaces the object with the mutated object

13:35 benmoss: yeah, but even when I don’t pass the key and just transact the map

13:35 whodidthis: so om re-renders

13:36 benmoss: hm i suspect thats right

13:38 whodidthis: something along those lines, things like add-watch dont work with mutable objects

13:42 benmoss: i thought the solution was to wrap the mutable object in a data structure

13:42 so like i have {:time #<20140412T133923>}

13:52 whodidthis: om only re-renders when values in the application state changes

14:02 gfredericks: I realized you can solve the flaky-tests problem with test.check by just wrapping the test code in a retry macro

14:02 s/with/when-using/

14:03 in particular there's no need to modify test.check in any way

14:10 hiredman: gfredericks: are you familiar with robert bruce?

14:10 drbobbeaty: gfredericks: happy to see you here! :)

14:11 hiredman: https://github.com/joegallo/robert-bruce (you know, for retries)

14:11 AimHere: "The definition of insanity is doing the same thing over and over again, and expecting different results"

14:12 justin_smith: AimHere: that is why good musicians are all insane

14:12 and more importantly, no good musician isn't insane

14:24 gfredericks: hiredman: yes; these are kind of specialized though

14:24 e.g., retrying on falsyness

14:24 drbobbeaty: I'm here all the time :)

14:27 bodie_: any pointers on pair programming w/ someone in windows via emacs?

14:27 I'm on linux

14:27 gfredericks: AimHere: nothing can ever be done the same way twice ;-)

14:28 bodie_: I know it's sort of unrelated to clojure, but figured someone might have an idea :) I've been using Saros in Eclipse but I don't trust the Clojure plugin

14:28 (use emacs live as my clojure ide)

14:28 gfredericks: bodie_: sidestep windows with ssh & tmux?

14:29 bodie_: that's probably the best option we have honestly but I'd love to be able to have him build and test on his machine as well

14:29 although he could just git pull or whatever, I could see it getting messy fast

14:30 plus, it would be so nice to have multiple cursor editing a la google docs / saros

14:30 I've been poking around for a good emacs bundle but nothing is springing to the front

14:30 gfredericks: I coulda sworn emacs had multiple cursors built in

14:30 via the client/server architecture

14:31 bodie_: yeah, that's what I was thinking

14:31 i s'pose I should go to #emacs, heh. just wanted to know if anyone had solved the same problem :)

14:33 I just don't want to be forced into Java .... um, has anyone used the Counterclockwise Eclipse plugin for Clojure/

14:33 ?*

14:34 (and is it awful?)

15:10 TravisD: gfredericks: Not sure if this is what you're talking about, but there is rudel mode

15:13 gfredericks: TravisD: I thought if you had two clients with one server you'd get two cursors

15:13 TravisD: ah

15:14 I don't know much about the emacs client/server stuff. (In fact, I might know nothing at all)

15:17 gfredericks: it's supposedly quite simple; somehow it always ends up plainly not working for me, but I think I recall having this two-cursor setup going with a coworker once

15:18 TravisD: I was under the impression that collaboratively editing documents required a fairly clever protocol to manage the synchronization

15:18 gfredericks: at one point it got really obnoxious because that kind of setup doesn't guarantee you're both always looking at the same thing, so to mitigate that we setup two separate tmux sessions, one "owned" by each of us, and then we'd each have two monitors, one with our own tmux session and one with the pair's so we could see what he was doing

15:18 it was fun but apparently not worth the bother of doing again

15:18 TravisD: hehe

15:19 I had a really good time working on some projects with a friend through Rudel mode

15:19 we were in the same room, so maybe not the most essential thing, but it made for much more comfortable seating

15:20 gfredericks: amalloy: I bet futures would be a good improvement for seque; I just had an error suppressed by "agent is failed, needs restart"

15:21 amalloy: gfredericks: well, feel free to use flatland/sequeue instead. that's the future version

15:22 gfredericks: righto

16:11 oskarth: Anyone with a good tutorial / real world example of core.typed? Using it for a project but having problem grokking it (not too familiar with type annotation systems).

16:12 gfredericks: oskarth: just lots of docs on the wiki

16:34 supersyy: hmm I thought it would be fun to see if there were cases of

16:34 Java & PHP interop...

16:34 TravisD: supersyy: That sounds entertaining, but maybe not much fun :P

16:35 supersyy: not really no... I feel a bit constraint now and then, being forced to work with *shrugs* PHTML soup way too much

16:36 TravisD: PHTML is HTML mixed with php?

16:36 supersyy: yeah.... there was a reason I was staying away from that mess, but after clj you've really come to appeciate functional + immutable =/

16:37 yeah, didn't know them before either, until I got to work with this Magento system which uses them

16:37 TravisD: Or as Rich Hickey would say, the value of values

16:39 supersyy: Right.

17:05 sveri: hi, I got a problem where I really dont know how to start. I am trying to parse a edn response from my server in clojurescript. I returning a map with a list which I want to map over. However, I just cannot get it done, no matter what I try. I put everything together into this paste: http://pastebin.com/6ia0szqv maybe someone can tell me what is wrong?

17:07 amalloy: ~for

17:07 clojurebot: for is complected

17:07 amalloy: ugh. for is lazy, for is not a loop. those are also in his database

17:07 gfredericks: ~for

17:07 clojurebot: for is complected

17:07 amalloy: sveri: you want doseq

17:08 sveri: amalloy: thanks, i always forget about that when trying to debug what is wrong and step into the next error :D

17:08 amalloy: thanks, I try doseq now

17:10 amalloy: should map work too?

17:11 amalloy: ~map

17:11 clojurebot: map is an evil genius.

17:11 amalloy: dangit clojurebot. map is lazy too

17:11 sveri: :D

17:11 llasram: clojurebot: clojurebot?

17:11 clojurebot: clojurebot has a poetic soul

17:15 mi6x3m: hey clojure, is there any documentation on symbols. resolution and namespace qualification and syntax for starters?

17:15 i cant seem to find any info on the official cite

17:15 site *

17:16 just some pieces spread around the web

17:18 never mind, I just found something in the docs regarding the reader

17:24 sveri: amalloy: thank you, I got it working, its so easy to forget about the lazyness

17:59 benmoss: is it just a major uphill battle to use js objects in Om app state?

18:06 trying to get this to change the seconds while the seconds are changing, but i think it would require rendering three components, one for each part of the time

18:06 https://dl.dropboxusercontent.com/u/14411407/clock/index.html

18:41 Frozenlo`: In compojure, do I need to make a middleware to change data in the current session?

18:42 Or in other words, I can't change the session's data directly from inside a GET/POST route, correct?

18:47 amalloy: Frozenlock: i mean, you return a response that has whatever date you want in the :session key. whether you do that with a middleware or not is up to you

19:03 Frozenlock: amalloy: Aren't the defroutes/GET/POST returning only with the :body part? I can get the :session data via the arguments, but returning a modifed :session?

19:04 amalloy: every ring handler takes a ring request and returns a ring response, including GET and POST

19:05 (GET "/foo" req {:status 200 :body "ok" :session (update-in (:session req) [:foo-count] inc)}) for a rough sketch

19:06 there's no special powers that middleware has - it's all just functions taking requests and returning responses

19:08 Frozenlock: Thanks. I guess what's confusing me is that I've always used functions that only returns the :body part in my routes definition.

19:08 *return

19:43 zilti: I think there's a quite ugly bug in the most recent core.typed where it fails as soon as type checks include protocols - minimal test case: https://gist.github.com/zilti/10562073 - can someone confirm?

19:44 The message I get is "No method in multimethod 'check' for dispatch value: :host-interop"

19:45 gfredericks: I think any error message on that multimethod has to be a bug

19:46 I was getting one a month ago for :meta

19:46 martinklepsch: I have a large file with multiple <xml version=".... > statements which I'd like to split into individual strings before this line so I can hand them to xml/parse

19:46 currently I use awk and save them to a single files but this creates a few thousand files which I then need to read again

19:46 zilti: gfredericks: Do they have a bugtracker somewhere? I couldn't find one

19:47 martinklepsch: any advice how I'd do that?

19:51 amalloy: fwiw, zilti, you shouldn't really be writing (.get-data x) there, but (get-data x). the former will only work on objects that implemented the protocol inline, not on those that had the protocol extended to them

19:51 zilti: martinklepsch: Well you could use a clojure.java.io/reader in a line-seq, read it line by line into a StringBuffer, and as soon as you find the next <xml version="..."> tag you put it into a vector or the like

19:52 amalloy: Hm, (get-data x) never worked for me unless I wrote a helper function that wraps it

19:52 amalloy: huh?

19:53 zilti: amalloy: Well for how I remember it I got errors that it can't find a function named like that

19:54 amalloy: you need to require the namespace defining the protocol. but i can't imagine what kind of wrapper you're talking about that would help here

19:54 zilti: amalloy: Just tried it now again: "Could not resolve var: get-data"

19:58 Bronsa: zilti: I don't know about the second error you're getting but the first one is definitely a bug in core.typed

19:58 zilti: the last versions of core.typed moved from jvm.tools.analyzer to tools.analyzer.jvm so there might be some edge cases missing

19:59 zilti: Bronsa: Without the leading period it's working now

19:59 Bronsa: Maybe I'm the only fool who ever tried that

20:00 Bronsa: zilti: I'm looking at the relevant code in core.typed now and there's definitely a defmethod missing for :host-interop, care to open a ticket on the core.typed bugtracker?

20:01 zilti: Bronsa: I couldn't find the bugtracker

20:01 martinklepsch: zilti would that also work if the xml parsing requires additional files in the same directory as the parsed file?

20:01 Bronsa: zilti: http://dev.clojure.org/jira/browse/CTYP

20:02 zilti: martinklepsch: Well, I guess xml/parse accepts Strings? I don't know it that well, never used it. But that's how I'd extract the multiple "files" out of one file

20:03 martinklepsch: zilti: https://gist.github.com/mklappstuhl/efade66bc520e4b25d93

20:03 zilti: Bronsa: Will open a ticket. Thanks.

20:04 martinklepsch: Yeah it does usually when you ByteArrayInputStream it

20:05 Bronsa: zilti: np. I don't know enough about core.typed internals to write a patch to fix it but if you open the ticket I will write a comment that I'm sure will help Ambrose fix this. Looks like it should be an easy fix.

20:10 TravisD: Is there an list of all Rich Hickey's talks around somewhere?

20:12 zilti: Bronsa: http://dev.clojure.org/jira/browse/CTYP-132

20:16 tomjack: could the edn reader in cljs provide row/col metadata without getting slow?

20:17 I haven't considered whether edn keeps any of the problems from "not so homoiconic"

20:20 seangrove: tomjack: I suppose you could use tools.analyzer?

20:20 I wonder if the edn reader has meta-data about source location

20:21 Bronsa: seangrove: if you mean tools.reader, no, source-info metadata is only added by the clojure reader

20:21 seangrove: Bronsa: Probably what I meant

20:21 tomjack: oh, hmm

20:21 I guess I need the clojure reader too

20:21 :(

20:24 if you read edn and get source location metadata back, you'd better be able to print edn with metadata, I guess

20:24 ... but then what do you get back when you read _that_?

20:24 I guess it doesn't make any sense inside of edn

20:25 actually

20:26 hmm

20:26 it's metadata, so if it doesn't roundtrip through print/read, your generative roundtrip test will still pass

20:28 I once considered putting core.async into the reader, and thought I was nuts. I still am probably nuts, but in this case, could you compose the reader process with a process which inspects the input position, into a process which applies source location metadata to the values being read?

20:28 (optionally and extensibly?)

20:31 i.e. could also give the value read and the source location info separately as a pair

20:32 zilti: Oh hell, now I get "No method in multimethod 'check' for dispatch value: :reify" ^^

20:32 tomjack: writing a minianalyzer? :)

20:42 gfredericks: it's fun being able to instruct your tests to run 1000x longer than normal

20:48 TimMc: gfredericks: Re: a much earlier conversation: "You can't step in the same computer twice."

20:55 tomjack: gfredericks: I have been wishing that I could specify a total time limit, and just give a weight to each test

20:55 it sounds like you're saying you have a similar capability?

20:55 or do you tell it to run the test 1000x as many times?

20:56 ..or 10x but that means 1000x runtime difference?

21:11 gfredericks: tomjack: I patched in a TEST_CHECK_FACTOR env variable

21:11 so e.g. I set that to 1000 and it multiplies the :times arg in my defspecs before running

21:12 I'm sure this capability belongs in test.check proper but am not sure what the best design/interface is

21:17 vic_: For the last couple of weeks I've been trying to learn Racket (racket-lang.org), but it's a huge language, easily as big as C++... yes, it's like freaking C++! And I hate C++. So I'm thinking about abandoning that Racket project, and trying another variant of Lisp... Is Clojure closer to C (I love C), or is it more like to C++?

21:18 gfredericks: I think I can say I've never heard that exact question asked before

21:18 oubiwann: vic_: in what way did Racket feel like C++? Just the size? (and size of what?)

21:19 vic_: I gotta say, I'm with gfredericks on this one ;-) Your question is quite surprising!

21:19 gfredericks: drbobbeaty: are you around for this question?

21:20 vic_: I mean number of features, "size", complexity.

21:20 martinklepsch: anyone familiar with elasticsearch/elastisch? trying to search an array field but I'm not sure how to query it...

21:21 (esd/search "development" "team" :query {:term {:members "Daniel Francis Lowery"}})

21:21 this doesn't return any results

21:22 gfredericks: vic_: I think of clojure as having a simple/elegant set of core features that you can do a surprising amount with, and a larger and messier hodgepodge of interesting/useful ancilliary features

21:22 martinklepsch: I added a mapping as described here: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-array-type.html

21:22 gfredericks: for things like complex program design, performance, interoperability...

21:25 vic_: mmm... thanks...

21:33 TimMc: vic_: Clojure is definitely more C-like along that axis.

21:42 technomancy: I've never heard racket compared to C++

21:42 it has a large standard library, but the features are mostly orthogonal

22:32 danielszmulewicz: Hi! Anyone familiar with datomic?

22:36 Are datomic transactions idempotent? May I just write repeatedly the same tx-data to the db, or do I have to check if previous data exists?

22:48 john2x: how does ->> work with functions with & rest args?

22:54 amalloy: john2x: it's a macro, so it doesn't really care about what the function's args look like. do you have a more specific question?

22:56 john2x: amalloy: i mean, does the result of the last fn get passed as the last item (or only item if none are provided) of the rest arg, provided all other args are supplied?

22:57 amalloy: john2x: i mean, i think the answer to that is yes, but you're thinking about it wrong: (->> x (f a b) (g 1 2)) expands to (g 1 2 (f a b x)), regardless of whether f or g take &rest args

22:58 ->> doesn't actually pass anything as an argument, it just manipulates the source-code tree; what happens to function arguments is a separate step

22:58 john2x: amalloy: got it. thanks.

23:01 hmm what's the recommended way of writing CRUD functions? just a thin wrapper function that expects the appropriate table values? or is there a better way?

23:03 i'm writing thin wrappers for now, but I'd need to write a lot of wrapper functions for each CRUD operation for each table.. then there are the inter-table CRUD operations..

Logging service provided by n01se.net