#clojure log - Aug 15 2013

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

1:17 ed_g: is it possible to pass a dynamic variable into an agent's context?

1:17 technomancy: ed_g: you can send it a bound-fn

1:20 ed_g: does that mean send-off a lambda which has a copy of the dynamic variable?

1:20 ztellman: ed_g: I'm pretty sure that's the default behavior

1:24 technomancy: oh yeah; I'm thinking of the 1.2 behaviour

1:24 callen: other than Incanter, what's a respectable analogue to NumPy for clojure? Ideally equally as performant or better.

1:25 I'm aware of ztellman's mad scientist oeurve although I can't be sure if any of it is applicable.

1:25 ztellman: core.matrix seems promising

1:25 not sure how completely realized it is

1:25 callen: ztellman: thanks :)

3:34 H4ns: how do i synchronously access the body of a request in a POST handler in http-kit? the documentation says it conforms to the ring spec, but i'm lost in the documentation.

3:37 seems that i need to have a json middleware like ring-json

4:55 is there a function that gives me a count of elements in a seq that satisfy some predicate (i.e. count-if)?

4:56 Raynes: (count (filter ...))

4:56 TEttinger: ,(count (filter pos? ["darn you" "Raynes" 11 -1]))

4:56 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>

4:57 Raynes: H4ns: This won't make two passes because filter returns a lazy seq.

4:58 H4ns: Raynes: ah, nice. thanks!

5:27 what's an idiomatic way to call a function for number of elements from a seq and return the results? (the-fn + [1 2 3 4]) => (3 7)

5:27 supersym: reduce

5:28 H4ns: thanks

5:29 erm, well, reduce always takes one element. i'll probably have to use group

5:31 supersym: ,(map #(reduce + %) (partition 2 [1 2 3 4 5]))

5:31 clojurebot: (3 7)

5:31 H4ns: ah, partition! thanks!

5:31 supersym: :)

5:36 TEttinger: H4ns, reduce is fantastically flexible. you can see some things on clojuredocs that use reduce with a function that takes a vector and an item from the collection you pass it... really potent stuff

5:37 err, it was somewhere else, but http://clojuredocs.org/clojure_core/clojure.core/reduce

5:42 ah, it may have been here http://www.learningclojure.com/2010/08/reduce-not-scary.html

5:52 supersym: TEttinger: yeah... I seemed to keep getting confused by it first

5:53 this is my first lisp :P

5:53 TEttinger: me too

5:53 and it's the way I think now

5:53 maybe always has been

5:53 supersym: yeah once you get it you get it :P

5:53 TEttinger: I remember programming in lua with tons of functions getting passed around, before I knew clojure

5:54 lisp is just... cleaner

5:54 supersym: god... I used to have awesome as my wm before xmonad

5:54 TEttinger: lua's great though

5:54 supersym: I remember it exceptionally well for killing my desktop on the slightest typo

5:54 yeah

5:55 I know.... really powerful embedded scripting/extensions using tables

5:56 TEttinger: luajit is a masterpiece of compiler tech and easy to use. there was a project called Vortex to add lisp and F# features to lua and have it compile to LuaJIT dialect lua

5:56 supersym: oh ok :)

5:57 I never really tried F#, once I reached that stage in my visual studio adventures, I decided to dump windows for linux

5:57 TEttinger: I haven't seen much difference in my productivity on windows or linux

5:57 http://quaker66.github.io/vortex/

5:58 but a significant amount of my work is with windows-only multimedia stuff

5:59 supersym: well productivity, maybe, I was pretty damn at home in VS2010 and that was a really nice (12.000 dollar) tool

5:59 but I was tired of all the bloat, the background automated enabling of services, the malware

6:01 tbh tho: stuff like git etc isn't the same in windows

6:01 and powershell really sucks once you mastered zsh :)

6:06 arcatan: ugh. i'm not slacking off, i'm waiting for git to checkout my branch on windows.

6:58 H4ns: is there a way to limit the amount of data that nrepl prints? i'm dealing with large structures which take too long to print in emacs.

7:00 hugod: H4ns: *print-length* might help

7:01 H4ns: hugod: thanks, that was precisely what i wanted to have :)

7:06 erm, only that it does not work :(

8:00 is defstruct gone from clojure? i have stuart halloway's book from 2009 which mentions it, but i can't see it on the cheat sheet.

8:04 jkkramer: H4ns: it's deprecated in favor of defrecord

8:08 H4ns: jkkramer: and i should not be scared by the "alpha" label that it has?

8:09 shafire: Hi

8:09 Can I prove clojure programs?

8:10 jkkramer: H4ns: no need to be scared. it's not going anywhere

8:14 Anderkent[away]: H4ns: it's not going anywhere but it might not work perfectly with dynamic development (lots of code reloading in a repl tends to mess with compiled types like records/protocols)

8:14 H4ns: okay, i guess i'll just stick with maps and be done with it.

8:14 jkkramer: it's often a good idea to put your records and protocols in their own ns to avoid such issues

8:15 yeah, maps are good unless you have a specific need for records

8:30 hugod: H4ns: looks like nrepl isn't printing the result within the session bindings - possibly a bug in nrepl

8:41 H4ns: (set! *print-length* 10) should work

8:42 there is also *print-level*, which depending on your data structure, could help

8:42 ro_st: hugod: are you aware of any way to stop the pprinter from including commas in its output?

8:42 so annoying when using CuCxCe in emacs and getting commas back

8:42 hugod: ro_st: not that I am aware of

8:42 ro_st: also, an aside: thanks for crtierium! awesome lib

8:43 criterium, too -grin-

8:43 hugod: glad you find it useful

8:43 H4ns: hugod: that seems to work, thanks! i don't quite know what stopped it from working when i tried before.

8:45 hugod: H4ns: it seems a bit subtle - using `binding` of course doesn't work to set it, as the printing is done outside of the scope of the `binding` form, and alter-var-root doesn't work, as it has a thread-local value, which is what set! modifies

8:47 H4ns: hugod: is there a good place to put such initialization so that it modifies the right values for the nrepl repl, for all projects?

8:49 Anderkent: i think if you have a file "user.clj" on your classpath it will be executed whenever your repl starts

8:49 but if you only want it for repls started by your editor I think the editor must do the work

8:50 H4ns: Anderkent: i see, thanks.

8:50 hugod: H4ns: There is also the :init option you should be able to set in your leiningen user profile https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L148

8:50 `cbp: H4ns: you can set :global-vars on your project.clj

8:51 hugod: `cbp: not sure that will work with thread locally bound vars, but worth a try

8:53 tcrayford: is there a decent clojure testing library with completely parallel testing?

8:53 I realized recently that literally none of my tests touch any shared globabl resources anymore, so I'd like to run everything in parallel for performance

8:53 * schmir wants py.test for clojure

8:54 tcrayford: (alternatively if there's a clojure.test plugin that does parallel testing, that'd be fine too)

9:10 hugod: `cbp, H4ns: :global-vars seems to do the job nicely

9:12 H4ns: hugod/`cbp: thanks, done :)

9:15 hugod: ro_st: you could define your own print-method for IPersistentMap that called a modified print-map

9:38 bdesham: I'm trying to generate a matrix where the i,j element is the result of (f i j). Is there a more idiomatic way than <https://gist.github.com/bdesham/6240709>?

9:39 ro_st: ,(map + [1 2 3] [4 5 6])

9:39 clojurebot: (5 7 9)

9:41 chouser: bdesham: that's pretty common. See also clojure.math.combinatorics/cartesian-product

9:42 bdesham: chouser: ok, thanks

9:48 ro_st: to call a js method in the global scope from cljs would be (.it js/window) right?

9:49 ne'ermind.

9:56 gvickers: I am working on a project that requires the ability to dynamically load jars and execute them in their own thread. Conceptually, I am having a hard time figuring out the best way to load the namespace and call the functions. Anyone work on something similiar?

9:57 chouser: gvickers: dynamically loading jars is rather a pain. Generally it means manipulating the Java classpath. You might look at pomegranate

10:02 mdrogalis: gvickers & chouser: I can second that it's quite a headache.

10:04 pandeiro: anybody know if lein is broken for glibc 2.18?

10:04 http://sprunge.us/SCOa

10:04 shafire: Can I prove clojure programs on correctness? (mh, how to say that)

10:04 ro_st: like you would with Haskell?

10:05 i don't think so, because Clojure isn't a pure language

10:17 pandeiro: k my problem is not lein-specific; having to rebuild openjdk due to a gcc/glibc upgrade

10:18 nDuff: shafire: ...only if you're willing to make a bunch of assumptions. You can certainly have a subset of the program that uses only pure functions, and use formal reasoning around that.

10:19 H4ns: how can i create a map from a & rest parameter? i want to merge any extra keyword arguments supplied to a function with another map.

10:19 (into map rest) gives me IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom

10:19 mdrogalis: H4ns: Can I see an example of input/output that you want?

10:20 fredyr: ,(merge {:a 1 :b 2 :c 3} {:b 9 :d 4})

10:20 clojurebot: {:d 4, :a 1, :c 3, :b 9}

10:20 H4ns: ,(let [[& rest] [:a 1 :b 2]] (into {} rest))

10:20 chouser: H4ns: (into map (apply array-map rest))

10:20 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword>

10:20 fredyr: H4ns: merge might do the trick?

10:20 shafire: nDuff: ro_st: thanks

10:21 H4ns: chouser: thanks!

10:21 mdrogalis: ,(apply hash-map [:a 1 :b 2])

10:21 clojurebot: {:a 1, :b 2}

10:21 mdrogalis: That sort of thing?

10:22 H4ns: right

10:22 chouser: the problem was that into turns its second arg (rest) into a seq and calls conj on each

10:22 So you were getting (conj map some-key) and then (conj map some-val), etc.

10:23 but conj on a map requires a key-value pair, that is a mapentry or 2-element vector

10:23 hence the error

10:23 H4ns: ok. probably requires some more practice to deduce that from the message :)

10:25 chouser: Well, the error message told you it wanted a seqable (ISeq) but you were giving it a keyword

10:26 H4ns: i'm not saying that the message is bad, i'm just too inexperienced to draw the right conclusions from it.

10:27 Foxboron: H4ns: the biggest challange IMO is the clojure errors. Once you get over that, it's is not that bad

10:27 H4ns: Foxboron: coming from common lisp, i find the stack traces a bit lacking :)

10:28 Foxboron: H4ns: go blame java :3

10:28 H4ns: Foxboron: but there is a lot good in exchange, so i'm not complaining.

10:32 chouser: if you looked at the trace you'd see it was conj complaining about that.

10:32 So yes, I agree the errors could be a lot better. Also, the errors are currently quite useful if you learn how to use them.

10:34 Foxboron: chouser: yeah, as i said. It is a little learning curve. Not quite there myself

10:37 mdrogalis: Eeek. Why are conferences so expensive?

10:38 Not even programming-related. Just in general, for any field.

10:38 ro_st: ask puredanger. he should know :-)

10:38 Ember-: because those conferences need to cover their expenses?

10:39 mdrogalis: It's naive, but I'll ask it anyway. Aside from venue, what are their expenses?

10:40 tbaldrid_: mdrogalis: and remember, these are fairly small conferences ~350 people, I'd imagine they'd get cheaper if the numbers got higher

10:40 nDuff: mdrogalis: venue is the really, really big one -- but there's also speakers.

10:40 chouser: mdrogalis: I think the venue and food (even snacks) are more expensive than you might think. Then they also cover travel and lodging for the speakers, who are otherwise donating their time to produce the talks.

10:40 ro_st: catering. some confs pay a stipend to speakers. not sure what goes into getting discounted hotels either

10:40 nDuff: mdrogalis: ...venues are more expensive than you'd think, though. They charge through the nose for things like box lunches, coffee, &c.

10:41 mdrogalis: Heh, I had no idea.

10:41 Yeah, I just noticed it's consistently really expensive across a few different engineering and academic fields.

10:41 chouser: The conj and strange loop don't pay the speakers beyond travel and lodging. (except maybe the keynote speakers? not sure about them)

10:46 Mudge: hello

10:53 NiKo`: hi people

10:53 trying to use leiningen on osx but it's painfully slow

10:53 google doesn't bring much help about this :/

10:54 I'm using stock jvm provided by osx and a fresh installation of lein through brew

10:54 hints?

10:55 (slow == lein help 46,84s user 1,73s system 262% cpu 18,517 total)

10:57 timvisher: so repl development may have finally hit me last night as far as why anyone would do it. it's the same reason one might use a shell over `M-!` and it's ilk in that you have automatic records of the development of your function as it grows and if you make a mistake you just go back a definition and start again without having to muck about with undo/redo.

10:57 now i don't think it would be too hard to have every form i send to the repl via `C-x C-e` or it's ilk be also displayed in the repl. i feel like someone was already doing work along these lines though. is that the case?

10:58 Rubix: is there a dead-simple way to ramrod a pojo into a clojure map such that each key is a string representation of the declared data member ?

10:59 timvisher: Rubi: I think you're thinking of http://clojuredocs.org/clojure_core/clojure.core/bean

10:59 ?

10:59 Rubix: ^^

10:59 with a bit of help if you really want the string keys

11:00 Rubix: timvisher: that would be exactly what I want

11:00 oh, snap, is that my n00b showing?

11:00 timvisher: also note https://github.com/clojure/java.data


11:01 `cbp`: I had to google pojo

11:01 Rubix: cbp: it sounds dirty to me

11:01 `cbp: it sounds like chicken in spanish

11:02 timvisher: `cbp`: i take you're not from a jvm background? or has it just been that blissfully long since you've been paid to write Java? :)

11:02 Rubix: "spanish chicken" could be dirty too

11:04 `cbp: timvisher: java was actually my first language but i've never been paid for writing it. I'm mostly a php guy :(. I do get paid to write clojure though in a way.

11:04 timvisher: `cbp: that's awesome. i had that for about 11 months. it twas a blissful time. :)

11:05 not the php part. i'm enough a snob i suppose to turn my nose up that

11:05 although i have been paid to write it. lol

11:06 jtoy: hi chunfeng

11:06 chunfeng: hi

11:14 mdrogalis: jtoy: Everytime I see you on IRC, I think "Man I should read that neuroscience book he recommended" Someday it will happen.

11:16 jtoy: mdrogalis: which one?, i've read and recommend a bunch :)

11:16 mdrogalis: jtoy: I'll look it up in my favorited tweets when the time is right. Can't even remember, ha.

11:17 pandeiro: do i need to install elasticsearch manually to use the http api with elastisch? anybody know?

11:19 schmir: pandeiro: I'm also using elastisch with elasticsearch. but I don't quite understand your question.

11:20 pandeiro: schmir: i am just running thru the getting started guide but it's not clear if elastisch installs elasticsearch or not

11:20 GeneralMaximus: how does one get rid of those autocomplete frames that Emacs pops up at the bottom of the screen?

11:20 schmir: pandeiro: elastisch does not install elasticsearch

11:20 pandeiro: and when i try to run the initial examples, i get a Connection refused, so i assume the server is not running

11:22 schmir: pandeiro: right. you need to start an elasticsearch instance. but that's quite easy

11:24 pandeiro: schmir: yeah almost got it

11:30 huh, doesn't seem to be running

11:31 sharms: I have a failing test which I would like to take a look at in a repl

11:31 do I just do 'lein repl' then paste it all in, or is there a shortcut to have it load the same code it would load during 'lein test'

11:34 supersym: http://richhickey.github.io/clojure/clojure.test-api.html#clojure.test/run-tests

11:34 @sharms

11:35 bbloom: hmm what's that clojurebot prompt?

11:35 ~github

11:35 clojurebot: http://github.com/richhickey/clojure/tree/master

11:35 bbloom: ~richhickey

11:35 clojurebot: Titim gan éirí ort.

11:36 bbloom: ~github

11:36 clojurebot: github is http://github.com/clojure/clojure

11:36 bbloom: clearly that one

11:36 supersym: bbloom: I wanted to say a thank-you for backtick...having a blast learning all about quoting :)

11:37 bbloom: supersym: you're welcome! glad you like it

11:40 `cbp: GeneralMaximus: I think it doesnt do that if there's _something_ after what you're autocompleting. Like a newline

11:41 ambrosebs: type checking DOM manipulations with core.typed https://github.com/clojure/core.typed/blob/master/src/test/cljs/cljs/core/typed/test/dom.cljs

11:42 GeneralMaximus: `cbp: it is usually very intelligent. e.g, if i type "reduc" and hit tab, it pops up a frame with everything starting with those letters. if i go back and delete those letters, it hides the frame. but i have been stuck with that frame on several occasions.

11:42 `cbp: in that case, i have to switch focus to that frame, delete it, and come back to the frame i was in

11:43 (or is it called a window? sorry, my memory of Emacs terminology is sketchy.)

11:45 `cbp: GeneralMaximus: sorry i misunderstood your question. My autocomplete shows the completions automatically but sometimes it inserts like 20 newlines at the end of the file (or nrepl buffer) but doesnt seem to do that when theres something after what it's autocompleting. You can hide the completions with C-g

11:46 GeneralMaximus: `cbp: when i do C-g, it just beeps and says "Quit" in the minibuffer. doesn't actually close the window.

11:46 `cbp: putting a space after what it's completing does get rid of the window, thought.

11:46 *though

11:47 `cbp: GeneralMaximus: you can try looking at other people's autocomplete configuration. Emacs live has a good default for one

11:48 GeneralMaximus: `cbp: i will do that. thanks.

11:53 supersym: huh... what is this tho, found a macro with final argument [s s′] but the quote isn't a backtick or normal quote

11:54 as in: (list 'defmacro s′ (str s) ... but here in irc it shows as a regular quote, hmmm. Anyone know what it does, the suffix quoting?

11:56 mtp: it shows up as a unicode PRIME

11:56 for me

11:56 codepoint #x2032

11:56 supersym: thnx

11:57 `cbp: ´

11:57 :-O

11:57 learner__: hi, in Clojure when on REPL, how can I see all global variables and their values (like *warn-on-reflection*) ? thanks for your time

11:57 supersym: yeah I don't think my keyboard has it

11:59 ah, the same sign as in minutes, seconds etc... right now I remember thats a different one

12:01 `cbp: learner__: I guess you could use something like (clojure.repl/apropos #"\*.*\*")

12:02 learner__: If you meant dynamic vars because otherwise every var is global.

12:03 learner__: `cbp: Thanks. I want to know the every single global variable and it's value

12:04 seangrove: Is storing code in database normal? I remember someone doing something like that in php with eval, and thinking it seemed an abomination, but maybe I'm just not open-minded enough.

12:04 supersym: seangrove: I don't find it normal

12:05 though I see floating around sometimes, I've never found it a particularly attractive idea

12:05 anyway, clojure code=data, often you find yourself not needed a database at all

12:06 dnolen: bhauman: btw, that partition thing from yesterday looked good :)

12:07 bhauman: I don't know if you saw but I said I'd be very surprised if making tons of channels and wiring them together was a performance problem.

12:08 bhauman: dnolen: the partition thing is working great cleans so many things up.

12:08 dnolen: bhauman: awesome

12:09 bhauman: dnolen: many channels may-not= bad performance. got it.

12:09 `cbp: postgresql has stored procedures which can run faster than client code

12:10 never really used them though :)

12:11 supersym: if you must use sql, stored procedures are wtg

12:12 `cbp: I guess i should be using them then :-)

12:12 supersym: or at least in mssql/.net they were rock solid but takes a lot of time to set up and very rigid

12:15 dnolen: bhauman: I also think in bigger designs it will be normal for channels and go processes to come and go, I'm doing this in my next post and it's pretty amazing IMO.

12:16 bhauman: dnolen: you are demonstration the creation and collection of lots of channels?

12:16 supersym: hmm github die for anyone else?

12:16 bhauman: supersym: yep

12:16 supersym: aight

12:17 dnolen: bhauman: I'm doing it one place, hopefully easy to see how it can be applied at a larger scale.

12:18 bhauman: but yes in principle you can create a process that represents some component that fires up a bunch of channels to do it's work and removes the event sources when it's done and exits, allowing all other processes to get GCed.

12:18 bhauman: dnolen: gotcha

12:18 dnolen: bhauman: for UI stuff I think this is a good pattern, just remove the sources (removeEventListener) and exit

12:20 bhauman: dnolen: gotcha, you are referring to while(true) go loops that don't close?

12:21 egghead: bhauman: I've noticed mostly i've been using go blocks with in/out chans and rarely do I find myself using the go block to deliver the result of some computation

12:21 but it seems like that is probably the cleaner thing to do?

12:21 I really liked the way bhauman did that in the dots game

12:22 actually I might be mistaken, think I'm thinking about the little :draw :draw :draw :drawend pattern

12:22 supersym: whats the difference between (declare foo) and (def foo)?

12:22 dnolen: bhauman: say a user clicks in a autocompleter field, you fire up all the channels and hook everything together, user makes a selection then tabs out, on tabout you can just remove listening on the event sources and exit the autocompleter loop

12:23 bhauman: egghead: I think both are very appropriate. Think one for modifying a stream and another for creating a stream.

12:26 supersym: oh the dots game looks nice btw :)

12:26 bhauman: dnolen: nice, but in your case there is a tab event channel that acts like a switch to destroy the autocompleter?

12:26 coventry: supersym: The source for declare in core.clj suggests that declare is a sequence of defs with {:declared true} as additional metadata.

12:26 bhauman: supersym: thanks

12:27 supersym: coventry: thank you

12:28 I should really check the source before asking

12:30 seangrove: bhauman: Enjoyed your core.async dots article!

12:30 dnolen: bhauman: I listen on blur which handles click elsewhere and and tab out

12:30 bhauman: I've got a cool example where we need a cyclic barrier to deal w/ a browser quirk

12:30 bhauman: seangrove: thanks, man :)

12:30 * bhauman is now really looking forward to dnolen's next post

12:31 bhauman: dnolen: ^

12:31 dnolen: bhauman: cyclic barrier here just means a channel that waits for n other channels to write data before writing out their values in a vector

12:31 bhauman: we need this because f**king browsers blur on mouse down, so we can't wait for click

12:31 anyways the beautiful thing here is this is all quarantined from the actually autocompleter code

12:32 all this crap is at the event layer where it belongs

12:33 bbloom: blur is extra broken in IE too

12:33 blur events can just magically go missing sometimes

12:33 bhauman: dnolen: I totally commiserate about the complexity of raw events. I went down a deep rabbit whole drawing. And I'm still not at the bottom.

12:33 "with the drawing" i mean

12:34 dnolen: bbloom: yeah I plan on doing the requisite IE compat stuff, though I'll probably cut it off at IE 7/8 for for lack of patience

12:34 I expect most of the issues to be CSS, not the event stuff

12:34 bbloom: oh, nobody should care about 6 any more. fuck 7 too for most purposes. however, 8 has these bugs w/ blur too according to the react.js source

12:34 dnolen: this has been the case w/ my other posts

12:35 bbloom: I don't doubt it, my revelation here is we don't need to taint a correct process w/ this stuff

12:35 "Quarantining Quirks"

12:35 bbloom: yes.

12:35 react does a nice job of creating a uniform event layer

12:36 dnolen: bbloom: cool, do they use queues as well?

12:36 supersym: bhauman: I was pondering some problems before really diving into cljs

12:36 seems like your post/game solved them quite elegantly

12:37 bhauman: supersym: thanks, I am refactoring some of the examples right now to clean up a major short coming of the method used in that post

12:38 bbloom: dnolen: in a sense. they just have a bunch of javascript arrays that they use in queue-style and accumulate events up. they then wrap all the browser events in synthetic event objects that prevent a cross-browser interface & all the subscribe/unsubscribe stuff gets de-quirked as much as possible

12:38 if github was working, i'd link you to their ascii architecture diagram

12:39 it's in src/core/ReactEventEmitter.js

12:39 dnolen: bbloom: and this architecture is cleanly exposed to users who want to adopt the pattern?

12:40 bbloom: one thing I'm seeing is that I rarely want subscribe/unsubscribe nor my early usage of `multiplex`

12:40 bbloom: dnolen: their dom structure / behavior stuff is relatively decoupled from their reactive stuff, but all 3 rely on an ID assignment scheme & use those IDs to maintain state external to the DOM

12:41 yeah subscribe/unsubscribe is always a bad plan

12:41 if you use react proper, they basically garbage collect after each "frame"

12:41 egghead: multiplex, more like broadcast amirite :p

12:41 bbloom: they walk the change set and unhook all event handlers for objects that are no longer in the dom

12:41 they do that in a pass after updating the dom, iirc

12:42 dnolen: egghead: I not convinced about how often you need broadcast either

12:42 egghead: my hunch it that should be avoided nearly everytime

12:44 egghead: it's interesting to turn a chan into a fan-out style chan, but I agree that it's the edge case, sometimes you want multiple people to consume the message, what would be the better alternative to broadcast in that situation?

12:45 bhauman: egghead: the :draw :draw :draw :drawend pattern is not bad but it is weak in that consumers of the stream have to manage and detect each whole draw action. The consumers have to manage that state transition.

12:45 bbloom: i prefer to coerce events in to state

12:45 then pass state as an argument to a pure function

12:46 then diff output w/ the previous output and coerce the diff in to dom mutations :-)

12:46 that's what react does. it's pretty magical

12:46 bhauman: egghead: much better to do channel of channels [ [:draw :draw :draw] [:draw :draw :draw]]

12:46 bbloom: magical in the life changing sense, not in the opaque confusing negative sense

12:46 egghead: I'm not in love with explicit mapping/filtering of chans I've been doing with cljs stuff since I always end up being subtly bitten by consuming the message before I intend to

12:47 maybe that will pas

12:47 s

12:47 dnolen: bbloom: with the DOM mutations, how do they make that consistent, do you have to follow conventions in your template?

12:47 bhauman: egghead: yeah it's hard to put the message back on the queue without creating a new one

12:48 pandeiro: is dir no longer required into nrepl by default?

12:49 tbaldridge: mdrogalis: ping

12:49 dnolen: egghead: I think subscribe may be OK for multiple views needing to get changes from a data source, but I think worth exploring alternative designs. Maybe writing the changes N times onto a channel for N consumers is simpler?

12:50 egghead: there's lots to think about and invent - exciting stuff in my opinion. I definitely recommend ditching any previous notion of architecture you may have and try lots of stuff.

12:51 egghead: agreed

12:51 noncom: how do i access the main class file generated by lein from a java program? i do gen-class for that namespace and I think it must be compiled to a class available from java.. but i am a little confused, there are "core$_main.class" and "core$loading__4910__auto__.class" and "core__init.class" and "core.class" ... which one do i pick?

12:51 egghead: oh hay github is back

12:52 noncom: and how do I call it from java anyway? what will be its java fully-qialified name?

12:53 oh, manifest says "Main-Class: lein_natives_test.core"

12:54 so it breaks java conventions and starts with a lowercase letter.. hmm

12:56 egghead: noncom: it's relatively common to just include the clj runtime and provide a java class that delegates to your clojure code

12:57 ls

12:57 lazybot: bin etc home lib lost+found opt root sbin srv tmp var

12:57 egghead: oh thanks lazybot

12:57 noncom: egghead: is there an exception for that?

12:57 s/exception/example?

12:57 egghead: noncom: take a look at https://github.com/nathanmarz/cascalog/blob/develop/cascalog-core/src/java/jcascalog/Api.java for an example

12:57 dnolen: clojure-mode indentation is such an eyesore

12:57 http://ragnard.github.io/2013/08/12/datomic-in-the-browser.html

12:57 Anderkent: I wouldn't do that unless you need to expose stuff to javaland anyway..

12:58 seangrove: dnolen: What should it be instead?

12:58 pjstadig: noncom: also this https://github.com/clojure/clojure/blob/master/src/jvm/clojure/main.java

12:58 noncom: Anderkent: that is exactly what I need.. :)

12:58 egghead: along with https://github.com/nathanmarz/cascalog/blob/develop/cascalog-core/src/java/cascalog/Util.java#L36

12:58 seangrove: I wouldn't mind seeing a clj-fmt pre-commit hook tool

12:58 dnolen: seangrove: always 2 space, align only on binding forms and data structure literals

12:58 `cbp: damn this gandalf theme from emacs live has some impossible to read colors. Does anyone have good light-colored clojure color themes? :-)

12:58 Anderkent: noncom: oh, okay. I thought you were just looking to run something from a jar - java -cp <jarfile> clojure.main -m my.clojure.namespace is fine then

12:59 egghead: `cbp: I like http://chriskempson.github.io/base16/

12:59 Anderkent: noncom: in that case https://github.com/mikera/clojure-utils/blob/master/src/main/java/mikera/cljutils/Clojure.java might be for you

12:59 noncom: Anderkent: for technical reasons I need to get the access to the class-file generated by lein...

13:00 Anderkent: oh ok

13:00 nvm then

13:00 was wrong again :P

13:00 `cbp: egghead: :-)

13:01 bhauman: dnolen: we should throw some comments on that post eh?

13:02 Anderkent: dnolen: I don't see anything wrong with that indentation. Aligning call args is the right thing to do.. You can still put a newline right after fn name if it takes you too far right I guess

13:03 dnolen: Anderkent: I'm sorry it's an abomination plain and simple. My opinion of course.

13:05 llasram: Isn't it just the traditional way one idents Lisps?

13:05 Anderkent: so you'd do (f 2 3\n<indent>4 5) ? That's... surprising. For me the intiution of vectors with all members equal and lists with the first member priviledged (i.e skipped for alignment purposes) seems most natural

13:06 dnolen: llasram: no, this ugliness is a Clojure community innnovation

13:07 Anderkent: the main thing I find confusing is that some forms are special cased - defn etc.

13:07 hiredman: dnolen: that is not true, it is how emacs indents lisp

13:07 llasram: Looks to be standard for Emacs, yah: http://www.gnu.org/software/emacs/manual/html_node/emacs/Lisp-Indent.html

13:08 hiredman: you can get emacs to indent random clojure forms like you are saying by telling emacs those forms get defun style indentation

13:08 (defun is not a typo there)

13:10 some scheme style guides also recommend the aligned argument style

13:11 dnolen: hiredman: ok maybe it is an lisp dialect innovation, it's not something I've seen much in Scheme code

13:11 Anderkent: well, I guess for me what exact style you use is not that important, as long as you can produce a config that automatically aligns according to that style... Consistency over prettyness.

13:12 kasterma: Why do you value consistency over readability?

13:12 hiredman: dnolen: when you google "scheme style guide" the first one has the aligned arguments style

13:13 http://community.schemewiki.org/?scheme-style also

13:13 the only place where it is a issue, and I suspsect this is why you are so annoyed by it, is when you have forms like core.logic's fresh

13:14 dnolen: hiredman: yes but unsurprisingly no examples of about how catastrophically ugly it is with moderately long function names

13:14 pjstadig: yeah you need to have clojure-mode indent that like a defun, and you're good

13:14 Anderkent: dnolen: just put a new line after function name?

13:19 dnolen: Anderkent: then you get 1 space indent *shakes fist*. I should probably stop complaining and write an elisp defun that does what I want.

13:20 hiredman: (put-clojure-indent 'fresh 'defun)

13:20 clojurebot: Gabh mo leithscéal?

13:20 coventry: nrepl's M-. hits the leningen jar file for clojure source code, which is a bit slow. Is there a way to point it at an uncompressed tree?

13:21 hiredman: clojurebot: what are you doing?

13:21 clojurebot: Huh?

13:21 Anderkent: the one space indent makes sense to me since it's just a list. Otherwise you get indents in (quote (1 \n 2 \n 3))

13:22 unless you make your indent scroll a compiler I don't think you can reliably distinguish between list-to-be-executed and list-that-is-just-data

13:22 so you have to indent them the same way, and the 1 space indent is less ugly :P

14:08 dnolen: si14: what part about the core.match preallocated exception for backtracking is confusing?

14:10 bbloom: dnolen: sorry for the delayed response: the way you make that consistent is that you defer all dom operations & represent even the act of creating a node as data. when you write a render function in react, you don't actually create a node. you only create a node descriptor. and then if that descriptor matches the dom, nothing happens. so in effect, by always returning a plan instead of the result of executing the plan, then the runtime

14:10 can enforce consistency for you

14:10 dnolen: bbloom: so they have some kind of language for all the different ways you can manipulate the dom?

14:11 bbloom: dnolen: their JSX language is optional. it basically adds XML literals to javascript, but they parse trivially from <Parent x="5"><Child/></Parent> to something like `new dom.Parent({x: "5"}, [new Child()])`

14:12 but that just creates basically a description like: {"type": "Parent", "params": {"x": 5}, "state": {}, "content": [{"type": "Child" ....

14:13 dnolen: bbloom: yes so they fiddle with that, but how do they handle all the different kinds of dom manip you might do?

14:13 append, prepend, change attribute, HTMLFragment, etc

14:13 bbloom: or do they try to abstract that away?

14:13 bbloom: you don't do any of that nonsense :-)

14:14 so there are two answers:

14:14 1) you generally avoid that & instead write pure functions that return a new view. just like if you were rendering the full page server side. the runtime will make that efficient w/ memoization

14:14 2) but of course you need to react to events

14:14 dnolen: bbloom: so do they always build DOM? behind the scenes do they do the fasting thing

14:14 clone, HTMLFragment, string + innerHTML?

14:14 bbloom: yeah

14:14 seangrove: Woo, destructuring args in javascript

14:14 dnolen: bbloom: but not pluggable?

14:15 seangrove: It's not beautiful, but a step forward, I suppose

14:15 bbloom: for #2, you can call setProps on a child or whatever & that will maintain some stateful components. but all that state is processed transactionally. if you change props or state on yourself or a child, you can't observe the new props or state until the next frame

14:15 all the props & state are applied in a transaction

14:15 then the recursive diffing happens

14:16 dnolen: bbloom: ok sounds good, but as usually I'm skeptical this covers all the cases I care about

14:16 bbloom: dnolen: the event system is pluggable, so you can add new event types to play with this system

14:16 you can't do jquery-like aspect-oriented things

14:16 that's the biggest limitation, which could be viewed as a feature for larger apps

14:16 dnolen: bbloom: yeah I don't really care if you can't eliminate the rendering mapping dilemma

14:16 bbloom: would like a system that could abstract over DOM, WebGL, Canvas etc

14:16 bbloom: oh, they have an escape hatch

14:16 you can always request the underlying dom node

14:17 and there are callbacks for when you are mounted or unmounted on to a node

14:17 so you can do anything you want, but you just have to manage it yourself

14:17 and you can package that behavior up in to a mixin if you want

14:17 dnolen: bbloom: that's good, though the point is can you reuse the architecture or not for new surfaces

14:17 if not, it's the same garbage as everything else

14:18 bbloom: the same *design* can be applied to other things, which is what i'm occasionally working on: getting that to work for HTML, or Canvas, or GL, or Swing, or whatever

14:18 but their implementation is finely tuned for html/dom

14:21 doing this sensibly for an arbitrary backend & supporting a general notion of a "button" or other widget that is both abstract, but customizable per platform is *hard*

14:22 dnolen: you can think of react's diff rendering loop as a little interpreter that's doing symbolic macro expansion and selective evaluation at runtime. hence why i'm talking to kovas about symbolic engines :-)

14:26 dnolen: bbloom: yeah I got that from your earlier descriptions, I just want support for multiple interpreters :)

14:28 bbloom: dnolen: me too :-) i started implementing it in an ad-hoc fashion, but there was a TON of boilerplate code & the interpreters were SLOW, but casual analysis showed that a lot of things can be trivially optimized

14:29 tbaldridge: eric_normand: ping

14:29 eric_normand: tbaldridge: hey!

14:29 bbloom: dnolen: i found myself creating/flattening/reduce-ing large trees of s-expression encoded in vectors with keyword tags

14:29 tbaldridge: hey, I'm interested in the problem you mentioned on twitter. is there something we can do differently to solve your problem?

14:32 eric_normand: tbaldridge: I doubt it, but maybe.

14:32 tbaldridge: I converted many callbacks in our code into async channels

14:32 with go blocks blocked listening for a message

14:33 tbaldridge: eric_normand: ok, sounds reasonable

14:33 eric_normand: some of the callbacks I converted were listening on chrome channels (different type of channel)

14:34 so the callback to add a message on the channel was waking up the event page

14:34 then it would go into a loop (with setTimeouts)

14:34 listening for the messages

14:34 so it would never sleep and took 100% CPU

14:35 after a few days, the extension would crash

14:35 it could also be that it was creating a new go block (with infinite loop) per callback

14:35 I haven't diagnosed it that far

14:36 tbaldridge: eric_normand: I assume this is the api you are using? http://developer.chrome.com/extensions/messaging.html

14:36 eric_normand: yes

14:37 my conclusion was that we should not use core.async for these wakeup callbacks

14:38 and there is little other reason for core.async in the event page, since the event page is just a kind of relay between the content scripts

14:39 dnolen: eric_normand: huh reading the twitter convo and following this - I'm not sure I follow the reasoning.

14:39 tbaldridge: eric_normand: that's the part I don't understand, something seems odd in the fact "listening for the messages" causes a infinite loop. All these apis are callback driven, so this should happen

14:39 dnolen: eric_normand: sounds like something you could repro in small example if it's as fundamental as you say.

14:39 eric_normand: easy

14:40 (go (while true (let [x (<! c)] (.log js/console x))))

14:40 then never put message to c

14:40 don't even need the while loop

14:41 tbaldridge: I do that exact code all the time, it shouldn't be a problem

14:41 eric_normand: the problem is that the event page does not sleep

14:41 it will run forever as long as the browser is open

14:42 tbaldridge: are there a large number of messages in c?

14:42 eric_normand: no

14:42 tbaldridge: if the last reference to c is dropped, this go will be GC'd and the whole thing will go away

14:42 eric_normand: correct

14:42 but I cannot drop the reference to c

14:43 it has to be listening for messages

14:43 dnolen: eric_normand: so are you saying this is Chrome Extension architecture thing, the event page must be completely restartable or something?

14:43 eric_normand: dnolen: yes

14:43 chrome manages the wakeup

14:43 you register for events when you should wakeup

14:44 tbaldridge: "listening" in the code sample you gave above is just a callback attached to the channel. I assume you are using the stock core.async channels. i.e. you didn't re-implement the channel protocols

14:44 eric_normand: yes

14:44 tbaldridge: how are you getting data into c?

14:45 eric_normand: let me check

14:45 dnolen: eric_normand: I just tried you example, I see no calls to setTimeout

14:45 eric_normand: hmm

14:46 tbaldridge: I wonder if the problem is on the putting side of c

14:46 dnolen: eric_normand: I've done quite a bit of basic profiling of core.async under CLJS around memory and event generation and haven't seen this issue.

14:47 eric_normand: might be missing something but it's not coming up under the Chrome Timeline

14:47 eric_normand: ok, I need to do deeper investigation

14:48 dnolen: eric_normand: ok there's exactly one call to MessageChannel in Chrome, no others

14:49 eric_normand: we don't event use setTimeout for message sends, setTimeout only comes into play for put! and I think go block wakeup

14:49 tbaldridge might know a bit more

14:49 eric_normand: there must have been something waking it up

14:50 dnolen: eric_normand: I'm assuming you can't keep state on the event page because of wakeup?

14:51 eric_normand: dnolen: right

14:51 we use local storage

14:51 dnolen: eric_normand: ok, than it is probably the one message that screws everything up for you.

14:51 eric_normand: but now I realize that we keep the channel in state

14:52 so that the callback can put the message onto the correct channel

14:52 dnolen: eric_normand: initially sounds like the Chrome Extension model is busted to me though - and core.async might be a bad model because event page is a dirty hack

14:52 eric_normand: so yeah you create creating pages that stay awake because of one event

14:53 eric_normand: it looks like two problems: we keep channel around for the callback, and we don't check if the page is already loaded before initiating another channel

14:53 dnolen: eric_normand: right

14:53 eric_normand: I don't know if we can check

14:54 I basically ported all of our callbacks directly to channels

14:54 but I failed to realize that the callbacks needed also to register themselves again

14:55 they need to register each time the page is loaded, or it won't wake up again

14:56 dnolen: I think you're right. It's just a hack

14:56 dnolen: the script is meant to run to completion quickly and be run again later

14:56 dnolen: eric_normand: this is how I think it works

14:57 eric_normand: they run the page expecting it to terminate, your event handler is listening on a queue

14:57 eric_normand: but your code drops and event handler hanging the JS context

14:57 every event will create a new hung event page eventually crashing the browser

14:58 eric_normand: dnolen: agreed.

14:59 potetm: Okay, I have a newb question: what does the '#function-name syntax *actaully* mean?

14:59 amalloy: ,'#'inc

14:59 clojurebot: (var inc)

14:59 potetm: Is that just clojure's way of denoting a function reference?

14:59 '#inc

15:00 ,'#'inc

15:00 clojurebot: (var inc)

15:00 potetm: '#'inc

15:00 eric_normand: dnolen: my solution was to avoid core.async in the event page

15:00 potetm: ,'#inc

15:00 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

15:00 eric_normand: potetm: not function reference. it returns the Var

15:01 dnolen: eric_normand: yes, I think you're conclusion is reasonabe :)

15:01 tbaldridge: eric_normand: yeah, that makes sense now.

15:01 dnolen: s/you're/your

15:02 potetm: eric_normand: okay, so when I say (function-name arg1), in this context "function-name" is a symbol that refers to the var '#function-name

15:03 That seems a little convoluted to me… maybe I'm missing some underlying simplicity…?

15:03 dnolen: eric_normand: I suspect it can be made to work, but I think you'd have to extra careful

15:04 eric_normand: potetm: vars are there for interactive development

15:04 dnolen: agreed.

15:05 juhu_chapa: Is there a way to refer to parent namespace? i.e. (println ../somevar)

15:05 eric_normand: potetm: they are an efficient way for the compiler to point to something that won't change (the var) but refers to something that will (the function)

15:05 potetm: afk

15:06 potetm: eric_normand: afk? you mean afik?

15:06 channels: afk is a reader macro equivalent to Away From Keyboard

15:07 potetm: lol

15:07 I wasn't sure if he actually meant it because it was directed at me personally. Thanks channels ;)

15:09 callen: Twitter is great today.

15:10 eric_normand: potetm: sorry, just had something to attend to

15:10 potetm: in the middle of the chat

15:10 callen: ztellman: thanks for the laughs.

15:10 ztellman: you mean the totally reasonable solutions?

15:10 potetm: eric_normand: not a problem

15:12 callen: ztellman: sure, but aphyr's reactions to the exchange were great.

15:12 ztellman: yeah

15:13 snake-john: Hi, (let [x 2 y (- x)] (clojure.pprint/pprint ``(~y))) shows in the repl (clojure.core/seq (clojure.core/concat (clojure.core/list user/y))) . But I would have expected (clojure.core/seq (clojure.core/concat (clojure.core/list (-2)))). An anybody explain to me why the (-2) is not shown?

15:13 callen: ztellman: I've had to write code to monkeypatch test ordering to keep coworkers from relying on stateful, specific-order hand-offs between test-cases before so I'm sympathetic to the problem.

15:13 ztellman: callen: ha, I've never actually had to do that

15:13 amalloy: snake-john: not enough ~s

15:14 callen: ztellman: work with more Python and Ruby programmers - and you will.

15:14 ztellman: but the tests don't run in the order they're defined in the file, right?

15:14 so how on earth can they rely on the ordering?

15:15 callen: ztellman: people will use hacks to make it ordered

15:15 just google around for 'python unittest order'

15:15 my monkeypatch was a counter-measure.

15:15 ztellman: fun

15:19 gtrak: ugh seriously, I'm not mad at clojure for breaking changes, but ugh.

15:19 1.3-1.4 was way more trivial.

15:20 snake-john: amalloy: hmmh I would have thought the inner syntax quote gets run first which would yield (-2) and then the second syntax quote gets applied which would use the (-x). But this is probably not how nested quotes work

15:21 ztellman: gtrak: I dunno, that's a pretty flimsy invariant to rely on

15:21 gtrak: it's not done on purpose, but I think it ends up being transitive.

15:22 I think the practice of simply copying output as the value you're testing for is the real malpractice.

15:22 hammer: i need to convince clojure to use one method on a java API, and not the other, one takes an Iterable<Pair<String, byte[]>>, the other takes a Map<String, byte[]>

15:22 gtrak: I can't go look at it later and see if the order really matters unless I wrote it.

15:22 ztellman: hammer: hinting as ^Iterable or ^Map should do the trick

15:23 hammer: it's a both

15:23 PersistentArrayMap implements Iterable

15:23 gfredericks: hammer: yeah but you hint so it knows what to treat it as

15:24 gtrak: if the map instances randomized its storages, then the tests would never run correctly twice.

15:24 and that's way better.

15:25 instead of acting as timebombs

15:25 hammer: where would i hint it? I've got map m, and I'm calling Foo.bar(Map<String, byte[]) from java, so I've tried (Foo/bar (^java.util.Map m))

15:25 but that thinks I'm trying to call the function on m

15:25 ArityException Wrong number of args (0) passed to: PersistentArrayMap clojure.lang.AFn.throwArity (AFn.java:437)

15:25 gfredericks: hammer: (Foo/bar ^java.util.Map m)

15:26 cmatheson: /b #e

15:26 oops

15:27 hammer: ah awesome

15:27 gfredericks: cmatheson: that's a secure password because it has two special characters

15:27 hammer: thanks a bunch

15:28 cmatheson: gfredericks: haha, just trying to switch channels

15:39 gzmask: lein uberjar just doesn't work and keeps giving me: could not find load main class error. I am pretty sure I got all the stuff right and it was working a month ago...

15:41 gfredericks: ztellman: holy snap this potemkin

15:41 ztellman: gfredericks: ayup

15:42 callen: gfredericks: I appreciate that he used the word conflate instead of complect in describing import-vars.

15:42 gfredericks: ztellman: I keep wanting lazy maps everywhere

15:42 callen: I'm probably going to need potemkin soon because I have a library that is going to get hairy.

15:43 ztellman: gfredericks: lazy maps? maps with random key order? maps that only give you what you ask for every other time? use potemkin!

15:43 also there's this, which I think is one of the funnier things I've written: https://github.com/ztellman/potemkin/blob/master/src/potemkin/types.clj#L37

15:43 amalloy: i feel like ztellman must have recently hired a PR person and handed over his twitter/irc credentials

15:43 gfredericks: ztellman: I want to create a type which implements every interface in clojure.lang. Can potemkim help me do this?

15:43 ztellman: watches the protocol var, updates other protocols whenever it changes

15:44 gfredericks: perhaps defeverything?

15:44 gtrak: gfredericks: defclojure

15:45 ztellman: gfredericks; this gets you like 2/3rds of the way there: https://github.com/ztellman/potemkin/blob/master/src/potemkin/collections.clj#L21-L164

15:45 amalloy: it took me a while to find a PR firm fluent in Clojure, but it was well worth the effort

15:46 * gfredericks stares at `this##

15:46 ztellman: gfredericks: https://github.com/ztellman/potemkin#unify-gensyms

15:49 devn: ztellman: i just played hackey sack, sponsored by Factual

15:51 ztellman: Factual is renowned as a great patron of the hackey sack

15:58 noncom|2: where is weavejester? haven't seen him for a while..

16:00 eric_normand: anybody going to play in Clojure Cup?

16:01 `cbp: :-O are there prizes?

16:02 timvisher: has anyone heard of an effort to automitically build up var definition history in nrepl without directly interacting with the repl buffer?

16:02 i.e. logging off the form that's evaled whenever one is evaled?

16:03 noncom|2: timvisher: no.. and what about you?

16:04 timvisher: noncom|2: indeed i have not. it finally hit me at the Clojadelphia's meetup last night that the reason you might want to use the REPL directly is to be able to scroll back through the intermediate definitions of a function as you're building it up

16:05 it doesn't seem like it would be that hard to automatically print the evaled form in the REPL before actually evaluating it, so I thought someone else might have cooked one up already

16:05 hiredman: I think that assumes a style of working that is not universal

16:05 noncom|2: timvisher: oh, i think that's what ccw does

16:05 timvisher: hiredman: ?

16:05 noncom|2: that might be what i'm thinking of

16:06 hiredman: timvisher: I generally don't build functions in the repl

16:06 noncom|2: but personally i use ctrl+up to wind the buffer and find a particular memory from the past

16:06 timvisher: i also thought that hugo duncan might have mentioned something in his nrepl talk

16:06 hiredman: if I have a little expression or something I will build that up in the repl

16:06 travisrodman: ivaraasen: thanks for sharing your code example the other day, about how you consume the clojure code in java. it was in regards to the data importer. very helpful. thanks

16:06 hiredman: but often I start with (defn f [] ...) in a file, eval the whole file, call (f) in the repl

16:06 timvisher: hiredman: you're describing how i work, i believe

16:07 eric_normand: from the home page and the judges, clojure cup will be a game project

16:07 noncom|2: hiderman: timvisher: you all say this coz you no use lighttable yet

16:07 timvisher: you don't just type (f) directly into the file, perhaps in a comment form, and eval it?

16:07 hiredman: I extremely rarely type a form (defn …) in to the repl

16:07 timvisher: noncom|2: :)

16:08 hiredman: timvisher: sure, I've done that too

16:08 noncom|2: i do defns in repl when i figure out how to construct that or another sequence of collection-operating àòû

16:08 timvisher: regardless, i realized last night that what that looses is the intermediate steps of building up my function

16:08 hiredman: timvisher: but my point is, in that style a history of vars in the repl doesn't seem useful

16:09 noncom|2: that never exceeds oneliners though

16:09 timvisher: it seems like more people than not in the clojure community use the repl directly and then copy fully defed vars into their source file

16:09 hiredman: timvisher: if you are reloading a hole file, how does your history thing work?

16:09 timvisher: i don't like that because my repl buffer is not 'savable'

16:10 bbloom: timvisher: i think most of us write in to source files directly & then use a key combination to send forms to the repl

16:10 timvisher: hiredman: i'd assume that if a function definition hasn't changed it would not reprint

16:10 bbloom: interesting. maybe i've just gotten an incorrect impression then. :)

16:10 hiredman: *shrug*

16:10 noncom|2: timvisher: usually it does reprint, since the other way requires more analysis

16:10 hiredman: I am not advocating for something, or saying one thing is more common than another

16:11 timvisher: noncom|2: in ccw? i would be annoyed by that i think.

16:11 hiredman: I am saying there are assumptions there that aren't universal

16:11 timvisher: hiredman: i'm assuming there would be a configuration option with that

16:11 noncom|2: timvisher: anyway, tell us what is your vision of the future?

16:11 hiredman: so go a head and do whatever, just don't be surprised if no one cares :)

16:12 chronno: timvisher: nrepl-send-to-repl in https://gist.github.com/kingtim/4349847 although I haven't tried it.

16:12 timvisher: so if you don't want your repl buffer filling up with intermediate definitions then you wouldn't turn the feature on

16:12 chronno: interesting!

16:12 hiredman: duly noted. :\

16:13 noncom|2: vision is that curretly as i'm building up a form, i have to rely on undo to back off from a bad set of changes to a good state

16:14 noncom|2: timvisher: so, per-form history you want?

16:14 timvisher: if you think of the REPL as a shell, and your function as a complex set of piped together commands, then it would be like piping on 2 new commands, executing it, and realizing you screwed up, and not being able to press ↑ and try again

16:14 instead, you have to press your undo key a bunch of times, remembering what the form looked like before, and hope that you don't go to far

16:15 hiredman: timvisher: what repl are you using that doesn't have history?

16:15 noncom|2: yes it is so currently

16:15 timvisher: so the vision would be that i can always go to the repl buffer and look through the history of things that i evaled, in order, and pick up where i left off

16:15 noncom|2: timvisher: i think you can device this repl youself?

16:16 in elisp or swing? depends on your preference..

16:16 hiredman: timvisher: you just want to save the history?

16:16 timvisher: hiredman: nrepl.el does not do this by default (or in any configurable was afaict)

16:16 noncom|2: timvisher: once i made such an app. it was in java and for shell commands though. it was an easy task

16:16 timvisher: if i'm interacting with the repl directly it does, but i prefer to edit source files for basically any kind of editing, even if that's just exploratory

16:16 hiredman: because for example, in nrepl.el M-p will give you the previously eval'ed code

16:17 llasram: timvisher: Er, nrepl-history-size etc ?

16:17 timvisher: hiredman: do you have a source file open?

16:17 if you do, type `(+ 1 1) C-x C-e` and then switch to the nrepl buffer and press `M-p`

16:17 hiredman: I have many, in emacs buffers locally and remotelly

16:17 timvisher: `(+ 1 1)` does not show up for me

16:18 only what i actually have typed in the repl buffer is in that history

16:18 hiredman: sure

16:18 timvisher: hiredman: so that's the feature i'm talking about desiring. :)

16:18 hiredman: and what do you want to happen when I hit C-c C-k and then M-p in the repl

16:19 timvisher: what does `C-c C-k` do?

16:19 hiredman: loads the whole file

16:19 timvisher: interestingly, it loads the buffer

16:19 C-c C-l will load the file, but that's beside the point

16:19 i would want to have only vars whose definitions have changed appear in the repl

16:20 but if it was too hard, i'd probably be ok with all the forms being printed as they are evaled

16:20 llasram: Perhaps you may be interested in inferior-lisp-mode?

16:20 timvisher: llasram: is this how inferior lisp works?

16:20 i only used that briefly way back in the day and then moved onto slime

16:20 i wouldn't want to miss all of nrepl's features just to get history

16:21 llasram: Well, then pick and or fork your poison :-)

16:21 inferior-lisp just has a process which you can pump forms to

16:21 timvisher: that's what it's sounding like i'll have to do

16:22 llasram: So they're all in history, but you can't ask the process anything (like get docstrings) etc

16:22 timvisher: llasram: yep. that's what i'm looking for but with all of the other nrepl goodness. :)

16:22 this would _definitely_ not be worth the tradeoff of loosing the rest of nrepl

16:22 it's more of an expriment too

16:23 i'm pretty happy with my current dev flow, i just finally realized why some people might develop at the repl rather than in their source files

16:23 and it seems like it would be a good experiment to run

16:25 `cbp: Am I the only one that goes to the last paren of an expression then does C-x C-e? I feel like I should be able to C-c C-c inside the body like with common lisp :(

16:26 technomancy: `cbp: C-M-x

16:26 eric_normand: `cbp: I C-c C-c

16:28 `cbp: oh what the heck i swear i couldnt do c-c c-c before. Also i didnt know about C-M-x

16:29 coventry: C-u C-M-x is awfully useful for stepping through elisp.

16:29 gtrak: `cbp: huh, I still do it that way. thanks for the tip.

16:29 `cbp: must have been used to an old version of nrepl

16:31 gtrak: I can neither do c-c c-c nor C-M x

16:31 KDE grabs it I guess

16:32 C-M anything seems not right

16:34 ah, my repl itself is hosed

16:38 callen: just a reminder to everybody

16:38 Java's SecureRandom is not secure, nor is any userland CSPRNG

16:38 I just got done putting in a PR to weavejester's crypto-random to fix it.

16:40 ivan: callen: why not any userland CSPRNG?

16:41 gtrak: callen: this wrecks my plans for a SecureRandomPersistentHashMap

16:41 ivan: callen: also Windows does not have /dev/urandom

16:41 callen: ivan: CryptGenRandom for best-effort on Windows.

16:41 but CryptGenRandom has dubious-at-best entropy sources. Do not run things that need to be secure on Windows.

16:41 don't use SecureRandom on Unix at the very least.

16:42 or don't use SecureRandom with the expectation of cryptographically secure random bytes.

16:42 ivan: you cannot implement a cryptographically secure PRNG in userland.

16:42 you must use the kernel API.

16:42 ivan: why not

16:46 callen: ivan: I can't tell if you're asking for a white paper or you want to discuss cryptography system implementation.

16:46 ivan: callen: I just need a summary of why it's impossible, or some citation

16:46 is it because timing attacks due to scheduling?

16:47 callen: that's one of the reasons

16:49 there might be, in some perfect universe, a way to implement a secure CSPRNG in userland, but that never happens. So stop using them.

16:49 or implementing them. Because you'll fuck up.

16:50 gzmask: anyone use core.typed? how would you use it?

16:50 ivan: claiming that something is impossible requires stronger support than that

16:51 callen: ivan: it's a pretty standard understanding of CSPRNG

16:51 technomancy: ivan: what have you got against arguments from authority bro?

16:51 callen: technomancy: security is too fragile for amateur hour "good enough"

16:52 technomancy: particularly when secure options exist. it's stupid and unnecessary.

16:52 xicubed: i once interviewed at a lottery company, they had a server room with some radioactive substance who's decay provided the random seed...

16:52 callen: It also requires a lot of background to really be able to do anything without deeply fucking up.

16:52 technomancy: callen: of course. that doesn't mean you can't back up your claims.

16:53 callen: technomancy: I'm not really in the mood to go white paper hunting, I was scrambling to fix crypto-random and put the word out.

16:53 another problem with security is that there's a lot of out-of-date/wrong information that still comes up via Google

16:54 like OWASP's out of date recommendation to use SecureRandom without specifying impl.

16:55 seangrove: callen: People are basically good.

16:55 Just use a dialog to ask them if they agree to be good people, and don't bother with security

16:56 callen: seangrove: cute. Did you see http://amber-lang.net/ ?

16:56 seangrove: Yeah, remember seeing this awhile ago, looks really great. Never got as far into smalltalk as I would have liked

16:57 callen: seangrove: I was actually thinking about a hybrid of that plus client-side (only) datomic with CLJS source maps

16:57 visually exploring your data and each object's history.

16:58 seangrove: What do you mean client-side only datomic - no datomic server?

16:58 gzmask: anyone has experience with core.typed? does it type check on lein run or do you have to run some function in repl to type check?

16:58 ivan: heh "This class generates cryptographically secure pseudo-random numbers. It is best to invoke SecureRandom using the default constructor. This will provide an instance of the most cryptographically strong provider available" https://developer.android.com/reference/java/security/SecureRandom.html

16:58 callen: ivan: not actually true :\

16:59 and like I said, there is out of date information out there.

16:59 since I'm the only one that tracks security issues: http://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html

16:59 the Android bitcoin client was broken because of faults in SecureRandom's implementation.

16:59 the bitcoin client itself was not at fault.

17:00 ivan: satisfied?

17:02 gzmask: has anyone use core.typed before? does it do type checking during repl-function-calls or runtime?

17:04 llasram: gzmask: It's not widely used (yet?). The project-creator ambrosebs is frequently around this channel, but apparently not at the moment

17:05 gzmask: llasram: hrmm, thanks... I kinda assume anthing has a core. prefix is wildly hip

17:05 supersym: gzmask: https://github.com/clojure/core.typed/wiki/User-Guide

17:06 bbloom: gzmask: type checking w/ core.typed is explicitly invoked

17:06 supersym: assertion seems to take place at the REPL

17:06 as well

17:08 bbloom: yeah, via calling cf (check form) or check-ns

17:09 TimMc: callen: So what's actually wrong with SecureRandom? I see something about "improper initialization", but no details.

17:10 The vague impression I've got is that it's not so much Java that's at fault, but the native code Java is calling into on Android.

17:10 Raynes: tpope: Can I make vim-fireplace not try to start up a repl automatically?

17:10 It takes forever to load files in projects where `lein repl` fails because of it.

17:10 Because it tries every time.

17:11 callen: TimMc: Android's SecureRandom impl wasn't compliant. I don't think OpenJDK's was either.

17:11 hiredman: well, that is you call the runtime system on android "java"

17:11 if

17:12 TimMc: callen: :-(

17:13 callen: TimMc: I believe it had to do with the entropy sources used in the creation on the initialized seed. I could be wrong on that point.

17:14 I'm trying to figure out a wrapper for enforcing the use of "/dev/urandom" || CryptGenRandom right now

17:15 TimMc: I was hoping this was just limited to Android.

17:16 ivan: wrapping /dev/urandom with some kind of buffer is a good idea if you don't want to pay a huge performance penalty

17:16 TimMc: Depends on the system, no?

17:16 ivan: well, you can only open /dev/urandom, read, close, a few thousand times per second

17:17 TimMc: Oh, I see.

17:17 There's also an issue where on a *few* systems, /dev/urandom will block until it has more of the good stuff (juiced entropy from system timings.)

17:18 callen: that's sorta the point

17:18 you can stuff lower quality entropy in if you want, but you should stop pretending it's secure then.

17:19 the stuff that is supposed to be secure should stay so, and if you have some service or "thing" generating a ton of securely random bytes, it's time to get specialty hardware to provide extra entropy.

17:21 TimMc: /dev/random is the one that's supposed to block, right?

17:21 callen: yeap.

18:00 justin_smith: I wonder if anyone has used a shortwave radio on a adc to generate entropy

18:01 https://github.com/pwarren/rtl-entropy

18:02 they have a todo to add entropy to the system pool

18:03 callen: justin_smith: I know a good person to ask about that, they do work on ham radio drivers for FreeBSD

18:03 justin_smith: cool, it seems promising

18:03 callen: it's a nifty idea.

18:18 justin_smith: actually, lower tech, you could probably do a lot with a reverse biased zener diode connected to an adc

18:24 if I have two nrepl buffers open, how do I specify which one a given source buffer is connected to?

18:27 `cbp: why not just multiple emacs :-P

18:30 justin_smith: `cbp: that could be an option I guess, but I am doing one project that shares many properties with an older project: easier to be able to have both open in one emacs - until I deal with the "which of the repls does evaluation in this file connect to" issue

18:30 ie. m-x ediff

18:30 between old core.clj and the new one

18:38 looks like I need to run nrepl-connections-make-default before evaluating code that goes with that connection

18:40 this is tied to nrepl-connection-browser

18:41 it looks like there is support for "projects" but only via nrepl-jack-in?

18:43 glosoli: Hmm

18:49 seangrove: justin_smith: You can switch to the nrepl buffer you want to be default, and then run nrepl-make-repl-connection-default

18:49 I don't know if there's a per-buffer association

18:50 justin_smith: Sorry, just saw you already wrote that

18:50 justin_smith: no problem

18:50 do you know anything about the "project" feature referenced here and there?

18:50 that seems promising, but I am not seeing the big picture

18:51 seangrove: No, I've been running several nrepls recently and would like something like that

19:26 glosoli: How does one clear red overlay when something fails in code in Emacs Clojure Mode ?

19:38 technomancy: glosoli: clojure-test-mode?

19:38 should be C-c k or something?

19:39 glosoli: technomancy: yeah for example I am in the file which has main method and some routes (compojure) defined, and I accidently press C-c k an it outputs some errors and adds the overlay

19:39 :?

19:40 technomancy: you're running clojure-test-mode on a file containing compojure routes?

19:40 that's weird

19:40 hiredman: technomancy: could just be clojure-mode with compilation errors

19:41 technomancy: hiredman: huh; does nrepl.el emit overlays now?

19:41 glosoli: hiredman: yeah this one

19:41 hiredman: glosoli: have you fixed the errors and recompiled?

19:41 technomancy: I dunno

19:41 I never make errors :P

19:42 `cbp: cough

19:43 justin_smith: one can walk the face overlays in an emacs buffer, find the offending item, and delete it - it is like a weird emacs parallel version of the dom

19:44 I forget the details at the moment, but I have done it before

19:44 of course the facility that generated the overlay *should* provide a way to remove it

19:53 TakeV: LightTables is still in active development, yes?

19:53 Raynes: Certainly.

19:54 sinistersnare: hasnt seen an update in a little while i think

19:54 judging from chris grangers blog still being about that cancer and startups thing after a few montsh

19:55 glosoli: sinistersnare: There was some post in Github from him saying it should be released second week of the current month with no promises

19:55 sinistersnare: oh cool then!

19:56 glosoli: Dunno it\s been easier for me to switch to Emacs than waiting for LightTable to improve lol

19:58 justin_smith: it was a nefarious conspiracy; lighttable was just a decoy to get people using clojure in emacs

20:02 sinistersnare: ive been using Nightcode!

20:02 some random IDE a guy made and released a couple nights ago

20:03 patchwork: I really think we need some more code editors

20:04 There just aren't enough

20:04 brehaut: i cannot tell if you are being sarcastic or sincere

20:05 justin_smith: I've been thinking of running a bunch of different window managers on my virtual terminals, and running a different editor under each window manager, and on each one I would listen to music in a different music player.

20:05 sinistersnare: i think competition is great

20:06 patchwork: brehaut: I can't tell either

20:26 s4muel: i'm curious as to what most people here are using to develop clojure, or is that a long-hackneyed debate here

20:27 patchwork: s4muel: Emacs

20:27 plainman: emacs

20:27 patchwork: But editors are religion

20:27 jcsims: Emacs + nrepl

20:28 s4muel: my experience with vim/fireplace etc has been off-putting in comparison to even just the default clojure-mode in emacs (autocompletion, etc) but i am just so used to vim

20:28 patchwork: There is a vim mode in emacs

20:28 jcsims: s4muel: I was exactly the same way

20:28 s4muel: the aptly named evil mode

20:28 patchwork: So you can use all of your vim bindings from emacs

20:28 I know quite a number of people in your boat, and it seems to work for them

20:28 cmatheson: is anyone using evil-mode? i tried it out and it seemed great, but i was oncerned about how it interacted with the various minor modes

20:29 plainman: I started as a vi person, and I probably use it more than emacs, but I found it worthwhile to work at getting the emacs commands down into my fingers rather than try to use the vi mode

20:29 s4muel: I think part of it is also the repl-development 'ecosystem' as it were

20:30 which is just bonkers with vim

20:31 juhu_chapa: Hi guys!

20:31 s4muel: and try as i might i cannot get vim to do two things, and i know emacs does one: i want syntax highlighting for (defn my-symbol-i-want-highlighted-elsewhere [] ()), and doc strings for namespace/method outside of core

20:32 patchwork: s4muel: Yeah, use emacs

20:32 if you can overcome the blasphemy!

20:32 sinsnare: How is repl development a thing though? It doesn't get saved anywhere, how does it work?

20:32 TEttinger: I use Light Table, which has had some issues with evaluating anything longer than a paragraph of code in the instarepl... but otherwise does what I need it to do.

20:33 justin_smith: sinsnare: there is repl history, and really you should be writing functions in your source, and playing with them in the repl (to experiment with variations, see what they do with various inputs, etc.)

20:33 s4muel: sinsnare: reloading your code -- the beauty of functional stateless-ness. For example I'm working on a lamina/aleph processing/plexer thing. I reload the namespace, pass in a message, and see what happens.

20:33 TEttinger: gah you can reload namespaces? I've honestly been using lein repl, quit, lein repl as my workflow D:

20:33 justin_smith: and yes, redefining everything and seeing what it does next time

20:34 sinsnare: That's a really interesting thought. Never thought of it like that

20:34 justin_smith: (require '[foo.bar] :reload)

20:34 s4muel: some stuff requires state to be set up, example i have to prepare/enqueue dummy messages on a channel, but that's easy with some helpers like expectations run-before

20:34 patchwork: TEttinger: The greatest part of using clojure

20:34 modify function in source code, send the definition to the running repl, repl now uses updated code

20:34 sinsnare: I'm fairly new to repl stuff. Ive mostly done python repl as a calculator :p

20:34 patchwork: Now I can't live without it

20:34 TEttinger: I knew people were doing it, but I had no idea how

20:35 sinsnare: So excuse ignorance

20:35 cespare: TEttinger: any workflow that requires you to run lein commands all the time is no good, it's slow as balls

20:35 patchwork: Just C-M-x somewhere in the function definition, repl is now using new code

20:35 s4muel: TEttinger: it gets complex when you have side-effect things like tcp servers that need to be restarted on reload

20:35 TEttinger: cespare, yeah. I figured that part out myself.

20:35 patchwork: BAM!

20:36 sinsnare: that's cool stuff

20:36 patchwork: s4muel: In that case I have the servers referring to #'function-name (a reference to the var rather than the function itself)

20:36 TEttinger: the other issue is with my code using Swing, and main needing to be in a UI thread

20:36 patchwork: Then when I update it, the server is now using my new code

20:38 s4muel: patchwork: I am also doing that with a multimethod dispatch, cool that you can apply it there!

20:38 patchwork: Developed webservers that way, irc bots, socket servers etc

20:38 s4muel: patchwork: I am doing something like this to manage the tcp server from repl https://gist.github.com/shalicke/6246155

20:39 abp: http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

20:39 s4muel: Seems ghetto now.

20:40 patchwork: s4muel: Yeah, that is somewhat elaborate, but it works

20:40 Not entirely necessary if you are using nrepl and emacs

20:41 s4muel: I have (usually) a vim window open, lein autoexpect, and lein repl

20:45 TEttinger: so... I made a small swing app with clojure, but when I wanted a friend to run it, he didn't have java installed. I thought it was going to be rare, but a fair amount of end-users seem to be avoiding installing a JVM these days... What do you think about clojurescript for an application meant for less-technical users?

20:45 s4muel: That's another discussion, tdd workflow -- I'm new & landed on expectations / lein-autoexpect, the other camp(s) seem to be Midje or speclj, any thoughts from the peanut gallery?

20:46 technomancy: clojure.test is great

20:46 expectations seems the least crazy of the options you listed though

20:46 s4muel: Yeah I needed something that would ... not be too much of a learning curve, really, and automatic

20:47 Midje seems like that camp of almost-bdd where it's a journey to write the tests themselves (think webrat/selenium/argh)

20:47 technomancy: right; the main advantage of clojure.test is that basic usage involves a total of two macros; advanced usage typically only adds one more

20:48 callen: Midje is silly and was written by silly people emulating the efforts of nihilists.

20:48 None of them are to be trusted.

20:48 s4muel: author of Midje is probably in this channel somewhere. Don't get me wrong, better developers than me use it, I'm just saying it seems like a real commitment :)

20:49 hiredman: unlikely

20:51 callen: he's not here.

20:52 s4muel: very thoughtful of you, but ad hominem is pretty valid when you're relying on their software. Pass.

20:52 Cf. Rich Hickey vs. Rasmus Lerdorf.

20:52 s4muel: callen: true.

20:53 cespare: > ad hominem is pretty valid when you're relying on their software

20:53 wat

20:53 callen: for any that might care, pending testing, I'll probably reverse my position on c.j.j vs. Korma due to the new API.

20:53 cespare: unless you're willing to audit all of the code, you have to extrapolate from their track record and their judgment.

20:53 patchwork: callen: The new api for c.j.j or korma?

20:53 callen: patchwork: the new API for c.j.j

20:53 cespare: callen: != ad hominem

20:53 callen: it's greatly improved.

20:54 patchwork: Ah, haven't heard that

20:54 I'll check it out

20:54 callen: cespare: it really is. The person that wrote the software can invalidate my willingness to consider the software.

20:54 patchwork: Yeah korma has not been updated in a while

20:54 callen: cespare: concordantly, the point of ad hominem is to use the person behind the argument to invalidate the argument.

20:54 cespare: callen: what you're describing is not an ad hominem argument

20:54 callen: you are seriously misunderstanding me.

20:54 patchwork: cespare: Well, callen says so so it must be wrong

20:55 callen: I am saying ad hominem is a reason to ignore software from certain people. I'm explaining how it's parallel to the use of ad hominem in arguments.

20:55 Arguments can be evaluated on their merits completely within the context of a single discussion, code typically isn't that easy to box up.

20:55 s4muel: reputation as code

20:56 callen: As a result, evaluating the quality of the source becomes a potentially valid and definitely more efficient way to evaluate software from afar.

20:56 I really do not think it was a very subtle or difficult point to make

20:56 I figured the Rasmus/Hickey thing would make it obvious. I guess not.

20:56 going back the original point, anybody who reads the mailing list knows what I'm talking about.

20:59 * callen goes back to writing evil macros

20:59 patchwork: callen: I missed out on the mailing list discussion. Has midje been discredited?

20:59 I have never used it

21:00 * patchwork goes to subscribe to the mailing list

21:00 callen: There are people that use clojure.test because they don't care, people that use midje because they don't care, people that use clojure.test because they "been there, broke that" with testing frameworks like Midje and are duly terrified, and people that use Midje because they forgot to leave the Ruby at the door.

21:01 it's my personal opinion that syntax/DSL is a matter of "least concern" when it comes to testing and instead automating/managing things like fixtures, functional testing, integration testing is a lot more valuable and "labor saving"

21:01 patchwork: So midje uses rubyisms? Hmm… I always thought ruby used lispisms. Well, and smalltalkisms

21:01 Ah, so it emphasized DSL over actual functionality

21:01 Got it

21:01 callen: Ruby is syntactically Perl, semantically a mutable OOP lang, and the Smalltalk has been beaten vicious and put in the closet.

21:02 but because any jackass of the street can believe themselves to be capable of evaluating the readability of syntax, that's what everybody wants to fuck with when it comes to testing.

21:02 patchwork: Ha. Poor smalltalk

21:02 callen: ain't nobody want to do the subtle, more difficult work of making tests more useful or comprehensive.

21:02 or more interesting things like auto-generating test cases against defined constraints and input spaces.

21:03 s4muel: That would be very handy for testing channels and inputs.

21:03 callen: s4muel: google, "haskell quickcheck"

21:03 patchwork: callen: So is there a clojure testing library that does tackle that?

21:03 Count me as in the "uses clojure.text because they don't care" camp

21:03 *test

21:04 callen: there are implementations of QuickCheck for Clojure which is a good start. I just use clojure.test and write tooling to wrap the ugly of whatever I'm working on.

21:04 patchwork: QuickCheck, interesting...

21:04 callen: I've had to work on algorithms with non-deterministic/unverifiable output once the solution space gets large enough, so I basically had to write a fuzzing library.

21:06 there's also just typical web apps. Vanilla unit testing is not very well suited to verifying web apps these days.

21:06 fucking with syntax won't change that.

21:08 `cbp: callen: hi

21:08 s4muel: Yes. Although I think the problem lies at a lower level with simply managing side effects of tests and state in regards to that. Serving an http request is nothing special per se, it's the management of the state of the client, dbs, services, etc. that are ugly, IMO

21:08 `cbp: callen: any more projects i can help with? :-) I need some clojure in my spare time or ill go insane

21:08 s4muel: s/are/is/

21:10 callen: `cbp: I have many. Some hairier than others.

21:10 `cbp: I'm working on bulwark right now, it's a bit fiddly and early stage though.

21:10 s4muel: That's a part of the ugly in terms of implementation details, but I feel like the whole problem is waiting for a nice "gift-wrapped" clean-up like Leiningen was for packaging.

21:11 s4muel: I work on a lot of services/web app type stuff, so half of my shit that can break isn't even technically Clojure code. Being able to sanely test/mock that stuff without a ton of trouble would be nice.

21:17 `cbp: my todo-list includes: Bulwark (Rack::attack for Clojure), proxy+ with JVM annotation bytecode support, pomegranate "sync with project.clj", clj-time API rewrite, Rewriting Selmer with Instaparse as an experiment, possibly quickcheck for Clojure if the existing impls suck, and selmer leiningen plugin for testing batch compliation and reporting any errors if applicable

21:17 `cbp: want in on any of that?

21:20 `cbp: yeah sure

21:20 callen: `cbp: also fun bit of evil: https://www.refheap.com/17695

21:21 `cbp: are you familiar with how proxy works?

21:21 xeqi: callen: can you expand on pomegranate "sync with project.clj"

21:22 callen: xeqi: what it says on the tin. Like what Ritz can do.

21:22 walks up the directory path until it finds a project.clj, checks the dependencies against what's in the classpath as well as the any possibly provided maven repos in the project.clj

21:22 adds things that need added, removes things that need removed.

21:23 `cbp: the pomegranate sync with project.clj or proxy+ thing would be good places to start since they're less fiddly than the other options.

21:24 `cbp: callen: if youre asking me how a proxy server works sure, if proxy is a noun for something else then nope :-P

21:24 callen: `cbp: hoo boy. You're in for it now.

21:24 `cbp: http://clojure.org/java_interop#Java%20Interop-Implementing%20Interfaces%20and%20Extending%20Classes-%28%20proxy%20[class-and-interfaces]%20[args]%20fs+%29

21:25 `cbp: OH that proxy

21:25 callen: yeah, it doesn't support annotations.

21:25 it needs to.

21:25 so a library form of proxy+ with annotations is what's desired.

21:25 this is so things like Netty can be properly wrapped.

21:26 `cbp: oh yeah i get it

21:27 callen: good news, a test case is easy enough to slap together

21:27 bad news is, you'll probably end up balls deep in Clojure's Annotation*.java

21:32 `cbp: so the pomegranate stuff would let people add dependencies without leaving the repl? That sounds nice

21:34 callen: `cbp: well it already does that, but the idea is to not force them to use pomegranate's somewhat tedious and obviously stateful API

21:34 and instead just make the workflow "edit project.clj => (pom/sync!)"

21:34 `cbp: just modify project.clj and come back to the repl?

21:34 callen: yep!

21:34 TEttinger: `cbp, I've done it. it's cool. but as I established earlier, I have no idea how to properly use a REPL...

21:35 callen: I'm tired of restarting my lein repl

21:35 it's fucking annoying.

21:35 I lose all my stuff and end up making temp buffers of intermediate state/code for testing in a REPL

21:35 just so I can restart the REPL for dependencies

21:35 I could use pomegranate, but I find the API tedious even if it works fine.

21:37 `cbp: ok i'll se what i can do :-)

21:46 technomancy: callen: I think maybe the ritz project.clj stuff exists in its own lib?

21:46 alembic or something

21:46 haven't gotten a chance to try it

22:40 cjfrisz: 500-some people and we're all too shy

22:40 Or else everyone else figured out all the secrets of programming, and I'm alone in my ignorance

22:41 That is pretty much the scariest world I can imagine

22:45 ping dnolen

22:46 eric_normand: callen: better: https://gist.github.com/ericnormand/6246733

23:12 hugod: alembic isn't quite the ritz project.clj stuff, though it does use lein, so it would be straightforward to add support for incrementally reloading the project.clj file. It is only really possible to add dependencies to the classpath though, not change them or remove them.

Logging service provided by n01se.net