#clojure log - Dec 19 2013

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

0:03 noprompt: bitemyapp: we'll probably have to move our pairing session to sunday if that's cool.

0:04 bitemyapp: i have to attend holiday "events" tomorrow and potentially friday.

0:29 deadghost_: hmm how I can recover from an exception?

0:30 (clojure.java.io/reader "http://deadgho.st/this-page-does-not-exist")

0:31 gives a file not found exception

0:31 I want to tell it to continue the program

0:32 or in the case of 503 try a few more times then continue

0:33 TEttinger: ##(doc try)

0:33 lazybot: ⇒ "Special: try; catch-clause => (catch classname name expr*)\n finally-clause => (finally expr*)\n\n Catches and handles Java exceptions."

0:34 seancorfield: deadghost_: perhaps use clj-http instead so you have more control over how HTTP status is handled?

0:55 blur3d: does anyone know of an idiomatic way to define an expression once and allow it to be bi-directional (eg. 1 day = 24 hours and 24 hours = 1 day)

0:56 would something like core.logic be suitable?

0:56 bitemyapp: noprompt: this weekend works.

0:59 noprompt: bitemyapp: fantastic.

1:02 echo-area: blur3d: Will java.util.concurrent.TimeUnit be suitable for you?

1:02 Oh, that is only an example

1:02 blur3d: I'm looking to use it in a much broader sense

1:03 something like this

1:03 http://www.algebrahelp.com/calculators/equation/calc.do?equation=a%3D2b&solvf=b

1:04 I'm fairly sure i have seen an example in clojure somewhere... likely in one of the books I've read, but its hard to find

1:04 basically i want to be able to define something once, and flag it is reversible - and then it automatically adds both variations

1:05 TEttinger: blur3d, sounds like a use for macros?

1:05 like def-rev

1:06 blur3d: yeah, the macro can be used to define both of them... but i need a way to start with a=2b and get b=0.5a

1:06 echo-area: I saw similar things in SICP which introduced a constraint propagation system. Not sure if it exists for Clojure though

1:07 blur3d: maybe was I remember was a reverse stack function in C.

1:08 Im hoping to find something I can use generically... so if it knows you can get AUD/USD, then it knows you can get USD/AUD

1:10 echo-area: blur3d: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-22.html#%_sec_3.3.5 Maybe implementing something like this is a last resort

1:13 blur3d: I know the problem is similar to unit conversion, thus you can define a base unit as 1 and then the other units as a factor of the base - and for that you can use multi-dimensional analysis

1:19 anyway, ill keep looking out. Thanks @echo-area TEttinger

1:20 TEttinger: np

1:21 speaking of heavy metal in boss fights, Giygas part one has nes-style music, then transitions to http://youtu.be/9gbG_gzgyJI?t=2m6s

1:22 gah wrong chan

1:39 blur3d: I've found something that I might be able to work off - https://github.com/francoisdevlin/Full-Disclojure/blob/master/src/episode_012/episode_012.clj

1:40 it has a video covering it also http://vimeo.com/9666573

2:10 chenglou: clojure newb here, why does the let statement take a vector for binding and not a map

2:14 blur3d: chenglou: http://stackoverflow.com/questions/3859765/why-does-let-require-a-vector

2:15 chenglou: blur3d: ah thanks. Isn't that slightly expensive though

2:15 I've read that the implementation is a 32-way tree

2:16 but I guess usually they dont exceed a certain number of items

2:16 blur3d: I really haven't looked into it

2:16 chenglou: kk thanks

2:17 TEttinger: chenglou, I think the trees are used for sorted sequences IIRC

2:17 chenglou: TEttinger: I read it's the vector's underlying implementation

2:17 TEttinger: to the src!

2:18 blur3d: chenglou: IIRC hash-maps are internally vectors, so I would presume they are more performant then hash-maps

2:18 TEttinger: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentVector.java

2:19 chenglou: TEttinger: yep

2:19 blur3d: didn't know that, thanks

2:20 TEttinger: it appears to be a linked list up to or after 32 items, I cannot make sense of this

2:20 chenglou: TEttinger: 32-way tree

2:20 TEttinger: http://hypirion.com/musings/understanding-persistent-vector-pt-1

2:20 got it

2:21 btw loving clojure right now, it makes so much sense =)

2:24 TEttinger: yeah, that kind of data structure seems to be pretty useful in general. I know Judy Arrays (a kind of less-memory-intensive associative array designed to reduce cache misses, but 20K lines of code) internally use a 32 or larger way tree

2:24 err trie

2:26 chenglou: first time I hear about judy arrays

2:27 that thing looks awesome and has no performance downside...?

2:27 seriously_random: how to rewrite "(condition? (= blah bleh) (cons '() (recursive-fn (+ 1 n) a-seq))" so that function in the end doesn't give back a list with useless '()?

2:28 noidi_: seriously_random, maybe a list comprehension would work better than explicit recursion and consing: http://clojuredocs.org/clojure_core/clojure.core/for

2:28 seriously_random, the first example on that page demonstrates the use of `:when` to filter out elements

2:29 seriously_random: noidi_, it's got to be recursive

2:30 noidi_: why?

2:30 clojurebot: http://clojure.org/rationale

2:31 noidi_: http://blog.fogus.me/2011/03/09/recursion-is-a-low-level-operation/

2:31 seriously_random: noidi_, because it's mooc :)

2:32 also, recursions are kinda cool

2:46 rurumate: How to pass command line arguments (like input path) to a cascalog job jar?

2:48 nvm I found it in the cascalog-impatient wiki

3:28 blur3d: is there a version of deref that evals the function if it is not a delay, or derefs it? something like

3:28 (defn do-deref [r]

3:28 (if (delay? r)

3:28 @r

3:28 (r)))

3:50 noidi_: blur3d, AFAIK, you can implement IDeref if you want to create your own derefable objects https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IDeref.java

3:51 TEttinger: blur3d, that function looks perfectly reasonable. I should probably learn more about delays

3:51 noidi_: ,(let [x (reify clojure.lang.IDeref (deref [this] "lol"))] @x)

3:51 clojurebot: "lol"

3:53 noprompt: just wrote a wrapper around BreakIterator. bleh.

3:54 first cut: https://www.refheap.com/22037

3:54 bleh

3:59 i'm probably never going to use it.

4:02 blur3d: noidi_ TEttinger:kk, cheers

4:07 dyreshark: can anyone recommend a solid, idiomatic clojure codebase to read?

4:09 vijaykiran: dyreshark: https://github.com/Datomic/codeq perhaps ?

4:09 TEttinger: dyreshark, I can't say much about how idiomatic it is, but lazybot is certainly fun to work with, and it uses a lot of clojure features (from the written-early parts of the language)

4:11 dyreshark: vijaykiran: TEttinger: cool, i'll look into them. thanks :)

4:12 sm0ke: any one tried vertx adapater for ring?

4:13 clojure seems to be lagging behind in http://www.techempower.com/benchmarks/#section=data-r8&hw=i7&test=db

4:13 round 8 web framework benchmarks

4:14 also is there a grizzly ring adapter?

4:25 TheBusby: Any creative ways to produce a sorted-map which has random order? (just need to shuffle it once)

4:30 sm0ke: TheBusby: what do you mean by sorted-map with random orders?

4:32 clgv: TheBusby: sorted-map and random order sound pretty much mutually exclusive ;)

4:32 TheBusby: is sorted-map the only mechanism to create a map in one specific order?

4:32 TEttinger: sorted-map-by ?

4:32 ,(doc sorted-map-by)

4:32 clojurebot: "([comparator & keyvals]); keyval => key val Returns a new sorted map with supplied mappings, using the supplied comparator. If any keys are equal, they are handled as if by repeated uses of assoc."

4:33 TheBusby: (sorted-map-by get-rand-boolean-value ...) ?

4:34 clgv: TheBusby: that might not work if you desire a uniform random distribution

4:34 TheBusby: that was my first though, then shuffle and array-map?

4:34 clgv: TheBusby: you could create a random permutation and use that for sorting

4:37 TheBusby: clgv: so shuffle the map, then turn it into an array-map to preserve the random ordering?

4:37 clgv: TheBusby: ##(let [m {:a 1 :b 2 :c 3 :d 4}, order (zipmap (keys m) (shuffle (range (count m))))] (into (sorted-map-by order) m))

4:37 lazybot: java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.util.Comparator

4:38 clgv: ah damn comparator instead of attribute^^

4:39 TheBusby: ,(apply array-map (flatten (shuffle (seq {1 1 2 2 3 3}))))

4:39 clojurebot: {2 2, 3 3, 1 1}

4:39 clgv: ,(let [m {:a 1 :b 2 :c 3 :d 4}, order (zipmap (keys m) (shuffle (range (count m))))] (into (sorted-map-by #(< (order (key %1)) (order (key %2)))) m))

4:39 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry>

4:39 clgv: TheBusby: no. do not rely on the order of the arraymap since it is automatically converted to a persistenhashmap when growing beyond a certain size

4:40 TheBusby: clgv: excellent point, but hopefully I wont encounter that issue as I'm immediately converting the array-map to EDN, JSON, or XML

4:41 taruti: What is the right way to "pr" a byte-array so that it can be read back?

4:41 clgv: TheBusby: well, then just try. why do you need it to be ordered randomly then?

4:41 TEttinger: TheBusby, have you seen the lib Ordered?

4:42 https://github.com/flatland/ordered

4:42 TheBusby: clgv: hopefully to keep developers from depending on the order of fields. :)

4:42 TEttinger: no, looking now!

4:42 clgv: TheBusby: o_O

4:42 TEttinger: they might use some trick that you would find useful

4:43 TheBusby: TEttinger: would the advantage of order-map over array-map be the issue of assoc/dissoc that clgv mentioned?

4:43 TEttinger: ordered's maps are basically the same as Java's TreeMap s, just persistent?

4:44 no, http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html

4:45 I don't know why it needs to be random though

4:46 TheBusby: yeah... Just trying to make the dev API simulate all the different possible types of responses to break developer code before they release it.

4:46 TEttinger: if you just want to rearrange the order of fields to discourage wrong assumptions, ##(sorted-map-by (fn [l r] (- (rand-int 1000) 500)) :a 1 :b 2 :c 3) would work

4:46 lazybot: ⇒ {:a 1, :b 2, :c 3}

4:46 TheBusby: changing field orders, JSON/XML encoding tricks, etc

4:46 TEttinger: pfft

4:46 ##(sorted-map-by (fn [l r] (- (rand-int 1000) 500)) :a 1 :b 2 :c 3)

4:46 lazybot: ⇒ {:b 2, :a 1, :c 3}

4:46 TEttinger: there we go

4:47 TheBusby: TEttinger: as clgv was good to point out though, that doesn't ensure an even distribution

4:47 TEttinger: but I don't think you need one

4:47 dav: did the algebraic data types code get lost when the contribs got split into several packages? (https://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/types.clj)

4:48 clgv: TheBusby: I think your motivation for the whole taks is quite bizarre

4:48 $contrib

4:48 TEttinger: ~contrib

4:48 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

4:48 TheBusby: clgv: I found developers "grep'ing out" data from a JSON response already...

4:48 clgv: TheBusby: why is it your task to forbid that?

4:49 TheBusby: clgv: if we make changes in the future, it'll break their code

4:49 clgv: in a perfect world, they'd be responible for their own poorly implemented code; and yet 800 pound gorilla's...

4:49 clgv: TheBusby: but only because they use it wrongly. is it really your task to ensure they are doing it right?

4:50 if you start there you'll end up doing a lot of strange things to ensure they are using the service right

4:51 TheBusby: I used to feel the exact same way, now I'm willing to do a little effort if it'll head-off potential problems

4:53 TEttinger: you know... you could just reverse it at random

4:54 TheBusby: TEttinger: yep, that works too ;)

4:54 clgv: TheBusby: well just go with the array-map approach if you serialize it directly without modifications

4:55 TEttinger: ##((rand-nth [identity reverse]) sorted-map :a 1 :b 2 :c 3))

4:55 lazybot: clojure.lang.ArityException: Wrong number of args (7) passed to: core$reverse

4:55 TheBusby: okay, thanks for the heads up about distribution and the pointer to ordered-map! ;)

4:55 TEttinger: ##((rand-nth [identity reverse]) (sorted-map :a 1 :b 2 :c 3))

4:55 lazybot: ⇒ {:a 1, :b 2, :c 3}

4:57 TEttinger: err no ##((rand-nth [reverse]) (sorted-map :a 1 :b 2 :c 3))

4:57 lazybot: ⇒ ([:c 3] [:b 2] [:a 1])

4:58 TEttinger: apparently reverse and rseq will both return a seq not a sorted-map

5:00 sm0ke: i have (defn ring-handler [] (handler/site #'myroutes)) in my code which i add to project.clj :ring {:handler myns/ring-handler}

5:00 but i seem to be getting clojure.lang.ArityException

5:00 for every route i try

5:01 wtf is this

5:02 TEttinger: arity exceptions are just you passed the wrong number of args to some fn

5:02 does it give a line number?

5:02 broquaint: sm0ke: I think you want def rather than defn there.

5:03 sm0ke: broquaint: just tried that to no use

5:03 TEttinger: and of course you'd take out the [] for def

5:04 clgv: gists with code and stacktraces for the win ;)

5:04 sm0ke: TEttinger: hehe :P

5:05 forgot to take out the []

5:07 where do i specify these options? https://github.com/weavejester/lein-ring#web-server-options

5:08 mercwithamouth: anyone here have any medium sized projects that use enfocus?

5:08 clgv: mercwithamouth: better ask your question directly^^

5:08 bvdeenen: hi all, I'm looking for a way to limit the number of digits of a float that's shown in the repl. Any tips ?

5:08 sm0ke: fuck i never knew lein ring server is so awesome for development!

5:08 it has hot swap

5:09 mercwithamouth: clgv: no question...i just wanted to look over someones project to see how they structure their code =P

5:09 clgv: bvdeenen: you probably have to overide print-method for floats

5:09 TEttinger: there's a way, let me check

5:09 clgv: bvdeenen: or if you explicitely output them you can use `format`

5:09 mercwithamouth: sm0ke: hah i didn't know it allowed hot swapping either. c00l beanz

5:10 bvdeenen: no,no, it's just for during development of a function

5:10 I know about format

5:11 TEttinger: there's http://clojuredocs.org/clojure_core/clojure.core/with-precision

5:11 but that's for BigDecimals

5:12 bvdeenen: yeah, I found that already. I am developing some math functions that return float sequences, and my screen just fills up like mad

5:12 TEttinger: floats shouldn't be very long, hm?

5:13 bvdeenen: So it would be nice if I could just limit the number of digits the repl shows. I guess I'll go have a look at overloading core/print-method

5:13 Well each float is about 15 characters, and my function returns a vector of 50 :-)

5:13 Oh worse, 50 vectors of 3 floats

5:14 Anyway, I'll check on print-method, thanks for thinking along....

5:14 TEttinger: http://clojuredocs.org/clojure_core/clojure.core/*print-length* ?

5:14 that's what clojurebot uses

5:14 ,(repeat 7)

5:14 clojurebot: (7 7 7 7 7 ...)

5:15 bvdeenen: yep that works, it helps.

5:17 I'll see if I can add this to clojure.core/print-method, maybe even suggest it as a patch, with a *print-round* global

5:17 clgv: bvdeenen: you can just set *print-length* and *print-level* in your REPL

5:18 bvdeenen: print-method would be only for using format to limit the decimal places shown

5:19 bvdeenen: Yep, I'm using *print-length* now, that helps, but I still like the idea of having a global rounding constant for floats in the repl

5:19 clgv: bvdeenen: that's the approach I meant (defmethod print-method Float [v ^java.io.Writer w] (.write w (format "%.3f" v)))

5:19 similar for Double

5:20 bvdeenen: Cool! thanks for the tip

5:20 clgv: bvdeenen: you could also use a dynamic variable for the number of decimal places there

5:21 bvdeenen: He dude, you just created my patch! Just add it to clojure.core please, and everone is happy... :-)

5:21 clgv: bvdeenen: no certainly not. since this influences text serialization ;)

5:22 bvdeenen: oh :-(

5:22 clgv: pr-str and such use print-method as well

5:24 bvdeenen: That's too cool, it works, ok now I'll try to figure out how it works, because I'm new to clojure

5:25 seriously_random: is there tuple assignment like in python?

5:25 clgv: seriously_random: Clojure has destructuring if that is what you mean

5:26 dav: Is there no decent algebraic data type library for clojure?

5:26 clgv: ,(let [[a b c] (range)] [c a b])

5:26 clojurebot: [2 0 1]

5:27 clgv: dav: what do you want to do?

5:28 dav: clgv: pattern matching on algebraic data types

5:29 clgv: as done here: https://code.google.com/p/clojure-contrib/source/browse/trunk/src/clojure/contrib/types/examples.clj?spec=svn596&r=596

5:29 clgv: except clojure-contrib was disbanded and it seems to me that this code is gone

5:29 clgv: dav: there is core.match for pattern matching

5:29 dav: clgv: it seems to pattern match values.. that's not very interesting

5:30 clgv: I'd want to pattern match type constructors

5:31 I guess I can probably reproduce the functionality with map matching

5:45 broquaint: There's a subtlety here I'm not appreciating and could do with some enlightenment - https://gist.github.com/broquaint/8037288

5:53 Oh I think it's the REPL not knowing how to stringify it.

5:54 seriously_random: how to write the following for loop in clojure: http://pastebin.com/1WcjHa90

5:55 sm0ke: broquaint: thats weird there is a default toString for EVERY Object in java which prints the object reference

5:57 broquaint: working with java apis which do not have Builder patterns is ugly in clojure

5:58 as a sidenote

6:04 broquaint: Duly noted, sm0ke :)

6:09 daGrevis: did I do this koan correctly? "One function can beget another"

6:09 (= 9 (((fn [] #(+ %1 %2))) 4 5))

6:09 yodas?

6:20 clgv: daGrevis: what is filled in? otherwise I'd say (= 9 (+4 5)) is simpler ;)

6:21 daGrevis: clgv, it would be simpler, but I would count is as cheating

6:22 clgv: daGrevis: why?

6:22 daGrevis: beacuse u r just ignoring 4 5 that are passed to the function as arguments

6:22 elegant cheating :P

6:22 clgv: daGrevis: I dont know what the exakt exercise is. no + does not ignore 4 5 ;)

6:22 daGrevis: clgv, can you show me full example of your code?

6:23 clgv: as said above, I have no clue what part of the expression is fixed and where exactly you need to fill in something

6:23 uday: Hi, We are using core.match for pattern matching. And we want to match a set instead of a vector or sequence like this [([1 2 3 4] :set)]. Can you someone suggest us how we can implement our own matchers like this?

6:24 clgv: uday: in case you get no answer very soon, try to ask dnolen in several hours

6:26 daGrevis: clgv, https://github.com/functional-koans/clojure-koans/blob/master/src/koans/06_functions.clj#L26

6:26 you need to fill ___

6:26 uday: clgv: Sure. Thanks

6:26 daGrevis: you could just fill it with 9 and it will pass

6:26 clgv: daGrevis: ok then I'd use (= 9 (((fn [] +)) 4 5))

6:27 daGrevis: no you couldnt

6:27 daGrevis: :/

6:27 * daGrevis goes back to repl

6:27 clgv: ,(= 9 (((fn [] 9)) 4 5))

6:27 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

6:27 clgv: see ;)

6:27 ,(= 9 (((fn [] +)) 4 5))

6:27 clojurebot: true

6:28 daGrevis: clojurebot, ye, cool

6:28 clojurebot: I don't understand.

6:28 daGrevis: whoops

6:28 i got to ask, why 9 doesn't work?

6:29 , (= 9 (((fn [] 9)) 4 5))

6:29 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

6:29 clgv: because 9 ist not a function but it called as one

6:29 ,(= 9 (((fn [] (constantly 9))) 4 5))

6:29 clojurebot: true

6:29 daGrevis: clgv, is + a function?

6:29 clgv: ;)

6:29 yes

6:29 daGrevis: , (= 9 (((fn [] '9)) 4 5))

6:29 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

6:29 clgv: + is a symbol which is resolved to the function that adds numbers ;)

6:29 daGrevis: for something sake ;D

6:30 clgv: daGrevis: using (constantly 9) works in that case since it creates a function that always returns 9

6:30 daGrevis: clgv, why doesn't '9 work?

6:30 clgv: daGrevis: it is no function

6:30 ,(type '9)

6:30 clojurebot: java.lang.Long

6:31 daGrevis: i thought ' had a special meaning

6:31 clgv: daGrevis: yeah, it is a shortcut for (quote ...)

6:31 daGrevis: , (= 9 (((fn [] '9)) 4 5))

6:31 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

6:31 daGrevis: whoops

6:31 clgv: but that does not create functions ;)

6:31 daGrevis: ok, til and gotta learn a lot more

6:31 thanks :)

6:33 clgv: daGrevis: you got a book or know about clojure-doc.org?

6:33 daGrevis: clgv, currently im walking throught the koan

6:34 i have some knowledge in programming ;)

6:34 python, a bit of haskell

6:34 gotta get book! \o/

6:34 clgv: daGrevis: reading about the concepts of the language will speed up your progress ;)

6:35 daGrevis: clgv, any suggestions?

6:35 i mean, for book

6:35 clgv: daGrevis: "Clojure Programming" is quite recent. I read a few chapters of it which were well written

7:08 casperc: s

7:23 seriously_random: from index 1 to 2 in '(1 2 3 4 5) => (2 3) - how?

7:25 daGrevis: clgv, thanks for book suggestion ;)

7:26 clgv: seriously_random: ##(->> (range 1 6) (drop 1) (take 2)

7:27 ups

7:27 ,(->> (range 1 6) (drop 1) (take 2))

7:27 clojurebot: (2 3)

7:44 seriously_random: I don't want to sound intrusive, but could someone show something like this: http://pastebin.com/1WcjHa90 is done in clojure

7:47 I guess I could use destructure, "let [[a b c] '(1 2 3)]". But that will only work if sequence is fixed size

7:48 jballanc: seriously_random: in your pastebin you say "hashset", but sets are inherantly unordered

7:48 did you mean a seq or vec?

7:49 seriously_random: hashset is original input, I guess I convert it to sequence first

7:49 skipping words, not a good sign :)

7:50 jballanc: so, yeah, you could make it a seq

7:50 '(seq #{1 2 3 4})

7:50 whoops

7:50 ,(seq #{1 2 3 4})

7:50 clojurebot: (1 2 3 4)

7:50 clgv: seriously_random: since it is swapping back and forth there is no clear functional result. is it only supposed to do the printing side effect?

7:50 jballanc: but if you want to swap, you probably want a vec

7:51 seriously_random: would vec simplify the task?

7:51 clgv: seriously_random: what is the task? printing the original sequences with the 3 swaps?

7:52 seriously_random: clgv, 1234, 2134, 3214, etc (swapping with index 0)

7:54 clgv: ,(let [v [1 2 3 4]] (dotimes [i 3] (let [i (inc i)] (println (assoc v 0 (v i) i (v 0))))))

7:54 clojurebot: [2 1 3 4]\n[3 2 1 4]\n[4 2 3 1]\n

7:54 jballanc: heh...I would've used a for comprehension

7:55 saves a form

7:55 seriously_random: why can't it be something simple, like a, b = b, a in python?

7:55 jballanc: because vectors (and seqs and hashes and sets) in Clojure are immutable

7:55 clgv: seriously_random: persistent data structures, that's why

7:56 this is you a,b = b,a => (assoc v 0 (v i) i (v 0)))

7:57 you could write a separate swap function if it's worth it

7:58 jballanc: actually, since you're only printing the vectors there's not even any need to really do the assoc

8:00 clgv: jballanc: well it is the simplest. traversing the vetor needs more code ;)

8:00 and closer to the semantic in the pseudocode

8:04 jballanc: eh, I guess...

8:05 the pseudocode doesn't really fit with a functional design, though

8:05 seriously_random: here is the actual "pseudocode": http://helloacm.com/a-recursive-full-permutation-in-python/

8:11 clgv: jballanc: thats right. but we could approximate it with `dotimes` in idiomatic clojure ;)

8:12 jballanc: you can do a lot of ugly stuff in clojure :)

8:12 clgv: seriously_random: well there is at least one existing implementation for a lazy sequence of all permutations of a given length...

8:13 it was in the old contrib libs

8:13 jballanc: seriously_random: the article you linked, though, is doing something different than your pastebin

8:14 you were just permuting two positions, but the article you link is doing a full permutation

8:14 that should actually be much easier/clearer to do (recursively, as the article suggests) in clojure

8:17 seriously_random: jballanc, I was aware of not doing a full perm. set. It was more like a practice before the real deal.

8:17 jballanc: well, in this particular case, I think you've made the problem harder by not tackling the whole thing at once

8:18 with clojure (and functional programming in general) it's much better to sit and think about the whole problem than to try and piecemeal it together

8:19 seriously_random: or you could argue that starting from something will lead to some kind of understanding of what it is that you are doing

8:20 jballanc: yeah, but because of clojure's immutable data structures you're going to have a much harder time implementing the half-solution

8:25 clgv: jballanc: I think building solutions to problems bottom-up is pretty normal in Clojure due to the testing abilities in the REPL. but you need to think about howto structure the implementation it the needed functions

8:32 seriously_random: jballanc, http://pastebin.com/wpLWgzF5 - doesn't seem to do the same thing

8:34 one mistake is at dotimes (range)

8:34 clgv: seriously_random: yeah the mistake is that you wanted side-effect only code before and now you want a return value ;)

8:36 mdrogalis: Morning.

8:47 seriously_random: clgv, know anything about for and how println behaves? http://pastebin.com/x0fCMMT2

8:49 stuartsierra: clojurebot: for?

8:49 clojurebot: for is a loop...in Java

8:56 seriously_random: how to avoid deep nesting? http://pastebin.com/5cP2VQ7i

8:57 xsyn: I all

8:57 I'm busy playing with incanter

8:58 and I want to do an intersaection on the two lazy-seqs I've got

8:58 but I can't convert them into sets

8:58 how do I find the values that each lazy-seq has easily

9:03 silasdavis: any recommendations for load testing in clojure?

9:05 fredyr: xsyn: do you need to keep dups, or why not convert to set?

9:05 xsyn: just worked that out

9:05 thanks

9:05 (set (doall (lazy-seq))

9:13 clgv: xsyn: just (set your-lazy-seq) should work as well

9:14 jonasen: Bronsa: ping

9:14 Bronsa: https://github.com/clojure/tools.analyzer/blob/master/src/main/clojure/clojure/tools/analyzer/utils.clj#L85

9:15 Bronsa: that call to 'var?' makes tools.analyzer much less platform agnostic. Is it necessary?

9:21 Bronsa: jonasen: I know, that's something I need to fix before the first release

9:23 jonasen: Bronsa: ok, it's not a real big problem, the ast is returned as ':op :maybe-class' and I can write my own resolve-var pass

9:25 Bronsa: jonasen: FWIW resolve-var will be a dynamic var like create-var. I don't think there's any other option to support arbitrary representation in the ns map

9:28 jonasen: Bronsa: yes, that's probably true. There are a few other places in analyzer.utils where you're using 'var?'. Not sure if that's a problem

9:30 Bronsa: jonasen: no, I don't think those other places will be a problem

9:58 sw1nn: hiredman: Hi, I set up an instance of clojurebot for #ldnclj, but I just noticed that there's some code to invite the clojurebot from here into that channel. Is that something that might be possible?

10:11 romain_p_: Hi everyone, could somebody tell me what is wrong with http://pastebin.com/PkR7P6Rk

10:12 Specifically, I get an error "<! used not in go block"

10:12 clojurebot: Excuse me?

10:14 fredyr: are there any clojurescript alternatives similar to Backbone models?

10:17 jjl`_: what things have metadata attached by default?

10:18 tbaldrid_: romain_p_: not sure, did you :require <! from cljs.core.async?

10:18 and are you importing macros from cljs.core.async.macros?

10:18 `cbp: vars have metadata by default i guess?

10:18 this sounds like some interview question

10:19 jjl`_: heh, i actually do have a use for this information

10:20 `cbp: things that start with def put metadata on the vars, at the very least things like ns, line, file, etc

10:20 pepijndevos: hiring people in usefull

10:21 jjl`_: `cbp: that's what i thought, but i've just defined a function with defn in a lein repl and (meta myfn) returns nil

10:21 `cbp: (meta #'myfn)

10:21 on the var not the function

10:21 jjl`_: aha

10:22 romain_p_: tbaldridge: I am using (require [cljs.core.async :refer [<! >! chan go])

10:23 tbaldridge: romain_p_: remove the go symbol and do this for go instead:

10:23 (:require-macros [cljs.core.async.macros :refer [go]])

10:23 romain_p_: tbaldridge: OK, thanks!

10:23 tbaldridge: romain_p_: in CLJS you have to pull in macros via reqire-macros.

10:23 romain_p_: I was confused about that one

10:23 tbaldridge: *require-macros

10:24 romain_p_: tbaldridge: although it would be nice if the compiler complained, but I guess it cannot be done in such a dynamic language

10:25 pepijndevos: is there a reason for that other than noone bothered reimplementing the macro system?

10:29 stuartsierra: It's more complicated than that.

10:31 The Clojure compiler is partially implemented in Clojure. Macros are part of that.

10:31 The ClojureScript compiler is also implemented in Clojure.

10:31 Macros are a compiler feature that also require the full language runtime.

10:32 In ClojureScript, the language runtime (JavaScript) and the compiler (Clojure / JVM) are separate.

10:33 tbaldridge: My only complaint is that go doesn't exist inside cljs.core.async. So I would expect CLJS to at least warn about that.

10:34 stuartsierra: I think there's a CLJS compiler option for warnings like that.

11:08 dnolen: tbaldridge: romain_p_: there is new sugar now, if you give your macro file the same name as the CLJS file barring extension, :include-macros true works

11:08 also (:require [foo.bar :as bar :refer-macros [woz]])

11:11 lpetit: cemerick: hello

11:11 cemerick: lpetit: hi! :-)

11:12 lpetit: What's up ?

11:12 cemerick: lpetit: not much / a lot, depending. :-)

11:12 lpetit: he

11:30 zerokarmaleft: I'm getting a weird var resolution error, despite it clearly being interned => https://gist.github.com/zerokarmaleft/8042030

11:37 andyf: only on that symbol?

11:40 zerokarmaleft: andyf: afaict, yes

11:40 andyf: And repeatably with a new JVM?

11:42 zerokarmaleft: andyf: my bad, get-all-bids and delete-bid also fail to resolve, get-bid resolves but is unbound

11:43 andyf: yea, just tried with a fresh repl

11:44 andyf: no errors when loading the namespace?

11:45 zerokarmaleft: namespace loads fine

11:46 rukor: zerokarmaleft: out of curiosity, do you justify your namespace declarations by hand or some Emacs magic.

11:47 zerokarmaleft: rukor: a little of column A and a little of column B, but that's mostly enabled by M-x align-regexp

11:50 I wonder if this is some cider/nrepl funkiness

11:51 andyf: worth trying outside on a plain terminal REPL to check, if that isn't too much trouble.

11:51 rukor: Zerokarmaleft: i see, thanks. I also see some docstrings justified. Any ideas on how to achieve that?

11:53 zerokarmaleft: rukor: that's part of clojure-mode, I believe...clojure-fill-docstring

11:57 rukor: Aha, thanks. Perfect. Ive always disliked the default fill mode for docstrings. Thanks

11:57 zerokarmaleft: andyf: same thing

11:57 rukor: np

11:58 andyf: zerokarmaleft: I wish I had something more useful to suggest, but I'm not coming up with anything.

11:58 zerokarmaleft: it's bizarre

11:58 eval'ing directly in the repl creates a working binding

11:59 andyf: does defentity define any other symbols with the substring "bids", like "get-bids", as part of its effect?

11:59 zerokarmaleft: hmm, good question...checking korma docs

12:02 hiredman: zerokarmaleft: that form-init bit in a temp file name is something lein does when first launching a project repl, getting it at the repl like that is very weird, what does your project.clj look like?

12:02 zerokarmaleft: andyf: looks like it just creates a map and binds "bids" to it

12:03 hiredman: zerokarmaleft: what repl are you using?

12:04 zerokarmaleft: hiredman: https://github.com/codesy/patronage/blob/master/project.clj

12:05 hiredman: cider/nrepl

12:08 hiredman: zerokarmaleft: what happens if you remove the init-ns stuff and try to compile the file in a fresh repl?

12:09 zerokarmaleft: hiredman: same error, get-bid-command doesn't resolve when compiling get-bid

12:11 hiredman: zerokarmaleft: I don't think you can use declare like that for defentity, but I don't see how you would get the error you say you are getting from that

12:11 sw1nn: hiredman: did you catch my clojurebot question earlier? basically - can we invite ClojureBot into #ldnclj?

12:11 gfredericks: \j #ldnclj

12:11 slash directions

12:13 hiredman: sw1nn: http://en.wikipedia.org/wiki/List_of_Internet_Relay_Chat_commands#INVITE might work

12:14 zerokarmaleft: maybe you can use declare like that, it does like korma's macros explicitly var the names

12:15 sw1nn: hiredman: I tried it after looking at the code, but there's a flag :on-invite which may not be set?

12:15 hiredman: zerokarmaleft: what happens if you run java -classpath `lein classpath` clojure.main, then require your namespace?

12:16 zerokarmaleft: hiredman: same error

12:16 hiredman: sw1nn: ah, well

12:17 zerokarmaleft: unlikely, given as I said the form-init bit is lein specific

12:17 zerokarmaleft: hiredman: the context is the actual source file instead of a temp file

12:17 but it's the same var resolution error

12:22 andyf, hiredman: gotta come back to this later, thanks for the suggestions

12:24 hiredman: zerokarmaleft: looking at the code in the patronage repo, there is no get-bid-command in that file

12:26 zerokarmaleft: you have an extra m in your defn

12:31 dnolen: ok so in Om if we decomplect the data path and the render path we can have Datomic style queries to compute children instead of having to write silly functional code for it

12:38 pepijndevos: dnolen, whats Om?

12:39 dnolen: pepijndevos: https://github.com/swannodette/om

12:39 tbaldridge: dnolen: pedestal has a 120 line datalog engine you could also snag. or do the queries in core.logic.

12:39 pepijndevos: ah

12:39 dnolen: tbaldridge: excellent

12:40 tbaldridge: dnolen: it's super basic, but it works almost exactly like datomic's q fn https://github.com/pedestal/pedestal/blob/master/app/src/io/pedestal/app/query.clj

12:41 dnolen: tbaldridge: excellent I just want something simple

12:41 tbaldridge: this won't be a bottleneck at all, and people will be able to write beautiful queries instead of writing the same tedious map filter reduce ops over and over again.

12:42 tbaldridge: dnolen: nice.

12:43 pepijndevos: uuh, looking at react now. it has embedded xml!?

12:43 dnolen: pepijndevos: HTML, and it's optional

12:44 pepijndevos: I see... weird

12:44 dnolen: pepijndevos: the website isn't very informative, what is awesome about React is the virtual DOM diffing and the event simulation

12:44 which is what most of the React code is actually about

12:44 cark: dnolen : so Om redraws everything when there's a change in the "dom" ?

12:44 dnolen: cark: no

12:44 cark: Om doesn't do any rendering, React does it will only update what actually changed

12:45 cark: dnolen: ah ok

12:45 pepijndevos: :include-macros true? hmmm

12:45 dnolen: cark: however Om can drive the React lazy diffing process from the root very efficiently because our data is immutable.

12:46 cark: i'm not familiar with react, maybe i should have a look to it

12:47 kmicu: dnolen: Can you estimate how much work is needed for GClosure Adv. Comp. Friendly React.js ?

12:47 dnolen: kmicu: no idea but I don't really care about that.

12:47 kmicu: linking to a CDN for dev and :preamble for production works fine

12:48 cark: I've got a post coming out later today with lots of details

12:48 kmicu: Finally.

12:48 :)

12:48 dnolen: cark: CLJ/CLJS will get it immediately.

12:48 CLJ/CLJS users

12:49 scottj: Are there docs on #js for cljs?

12:49 cark: do you mean it will be included in with clojurescript ?

12:49 dnolen: scottj: not but it I don't see why there needs to be

12:49 cark: no

12:49 scottj: #js {} for objects #js [] for arrays, that's it

12:57 gfredericks: what does #js [{}] do?

12:57 dnolen: gfredericks: an array with a map in it

12:58 gfredericks: a js obj or a cljs map?

12:58 dnolen: gfredericks: the behavior of #js has been through quite a bit

12:58 gfredericks: #js isn't magical

12:58 s/through/thought through

12:58 gfredericks: dnolen: I'm just pointing out that it isn't obvious

12:59 dnolen: gfredericks: it is if you think about it

12:59 eggnoggin: it'd just return a js literal like [{}] tho right?

12:59 dnolen: eggnoggin: no, think about it some more

12:59 and why that's a really bad idea

13:00 gfredericks: something being a bad idea doesn't mean it can be ruled out in the absence of documentation

13:01 eggnoggin: a clojure vector where the 0th elem is a clojure map coerced to js ... wouldn't that be the same as typing [{}] in the js repl?

13:01 dnolen: gfredericks: I think people will figure it out pretty quickly. It should be documented and anyone can do that.

13:01 eggnoggin: aaah

13:01 gfredericks: dnolen: okay, I thought you had said it shouldn't be documented; my mistake

13:01 eggnoggin: so you'd write #js [#js {}]

13:01 dnolen: gfredericks: far as I know hardly any of the tagged literal stuff in CLJS is documented at all

13:01 eggnoggin: is that?

13:01 dnolen: eggnoggin: yes

13:01 eggnoggin: but wouldn't #js [{}] recursively coerce down to the js literals?

13:02 dnolen: eggnoggin: absolutely not

13:02 CookedGryphon: in core.async, is it possible to do an alts style statement but where I'm waiting on events *in* from one channel, or the capability to push an event to another channel?

13:02 tbaldridge: CookedGryphon: yep, look at the docs to alt! you can mix and match

13:02 http://clojure.github.io/core.async/#clojure.core.async/alt!

13:03 also: http://clojure.github.io/core.async/#clojure.core.async/alts!

13:03 CookedGryphon: tbaldridge: ah, I've only ever used alts!, I couldn't work out what the docstring for alt! was going on about

13:06 okay, I *think* I get what's going on...

13:06 justin_smith: I think alt! is like the equivalent of (let [chan val] (alts! [chan1 chan2 chanN]) (case chan ...)) -> (alt! chan1 ... chan2 ...)

13:16 noprompt: bitemyapp: omfg

13:32 jcromartie: so, I had previously had a nice prevalent system design going on, but now I have a requirement to have load balancing between two servers

13:33 now, there is no actual need to balance the load, but they want failover between VM instances in case one goes down

13:34 eggnoggin: jcromartie: are both of your apps stateless between requests? just use a reverse proxy

13:36 jcromartie: No, since I use a event sourcing design with state in memory

13:36 I can just as easily move state outside

13:37 so long as transactions are still possible

13:37 that means MongoDB is right out

13:37 pepijndevos: what if the load balancer goes down...

13:37 justin_smith: avout can help - it defines refs / atoms that are transperently shared between instances

13:38 jcromartie: justin_smith: nice!

13:38 justin_smith: with standard atom / ref semantics

13:39 depending how you were storing state that can make any changes to go from single instance with in-memory state to cluster a very smooth transition

13:39 jcromartie: it might be a little tricky if the different front ends have different versions of the app though

13:39 justin_smith: though it provides an incentive to make more small atoms/refs with separate parts of state, instead of one big one

13:40 jcromartie: yeah I am using a ref for state with an agent to write events right now

13:40 pepijndevos: how does it perform?

13:40 avout

13:40 justin_smith: I haven't used in in production yet

13:40 it can be backed by zookeeper

13:40 which is designed for low latency

13:41 but I should really load-test it

13:41 jcromartie: this might really be overkill though

13:42 pepijndevos: if you kill a fly with a shotgun, it still dies...

13:42 clojurebot: No entiendo

13:45 danielszmulewicz: whois gf3

13:45 sorry

13:45 justin_smith: avout is pretty lightweight - it is basically a keystore/message queue attached to standard clojure mutation protocols

13:46 WWWest: Hi

13:46 I just updated to clojurescript "0.0-2120", now my project takes ~15secs instead of 4 on every change with lein cljsbuild auto

13:46 is this normal?

13:49 danielszmulewicz: WWWest: most certainly not

13:49 WWWest: I also added core.async

13:49 tbaldridge: justin_smith: avout also has some fairly bad flaws

13:50 danielszmulewicz: WWWest: Each version bump is supposed to bring performance improvement, if not, it might be a regression.

13:50 WWWest: but I have 2 go's and 3 >!, <!

13:50 tbaldridge: justin_smith: https://github.com/liebke/avout/issues/1

13:51 justin_smith: ouch

13:51 jcromartie: tbaldridge: that's quite an issue, #1 from a year ago, still open?

13:51 justin_smith: luckily I am not counting on watches

13:52 mdrogalis: Avout not allowing you to read-every-write has burned me.

13:53 Yeah, the ZK-watch thing.

13:53 pepijndevos: It seems to be a "feature"

13:53 tbaldridge: yeah, the lib is based on some flawed views of ZK and as such has basically been discontinued.

13:53 justin_smith: it looks like that is a limitation of the underlying zookeeper

13:53 mdrogalis: So I don't know if ZK itself considers them flaws.

13:54 justin_smith: flawed views as in the implementors do not understand zookeeper sufficiently? or the premise of the lib is based on a flawed understanding of zookeeper

13:54 tbaldridge: The problem is that ZK detaches watchers after each change. So if you attach a watch, then read the value then re-attach the watch you have a race condition.

13:54 mdrogalis: The ZK docs say that "it's just something you need to account for."

13:56 patchwork: The issue is that zookeeper behavior does not map to clojure watches

13:56 So you can't expect watches on avout refs to have the same behavior as watches on regular clojure refs

13:56 pepijndevos: fu, distributed systems...

13:57 mdrogalis: Has anyone used something like ZK that doesn't have that oddity?

13:57 tbaldridge: eh, just use locks/transactions inside a machine and use other systems (message passing) outside machines.

13:57 patchwork: Leaky abstractions, yadda yadda

13:57 mdrogalis: Easier said than done, tbaldridge. At least I think so.

13:58 tbaldridge: true, it takes rethinking about your problem. But that's better than trying to get a distributed lock to work.

13:58 patchwork: So, avout is good for distributed state, but not message passing?

13:59 mdrogalis: patchwork: It's not so good for observing every change to a piece of state.

13:59 tbaldridge: I wouldn't use it for anything to be honest. It's been like 2 years since any updates were made to it.

13:59 mdrogalis: In fact - it can't.

13:59 patchwork: It seems if you want to see every change, you really want a message passing system

13:59 mdrogalis: Yeah.

13:59 patchwork: tbaldridge: So what about zookeeper in general then?

13:59 mdrogalis: I mean, it's emphemeral node feature is pretty great.

14:00 patchwork: Is avout just a bad abstraction over a good library, or is ZK itself basically flawed?

14:00 tbaldridge: No, ZK is fine for stuff like configs. I just have an issue with storing anything else in it. I wouldn't try to go and keep my application state in ZK.

14:00 patchwork: As in, maybe we need a different clojure library for zookeeper then?

14:00 tbaldridge: Now perhaps I'd keep a uuid in ZK that pointed to a datastructure on disk somewhere.

14:01 I've used this: https://github.com/liebke/zookeeper-clj

14:02 it works "okay" a bit temperamental. But it works fine for storing configs

14:02 patchwork: last modified 2 years ago as well!

14:02 tbaldridge: yeah

14:02 patchwork: same guy too right?

14:02 Interesting

14:02 tbaldridge: It all depends what you're wanting to do with it.

14:03 mdrogalis: Yeah, agreed.

14:06 tbaldridge: What else would you recommend if you needed CAS but didnt want ZK?

14:07 tbaldridge: ZK is fine for CAS or configs. I'm just saying I wouldn't recommend storing tons of state in ZK. Which Avout seems to be about (e.g. mapping refs to ZK).

14:08 mdrogalis: tbaldridge: Yeah, true.

14:08 Ah, right. There was a list in that ACID article about which storage engines supported CAS.

14:08 More than I expected

14:09 stuartsierra: The Java ZooKeeper API isn't difficult.

14:09 dnolen: Om post is up feel free to give it some HN love - https://news.ycombinator.com/newest

14:09 jcromartie: distributing state just sounds like a bad idea to me

14:09 so querying the db it is

14:09 dnolen: also the React 0.8 is worth upvoting they've been super nice

14:10 mdrogalis: stuartsierra: Agreed.

14:10 noncom: keywordize-keys works fine on multilevel maps, however, what if at some level there is a record and not a map? the keys do not get keywordied.. anyone knows a way around it?

14:12 stuartsierra: noncom: There's a patch already applied on Clojure 1.6 that lets `clojure.walk` support records.

14:13 noncom: stuartsierra: nice! but it is still in alpha.. maybe you could recommend a way to go then? :)

14:13 stuartsierra: copy-and-paste?

14:14 It's open-source, after all.

14:14 noncom: cool! gonna do it right away!

14:15 stuartsierra: If you're interested, https://github.com/stuartsierra/clojure.walk2 is more thorough. I've also submitted that as a Clojure patch.

14:15 jcromartie: so I threw together a fun little thing that runs "tasks" with rollback

14:15 I am not sure I can open source it yet, gotta get that cleared up

14:15 but it's for doing things with side effects that may need to be rolled back

14:15 and it supports vectors and sets as shorthand for sequential and parallel groups of tasks

14:15 so you can say: (perform [a #{b c d} e]) which will perform a first, then b c and d in parallel, and then e

14:16 noncom: stuartsierra: thank you, I will looks into the sources

14:16 mikerod: stuartsierra: I'm a fan of walk2

14:17 jcromartie: and, if any of them fail, everything that was completed is rolled back, which for collections means calling rollback on each completed member task

14:17 yedi: dnolen: how dare you post your own blog post

14:17 noncom: mikerod: sounds promising :)

14:17 yedi: i wanted to reap the karma benefits

14:17 mikerod: The docs say "This repo is for demonstration only." in walk2

14:18 jcromartie: to define tasks that can roll back you can specify a map like {:up #() :down #()} or you can defrecord and implement perform/rollback

14:18 mikerod: However, I've had no issues and do not see any.

14:18 You can even extend the protocol for Java-land Collections

14:20 noncom: mikerod: will it go to 1.6?

14:21 stuartsierra: The ticket is http://dev.clojure.org/jira/browse/CLJ-1239 if you want to keep track.

14:23 bitemyapp: MFW hoplon doesn't use leiningen.

14:24 stuartsierra: is that RestFn patch going to get merged?

14:24 the one Bloom was championing.

14:24 stuartsierra: bitemyapp: I don't know

14:24 mikerod: which patch is this?

14:24 noncom: yeah, i think it is a ery useful patch

14:25 s/ery/very

14:25 SegFaultAX: How useful? Ery useful.

14:25 bitemyapp: noprompt: I was thinking about data structures for frak.

14:25 noprompt: ever done anything with finger trees or PATRICIA tries?

14:26 or rather, for Frak++.hs

14:26 mikerod: noncom: What is the RestFn patch? Is there an issue related to it?

14:27 bitemyapp: noprompt: https://github.com/quchen/articles/blob/master/loeb-moeb.md

14:28 SegFaultAX: Speaking of finger trees... when will we be getting them in Clojure? :)

14:29 noncom: mikerod: i mean walk2. i do not know anything about RestFn... ?

14:29 stuartsierra: SegFaultAX: https://github.com/clojure/data.finger-tree

14:29 mikerod: oh :)

14:29 yes, an ery useful patch indeed.

14:30 SegFaultAX: stuartsierra: Think it'll ever make it to core?

14:30 octagon: bitemyapp: you're right, hoplon doesn't use lein!

14:30 stuartsierra: SegFaultAX: Not unless something in core needs it. We want to make clojure.core smaller, not bigger.

14:31 bitemyapp: octagon: are you the proud author?

14:32 SegFaultAX: finger trees are a bit tedious in a strict language.

14:32 stuartsierra: is there a canonical post for ML functors in protocols? I have a utility bag that I'd like to publish for Datomic that would benefit from it.

14:32 octagon: bitemyapp: i'm Micha

14:32 stuartsierra: If anyone has a good benchmark that demonstrates a consistent, repeatable performance improvement from the patch on CLJ-1200, I would like to have it.

14:32 bitemyapp: octagon: I don't know who that is.

14:32 octagon: bitemyapp: i wrote it with alan dipert

14:33 bitemyapp: short answer: yes

14:33 * bitemyapp makes some scratches in his notepad of Leiningen defectors

14:33 octagon: bitemyapp: i still use leiningen too

14:33 jcromartie: I was accidentally running 2 instances of "yes > /dev/null &" which happens to be exactly how they used to recommend maxing out your MacBook and getting it super hot

14:33 bitemyapp: octagon: hot.

14:33 octagon: bitemyapp: leiningen just isn't good for some things

14:34 bitemyapp: octagon: by all means, explain.

14:34 octagon: bitemyapp: basically, the idea is that tasks could be middleware like in a ring app, instead of plugins, profiles, tasks, and middleware in lein

14:35 bitemyapp: octagon: leiningen has hooks for that.

14:35 octagon: bitemyapp: the priority is for boot tasks to be composable

14:35 bitemyapp: boot has only one "watch" task, for instance, that you can compose with any other task

14:35 bitemyapp: octagon: they're designed around the same principle.

14:35 octagon: yes, you can do the same in Leiningen.

14:36 octagon: bitemyapp: we originally made a lein plugin, but it got unworkable pretty fast

14:36 bitemyapp: when it had to compose with lein-cljsbuild and various other things

14:37 bitemyapp: tbaldridge: the edn parsing situation is getting bad enough that we're considering layering an edn protocol on top of JSON.

14:38 every little thing is breaking, none of the edn readers/parsers in Python are workable.

14:38 logic_prog: is there a way to write a websocket _client_ in clojure/java rather than cljs/javascript ?

14:38 I want to write a _client_ to stress test my websocket server

14:38 tbaldridge: bitemyapp: seems that a little time with pyparsing or parsley would get you want you want.

14:38 bitemyapp: logic_prog: yeah, although that'd be weird.

14:38 tbaldridge: well, that "little time" is what already exists and those libraries are broken.

14:38 tbaldridge: I've been incrementally fixing edn_format but I'm losing my patience with it.

14:38 jcromartie: logic_prog: you can open as many websockets as you want from JS

14:39 logic_prog: yeah, but I want to write my testing code in java

14:39 s/java/clojure

14:39 noncom: you can use a JS on JVM

14:39 :)

14:40 logic_prog: I would need JVM on JS

14:40 noncom: you could try using rhino or such..

14:40 yeah, i am mostly joking. it's just that i had the same request some time ago

14:40 bitemyapp: tbaldridge: the edn spec being wrong combined with the terrible, terrible libraries out there makes using Datomic outside of Clojure incredibly painful.

14:40 jcromartie: Jetty has a websocket client library

14:41 http://www.eclipse.org/jetty/documentation/current/jetty-websocket-client-api.html

14:41 bitemyapp: tbaldridge: we've lost a lot of hours to this already.

14:41 but the edn spec errors really just digs the knife in.

14:41 jcromartie: logic_prog: I think that's your answer

14:41 include require org.eclipse.jetty.websocket/websocket-client in your dev dependencies and test away

14:41 cespare: Didn't nigel (or was it someone else?) send out a proposal for two-valued math functions (like quo, rem := n / d) a while ago?

14:41 logic_prog: jcromartie: very nice, thanks

14:42 cespare: I can't find the thread on golang-dev

14:42 tbaldridge: bitemyapp: that's the part that I'm wondering about. What spec errors are referring to? And if every single Python lib breaks, I'm wondering why.

14:42 bitemyapp: tbaldridge: the Python libs break because they're incredibly naive and untested. The edn spec is wrong about what's allowed in a symbol

14:43 tbaldridge: and its over-restrictiveness relative to what Clojure actually allows in the implementation breaks code that we needed to actually use with Clojure/Datomic.

14:43 tbaldridge: what symbols are being sent from Datomic?

14:43 bitemyapp: I don't really have time for this right now

14:43 if the divergence between the edn spec and what Clojure allows isn't disconcerting already, then you're not thinking ahead very far.

14:45 noprompt: garsh darn internet connection...

14:45 bitemyapp: noprompt: w/b

14:45 noprompt: bitemyapp: no sir, i can't say i have.

14:45 cespare: oops wrong chan, sorry

14:45 bitemyapp: noprompt: well I was just thinking about the data structures, tries vs. finger trees, that sort of thing - for Frak.

14:45 noprompt: also I was pondering a reverse Frak.

14:45 jcromartie: are there really advantages to "lein ring server" vs just having a main namespace with a fn that starts your app?

14:45 tbaldridge: I'm just saying, we use stuff like ruby edn quite a lot and haven't had these issues, so I'm wondering what the difference is. For example, Diametric works great with the REST frontend.

14:45 jcromartie: I really don't like having a top-level handler

14:45 bitemyapp: jcromartie: no advantages, just more muggle compatible.

14:46 jcromartie: I see

14:46 I thought that might be the purpose

14:46 noprompt: bitemyapp: yeah i've been interested in that as well. ultimately it would be nice to write a regex parser or an api for constructing regex.

14:46 technomancy: jcromartie: I don't see the point either

14:48 noprompt: i discovered this week i'm going to be a father. looks like i'll be reading technomancy's blog more often.

14:48 bitemyapp: noprompt: wat.

14:48 technomancy: noprompt: oh nice; congrats.

14:48 bitemyapp: noprompt: congrats

14:48 TimMc: noprompt: !

14:49 noprompt: bitemyapp: yep. i mean unless something goes wrong.

14:50 TimMc: But chances are you'll have a Little Lisper in a couple years.

14:50 bitemyapp: Haskeller, if I have my way.

14:50 porque no los dos is my motto though.

14:50 TimMc: "why not both"?

14:51 technomancy: noprompt: so far I've only done one "parenting" post, but I'm sure there will be more to come. =)

14:51 you've got lots of time to prepare

14:51 TimMc: Anyway, very exciting.

14:51 technomancy: (not that you can actually ever be prepared for something like that)

14:52 bitemyapp: I mean, all you really have to do is not kill the kid.

14:52 that's roughly the standard for perpetuation of the species so far.

14:52 noprompt: technomancy: haha, this is true. you know, when i discovered she was pregnant i flipped out internally. then i saw the ultrasound on tuesday and was happy for some odd reason.

14:52 arrdem: bitemyapp: good news, I'll be helping you lurk the channel more

14:52 technomancy: noprompt: yeah it's understandably gut-wrenching

14:52 jcromartie: "some odd reason" …

14:52 :P

14:52 arrdem: bitemyapp: bad news, my hardware startup shut down Q_Q

14:53 patchwork: noprompt: children rewire your brain. It is evolutionary.

14:53 dmpayton: noprompt: fwiw, not killing the kid is easier than it looks. kids are pretty resilient.

14:53 noprompt: bitemyapp: my dad applied similar logic when teaching me how to drive. "the goal is to get the wagon from point a to point b without wrecking."

14:53 bitemyapp: arrdem: :(

14:53 arrdem: sorry to hear that!

14:54 koalallama: noprompt: congrats

14:54 bitemyapp: tbaldridge: most promising alternative to edn_format so far is the lispreader from clojure-py.

14:55 jcromartie: The whole "you don't understand until you have kids" thing is TOTALLY true. It's literally impossible to explain without experiencing it.

14:55 tbaldridge: bitemyapp: well, we accept patches send one over and I'll merge it.

14:55 (inc jcromartie)

14:55 lazybot: ⇒ 5

15:00 jcromartie: what's a good way to mock a service for tests that doesn't depend on dynamic bindings

15:00 aside from implementing the service with protocols+records

15:00 and I may have just answered my own question

15:01 stuartsierra: yes you did

15:01 danielszmulewicz: noprompt: Secretary and core.async is pretty neat: https://www.refheap.com/22046

15:01 noprompt: danielszmulewicz: it's fun stuff. gf3 deserves most of the credit though. :-)

15:03 danielszmulewicz: it'd be great to have clout support cljs so there'd be one unified routing api story.

15:05 danielszmulewicz: noprompt: Is clout the thing that Compojure uses, or are they separate things?

15:07 noprompt: danielszmulewicz: yes. clout is what compojure uses for routing. i like it's design.

15:07 danielszmulewicz: i also like the strait forward approach secretary takes too.

15:07 danielszmulewicz: noprompt: Right. +1 for a unified routing api story.

15:08 noprompt: danielszmulewicz: the neat idea is potentially being able to reuse routing code on both the server and the client.

15:13 akhudek: dnolen: your todo app has a bug, if you delete some items then try checking some boxes, the wrong boxes get checked

15:13 dnolen: otherwise, very impressive!

15:14 danielszmulewicz: Is the todo app going to make it on the README?

15:14 I mean on the main page of http://todomvc.com/ ?

15:15 I see a "compile to javascript" section, but no link to Clojure-related technologies...

15:31 mikerod: I'v read through this https://groups.google.com/forum/#!topic/clojure-dev/9JB-vKjvbhE and then saw hiredman had a gist @ https://gist.github.com/hiredman/921874 . I find this interesting and think I'm being bit by it.

15:32 Is this expected behavior or a defect?

15:39 noprompt: technomancy: i've been thinking about creating a modifier key which, when held, would allow me to type numbers on the home row. :-_

15:39 :-)

15:39 the key travel to the actual number keys is too far.

16:06 technomancy: jcromartie: with-redefs doesn't use dynamic bindings

16:06 jcromartie: technomancy: thanks

16:07 I already moved to a protocol though :)

16:07 technomancy: =(

16:07 jcromartie: why so sad?

16:07 you're one of those "just use a map" purists?

16:07 mikerod: ,(eval (let [c (comp inc inc)] `(~c 1)))

16:08 clojurebot: #<ExceptionInInitializerError java.lang.ExceptionInInitializerError>

16:08 mikerod: :(

16:08 technomancy: not a fan of using protocols for anything other than extreme perf requirements

16:08 mikerod: ,(eval (let [c (comp inc inc)] (c 1)))

16:08 clojurebot: 3

16:08 technomancy: mikerod: yeah, functions get stripped of unused environment

16:08 stuartsierra: with-redefs is still dynamic (time) scope.

16:08 jcromartie: technomancy: I think they also make sense when it comes to external services, where a mock is truly useful sometimes

16:08 technomancy: otherwise you leak a lot

16:08 jcromartie: otherwise I prefer standard functions and data

16:09 what do you mean leak?

16:09 technomancy: jcromartie: as long as I don't have to maintain it

16:09 jcromartie: Imean they'd have to carry around a bunch of unrelated junk

16:09 mikerod: technomancy: is there anywhere I could look to understand this more?

16:09 jcromartie: does with-redefs work across namespaces?

16:10 technomancy: jcromartie: sure

16:10 mikerod: I guess I have a fn being AOT compiled that closes over its environment during macroexpansion time

16:10 technomancy: mikerod: not aware of any docs on the subject. this channel is surely your best resource =)

16:10 mikerod: I struggle to see a workaround, I was relying on the closure over the surrounding env

16:11 and AOT compilation is necessary

16:11 technomancy: you can get the closure via the implicit &env arg to macros, but not with functions

16:11 jcromartie: I see… with-redefs would likely fit the bill

16:11 technomancy: see my serializable-fn lib

16:11 jcromartie: I'll keep it in mind in the future

16:13 mikerod: technomancy: yes, I have seen the &env before hmm

16:14 I'll bang my head against my desk on this one for a bit I guess. :)

16:14 jcromartie: but then again, with protocols I can have different implementations of the services at the same time, while with-redefs is messing with globals

16:14 and globals are bad no?

16:14 technomancy: vars are globals

16:15 as long as the extent of the changes are limited they're certainly easier to follow than protocols

16:16 jcromartie: yes and changing them for short periods of time seems flaky :)

16:16 rather than treating them as permanent always-and-forever values

16:16 I prefer to think of top-level vars in namespaces as constants, with the option of temporary thread-local bindings. with-redefs seems like a pretty heavy hammer.

16:16 but it works for a unit test

16:16 zerokarmaleft: at what point does dynamic (time) scope become an issue for with-redefs?

16:17 jcromartie: if I was running my app from a REPL and I ran my unit tests (which used with-redefs for mocks) it would break the app while the test ran

16:17 technomancy: I haven't run into any problems with them in practice

16:17 jcromartie: which while not likely to cause real (as in production server) problems is not great

16:18 zerokarmaleft: hmm, I can't imagine that disrupting development workflow

16:18 jcromartie: I can imagine making a mess but I doubt it would really go bad :)

16:18 technomancy: I would take a bit of yuckiness in tests over making the implementation more complicated simply in order to make it testable any day

16:19 jcromartie: well, my implementation went from having a ns full of functions operating on a map, to a namespace full of functions operating on a record

16:19 and you create the record with a constructor function that takes a map

16:19 technomancy: reloading issues around records are super annoying to track down in repl driven dev

16:19 jcromartie: yes they are

16:19 that would be one thing

16:20 stuartsierra: tools.namespace fixes that

16:21 jcromartie: but then again if you are depending on with-redefs to mock external services then you have to mock everything that might be called by anything else, whereas providing a mock implementation as a record puts the mock in one tidy package

16:21 technomancy: even if you save of a record in a one-off def?

16:21 I do that all the time

16:21 *off

16:21 stuartsierra: don't do that :)

16:21 technomancy: jcromartie: fixtrues are just functions

16:21 devinus: is anybody here using OrientDB?

16:21 stuartsierra: but yes, it will lwork

16:21 technomancy: stuartsierra: no.

16:22 jcromartie: speaking of "one tidy package" I mean

16:22 jcromartie: yes

16:22 technomancy: in fact quite a bit tidier since they are scoped to just the tests

16:23 jcromartie: so would a reified mock service

16:23 technomancy: but you've still changed the behaviour of your impl just to support your tests

16:25 logic_prog: dumbass question: what is the reason, in the context of cljs, why I have to define macros in *.clj files and can't define them in *.cljs files

16:27 dobry-den: Since Datomic isn't ideal for counters, what would be a simple way to keep track of viewcounts for posts in my database without bringing in something like a Redis dependency?

16:27 vijaykiran: osnr: http://stackoverflow.com/questions/18381052/why-clojurescript-macros-cant-be-written-in-clojurescript

16:27 oops logic_prog ^^

16:27 logic_prog: vijaykiran: nice, thanks!

16:27 dobry-den: The simplest I could think of is an atom that stores a hash-map of post-ids and incs them. And this gets periodically serialized to viewcounts.edn

16:27 mikerod: technomancy: http://stackoverflow.com/questions/11191992/functions-with-closures-and-eval-in-clojure

16:28 turns out there was already a stack issue on it

16:28 dobry-den: (I guess I would use an agent, rather)

16:28 mikerod: that is comforting

16:28 technomancy: it's not really an eval issue

16:28 mikerod: mine isn't coming out of eval

16:28 technomancy: ah, right

16:29 mikerod: it is the results of a fn call that is called during macro-expansion

16:29 so it is hidden and sneaky, IMO

16:29 I'm not doing this weird eval-syntax-quote thing

16:29 technomancy: I think I misread your first question

16:30 mikerod: I have to AOT some Clojure code where a macro, at expansion time, calls a function that returns a map pointing to some anonymous functions that close over their environment

16:31 eh map pointing is wrong, I mean map with anonymous functions as vals

16:41 jcromartie: somebody help me out… what's that macro that lets you define a name for the intermediate result of a bunch of forms?

16:41 Profpatsch: Does the repl display the output of called Java classes?

16:41 jcromartie: like (_ it …)

16:41 zerokarmaleft: jcromartie: as->?

16:42 jcromartie: as!

16:42 where is that?

16:42 technomancy: Profpatsch: if they print to an outputstream that the repl is hooked up to.

16:43 jcromartie: zerokarmaleft: that's not in core right?

16:43 hm, it is

16:43 technomancy: not sure which repls reset System/out for you

16:43 zerokarmaleft: jcromartie: i think so

16:43 Profpatsch: technomancy: stdout, stderr?

16:43 zerokarmaleft: jcromartie: rather, I think it *is* in core

16:43 jcromartie: I couldn't find it in clojuredocs or google

16:43 technomancy: Profpatsch: you can try writing to System/out to check for yourself

16:44 maravillas: it's newer than clojuredocs has

16:45 Profpatsch: technomancy: Nope, (.println System/out "foobar") does nothing.

16:45 How to hook it up then?

16:45 technomancy: Profpatsch: technically it probably went somewhere you're just not looking

16:45 there's something like a System/setOut maybe?

16:46 been a while

16:46 Profpatsch: technomancy: Huh, aren’t you doing any Java interop?

16:46 technomancy: not doing much of anything these days

16:48 Profpatsch: Huh, too much maintaining leiningen?

16:48 technomancy: well, that sounds bad. I am not doing much clojure, but I am learning a hell of a lot.

16:49 no, Leiningen is just really stable and mature

16:49 https://github.com/heroku/logplex/pull/71 <- this whole week

16:50 I am using records, and they are terrible!

16:50 (erlang records, but still)

16:50 Profpatsch: Huh, Erlang. Not something you program everyday.

16:51 Especially at work.

16:51 mikerod: technomancy: https://gist.github.com/mrrodriguez/8046814

16:51 in case you had any interest, this is what I was eluding to

16:51 just some dummy fn and macro combination to demonstrate

16:52 I'm open to anyone else's insight on this issue as well :)

16:53 arubin: Interesting. IRCCloud displays gists inline.

16:54 bitemyapp: arubin: that's pretty appealing.

16:54 technomancy: mikerod: not really sure what you're intending there. wouldn't expect that to work.

16:54 bitemyapp: I also like my macro images to be inlined.

16:54 Profpatsch: Hm, not even (with-out-str) works for grabbing stdout in the repl …

16:54 technomancy: bitemyapp: you must trust your co-workers more than I do

16:55 Profpatsch: with-out-str operates on *out*, not System/out

16:56 mikerod: I don't know why you wouldn't expect it to work. It is a very simplified case.

16:56 *though

16:57 technomancy: you have a macro that returns a function object instead of a list that compiles to a function

16:58 mikerod: In the case 2 example; I want the macro to return a map that has keys -> fn objects

16:59 bitemyapp: technomancy: my coworkers are boring enough that I wouldn't worry. I'm the crazy one, remember?

16:59 mikerod: so making fn objects during macro-expansion and returning them = bad

16:59 technomancy: bitemyapp: it'll rub off on them eventually

17:00 bitemyapp: >:)

17:01 technomancy: mikerod: well the return value of the macro gets fed to the compiler

17:02 mikerod: I added a comment on the gist, where I did macroexpand-1 (to see what feeds to the compiler) ;= {:f #<user$get_map_of_fn$fn__10283 user$get_map_of_fn$fn__10283@7321803a>}

17:02 And that fails

17:02 with the function having the closure

17:03 I guess I can (try) to see that this is bad

17:04 zerokarmaleft: technomancy: how would you recommend tracing execution of hook-fns added via robert-hooke?

17:04 technomancy: zerokarmaleft: if they're vars then c.t.trace should just work

17:04 zerokarmaleft: tools.trace seems to break at the point of the hook

17:05 technomancy: on the hooked var or the hook?

17:05 bitemyapp: clojure-py is pretty cool, if anyone has a need for something like that.

17:06 zerokarmaleft: technomancy: the hook itself

17:06 technomancy: hm; sorry, I don't know

17:08 pdk: , (macroexpand-1 (-> 1 2 3 4))

17:08 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

17:08 pdk: welp

17:08 Profpatsch: technomancy: *out* should default to System/out, but *out* is a PrintWriter and System/out is a PrintStream in my repl

17:09 Can I redirect System/out to the *out* PrintWriter somehow?

17:09 mikerod: ,(macroexpand-1 '(-> 1 2 3 4))

17:09 clojurebot: (4 (3 (2 1)))

17:09 Profpatsch: Locally if possible.

17:10 mikerod: I'm not sure why clojurebot just fully expanded that macro

17:10 pdk: You have to quote the form passed to macroexpand-1

17:10 AeroNotix: kind of new to clojure -- can I use leiningen to find local applications/libraries? Ala $GOPATH or $PYTHONPATH or w/e?

17:10 mikerod: unless it will be evaluated

17:12 justin_smith: AeroNotix: lein finds remote deps and installs them to a local archive, you can use lein install to add something to the local archive manually

17:13 bitemyapp: AeroNotix: ls -alh ~/.m2/

17:13 AeroNotix: justin_smith: say like I am developing a project locally and I also locally develop a library for it. Does it need to be a remote dependency too?

17:14 justin_smith: AeroNotix: no, you can use lein install to make it available locally

17:14 and lein uberjar to pack it up with the rest

17:14 but it can be convenient to put it on clojars

17:15 AeroNotix: hmm, with quicklisp for common lisp you can do this. There's a directory which it scans for quicklisp enabled projects. Anythign like this with leiningen?

17:15 technomancy: AeroNotix: lein is more focused on ensuring everything works on a fresh checkout out of the box

17:16 AeroNotix: technomancy: what does that mean in this situation?

17:16 QuickLisp works fine

17:16 technomancy: you can add optimizations for local dev, but that's a step you do after correctly declaring things in :dependencies

17:16 justin_smith: AeroNotix: it works fine on whose box and after finding the deps how?

17:17 AeroNotix: justin_smith: quicklisp is a managed set of repositories. There's an index which lists where dependencies live. (ql:quickload :project-name) then walks the dependencies and grabs them all.

17:17 technomancy: from what I've heard about $GOPATH, "works fine" is not really a good description

17:18 AeroNotix: Perhaps using it would be a better way to form an opinion.

17:18 justin_smith: AeroNotix: so if I had a checkout of your source project, that is all I would need? or would I need to go download a bunch of libraries by hand?

17:18 AeroNotix: justin_smith: you need to have a quicklisp enabled system, yes. But that's similar to needing to have lein installed.

17:18 technomancy: hopefully that will never be necessary

17:18 AeroNotix: technomancy: what wouldn't be necessary?

17:19 technomancy: being forced to write go at work

17:19 AeroNotix: I'm not getting into that conversation. You're arbitrary beef is your arbitrary beef.

17:19 It's a language which Clojure itself ripped off to good effect. Not sure where the problem is but whatevs.

17:19 You disliking it still doesn't make me understand lein any better.

17:20 technomancy: I've made an explicit choice to avoid the slopiness around go's dependency handling

17:20 AeroNotix: I don't care. I think I made that clear :)

17:20 justin_smith: AeroNotix: lein is a dpendency manager, it doesn't use a path, instead it uses mvn project coordinates for each project so versions can be installed in parallel

17:20 AeroNotix: justin_smith: I see.

17:20 technomancy: projects should declare everything they need in order to function

17:21 AeroNotix: technomancy: cool.

17:21 justin_smith: Do I need to understand mvn to use lein?

17:21 technomancy: if it's not declared in project.clj, it doesn't exist, basically

17:21 AeroNotix: technomancy: cool.

17:21 justin_smith: AeroNotix: lein generates a specific path for each artifact you need based on your dependency delcarations, and the recursive declarations generated for that

17:21 AeroNotix: you won't need to understand mvn

17:21 AeroNotix: (fwiw you demonstrably do not understand go's dependency tracking, technomancy but we'll leave it at that.)

17:22 technomancy: not worried, there is a huge pile of other reasons to avoid it

17:22 AeroNotix: justin_smith: so how do local projects come into this? Are there some docs somewhere about that? I looked at some SO answers and it looked like there were some specific flags for local paths

17:22 technomancy: cool.

17:22 justin_smith: AeroNotix: as I said, lein install will put the project in the current directory into the local repo cache

17:23 then another project can declare a dep in order to find it

17:23 AeroNotix: justin_smith: OHHHH!

17:23 justin_smith: I get it, I get it

17:23 justin_smith: how many times did I say "lein install" ?

17:23 AeroNotix: justin_smith: sorry, this is new to me

17:23 technomancy: so you have two projects, right? one of them is a lib? if you can put it on clojars, that will make things much easier.

17:23 AeroNotix: technomancy: baby steps

17:23 also, it may not be public code.

17:24 justin_smith: AeroNotix: a difference is that every dependency is versioned

17:24 that is actually a huge benefit

17:24 pdk: , (macroexpand-1 '(-> 1 2)))

17:24 clojurebot: (2 1)

17:24 pdk: , (macroexpand-1 '(-> 1 2 3))

17:24 clojurebot: (3 (2 1))

17:24 technomancy: yeah lein is secretly an attempt to convince everyone to OSS their libs by making private repos a hassle. you heard it here first. =)

17:25 AeroNotix: technomancy: cool.

17:25 akhudek: AeroNotix: it's trivial to just locally install libraries for local dev

17:25 AeroNotix: we do it all the time

17:26 justin_smith: akhudek: he may even know the command to do that by now

17:26 AeroNotix: justin_smith: :)

17:28 hmm this is pretty cool

17:29 mikerod: technomancy: you will make Richard Stallman proud

17:29 justin_smith: AeroNotix: the ability to select versions without having to uninstall anything or manually set a path is pretty nice, I am spoiled for other environments at this point

17:30 AeroNotix: isn't this just re-using java machinery?

17:30 e.g. mvn

17:30 justin_smith: yes, but edn instead of xml is a nice bonus

17:30 and it is more succinct

17:30 hyPiRion: well, clojure, rather.

17:31 Bronsa: mikerod: you will make RMS mad at you for confusing Open Source with Free Software

17:31 technomancy: mikerod: it's the least I could do after the whole "writing Emacs" thing.

17:31 justin_smith: AeroNotix: I am not saying no other language has it, but from what I have seen none has it quite as simple

17:31 AeroNotix: cool ok

17:31 mikerod: that's true, way to give back

17:32 or perhaps it is pay it forward

17:32 technomancy: npm has a neat thing where you can trivially isolate dependency trees due to the way js modules work

17:32 you can't do that for java since packages aren't first-class

17:32 TimMc: Bronsa: Not even that; you could still have binary blobs in a public place without having the source there.

17:32 technomancy: and doing it for clojure without doing it for java is kinda pointless =\

17:35 AeroNotix: but yeah, maven built some very good foundations we're sitting upon. not too keen on how their builds work, but their repo infrastructure is great.

17:35 AeroNotix: technomancy: cool

17:36 technomancy: I admit I would have made several design mistakes due to my rubygems background if some of those decisions hadn't already been made for me. =)

17:36 akhudek: the only thing that would make mvn better would be the ability to use multiple version of one library in one project

17:37 technomancy: akhudek: it's not really Maven's faund that Java packages are half-assed tohugh

17:37 akhudek: very true

17:37 TimMc: akhudek: I suspect that was omitted because Java doesn't generally allow for that.

17:37 technomancy: fault

17:37 geez, my fingers

17:37 TimMc: Even though Maven "isn't just for Java".

17:38 AeroNotix: so let's say I just `lein install'd something. I fire up a repl, will it be able to access that repo? Or does it need `lein repl'?

17:38 technomancy: TimMc: well, that brokenness is baked in pretty deep

17:38 justin_smith: AeroNotix: with alembic or pomegranate it can find and load that lib

17:38 AeroNotix: but it is often easier to make a project.clj that declares the dep

17:39 AeroNotix: and *then* `lein repl' in the other project?

17:39 technomancy: AeroNotix: tl;dr: no, but if the project.clj hasn't changed you can use lein's checkout-deps feature to pick up changes in a library's working copy without restarting the repl

17:39 justin_smith: right, then require the dep

17:39 technomancy: (assuming you've already added it to :dependencies)

17:39 justin_smith: https://github.com/pallet/alembic

17:39 AeroNotix: cool, ok

17:40 so basically, I can't just fire up a REPL and find the local cache of stuff without some third-party things.

17:40 ala Python REPLs

17:40 technomancy: `lein help faq` tells you about checkout deps

17:40 AeroNotix: reading

17:40 technomancy: ...I think

17:41 justin_smith: technomancy: I think he is just asking about finding something in a repl after a lein install

17:41 unless I misunderstand

17:41 AeroNotix: that's correct justin_smith

17:41 Profpatsch: technomancy: I guess I have to redefine System.out to *out*. However, System/out is static. Is there a way to redefine that in Clojure?

17:42 justin_smith: AeroNotix: I think technomancy was trying to tell you how to do something more complex

17:42 AeroNotix: probably

17:42 * technomancy is just using his time-tested IRC pattern-matching algorithm

17:42 technomancy: checkout deps confuse everyone, so I was pre-emptively over-explaining

17:43 Profpatsch: not sure off the top of my head, but you're on the right track it sounds like

17:43 AeroNotix: I just want to have a project of code which I import via the repl.. can it be done?

17:44 technomancy: just do the `lein install; restart the repl` thing till you get the hang of that

17:44 then once you get tired of having to restart the repl, read up on cehckout deps

17:44 AeroNotix: so when I `lein install' ALL repls have access to this via the local cache?

17:45 justin_smith: if it is referenced in project.clj or you use alembic or the like, yes

17:45 AeroNotix: ok. So not just any random repl

17:45 technomancy: `lein install` means "put this in the local repo"

17:45 so it means that any project on your machine can declare it in project.clj

17:46 as if it were a published dependency on clojars or whatever

17:46 justin_smith: AeroNotix: a key here is there is no implicit dependency (though there is recursive dependency). Every dependency is declared somewhere.

17:46 AeroNotix: hmm

17:46 justin_smith: AeroNotix: though there are workarounds like adding deps to profiles.clj if you want it in every repl

17:46 bitemyapp: yeah so if you want to use Datomic with Python, seriously consider clojure-py.

17:47 justin_smith: or as I mentioned there are libs that find and resolve and import deps at runtime

17:47 AeroNotix: ok thanks

17:52 ahaaaa, I got it.

17:53 so, if I wanted to. I could use profiles.clj to have a similar workflow to what I get in other languages (a global set of repositories) by dynamically adding the deps in the profiles.clj

17:53 whilst also maintaining dependency happiness with the project's project.clj

17:55 technomancy: yeah, typically you would do that with dev tools that the project doesn't actually depend on

17:55 justin_smith: AeroNotix: well I would do it by adding a dep on alembic to profiles.clj

17:55 AeroNotix: but only finding deps explicitly is a huge benefit

17:55 technomancy: profilers, debuggers, refactoring tools, etc

17:55 justin_smith: AeroNotix: it makes deployment and sharing code much simpler

17:56 AeroNotix: justin_smith: if the dependencies are listed properly with project.clj how does that affect things if profiles.clj also has dependencies. Do the deps in profiles.clj get included, too?

17:57 justin_smith: AeroNotix: only one version of a dep will be pulled in, project.clj should override profiles.clj

17:57 they are merged

17:57 technomancy: the lists get merged. if there's overlap it can be problematic though.

17:57 you can see the full thing with `lein deps :tree`

17:57 AeroNotix: ohh, I thought the profiles.clj dependencies were separate.

17:58 technomancy: `lein with-profile production deps :tree` for the "pristine" deps

17:58 AeroNotix: thanks all

18:14 jcromartie: alright technomancy: you've convinced me

18:15 technomancy: cool; your next mission is to use clojure.core/when for side-effects, not just for when you have a single-branch condition

18:16 bitemyapp: ooooohhhh monad comprehensions

18:16 AeroNotix: nice using # in macros for gensym. Nice touch

18:16 bitemyapp: technomancy: monad comprehensions would be nice in OCaml Async.

18:25 technomancy: I believe you but don't know what to do with this knowledge.

18:25 bitemyapp: technomancy: hum. Does OCaml have list comprehensions?

18:25 the syntax in Haskell is repurposeable.

18:26 technomancy: not sure; I always just use map/iter

18:26 bitemyapp: yeah but I mean generalizing to monads

18:27 technomancy: dunno; I've only ever used two monads on purpose, and one of them was called "The GitHub Monad"

18:28 shep-home: After watching http://vimeo.com/68383317, my interest in quickcheck and friends is renewed

18:28 mostly because I realized that my generated data can be a sequence of functions that are applied to an initial state

18:29 which led me to try it out. It works, but I was less-than-enthused with the output from failing cases

18:29 Is there some better string representation of functions that would help me here?

18:29 Or perhaps some tweak to simple-check?

18:30 akurilin: Oh man, exciting day in clojureland today.

18:30 Great post there dnolen .

18:30 shep-home: For example, ":smallest [1 (#<core$partial$fn__4190 clojure.core$partial$fn__4190@71a40dde>)]" is not helping me narrow down the problem i have introduced

18:37 edw: Hey guys, I pushed a little library in Clojure that allows folks to use etcd for configuration using the same interface they'd normally access environment variables, making development and deployment of Clojure apps on CoreOS simpler. <https://github.com/edw/scallion>

18:39 pdk: tonight is a mini accomplishment

18:39 ported -> and ->> to common without them overflowing stack or giving stupid results

18:43 devn: dnolen: the link to "Source" in your TODOMvc clone points at tastejs's github repo

18:44 Just an FYI

18:47 logic_prog: do atoms have almost no overhead in cljs because javascript is single threaded?

18:52 edw: logic_prog: One would hope that you're mostly deref-ing atoms and not modifying them. It's probably the difference between writing "x + 1" and "x[0] + 1" in terms of time and space.

18:53 logic_prog: I need to have a global queue

18:53 I'm using (atom []) to simulate it

18:53 should I be doing something else?

18:53 edw: Been there.

18:53 logic_prog: I was goign to use core.async, ... but core.async has a limit on # of elements on the chan

18:53 edw: what did you end up doing?

18:53 also, I have no idea the difference between "x+1" and "x[0]+1"

18:54 edw: Probably quite small.

18:54 logic_prog: doesn't x+1 and x[0]+1 mean semantically different thigns

18:54 when x is a vector?

18:55 edw: logic_prog: Yeah. In the first case, x would be your queue, in the second, x is an array, the first and only element of which is your queue.

18:56 weavejester: Does anyone know if there are any issues with using Austin with the latests Clojurescript/

18:57 edw: I'm very unfamiliar with the performance promises (if any) that JS runtimes give you about performance of adding or deleted single items from the front and/or back of an array. I'd think you could just use pop(), push(), shift(), and unshift() JS methods directly.

18:57 weavejester: Ah, actually, looking at the source code I might be missing a configuration option

19:01 Hm, that didn't work either...

19:02 Is anyone using anything other than Austin for cljs REPLs?

19:03 shep-home: reiddraper: https://gist.github.com/shepmaster/8048392 -- an example of the output that I am getting with simple-check

19:03 Pretty nice tool :-)

19:03 Thanks for your work on it!

19:05 justin_smith: shep-home: one thing that often helps is using named anonymous functions when possible. This comes up with trying to decipher stacktraces too

19:07 bitemyapp: weavejester: what's your impression of Hoplon so far?

19:08 weavejester: bitemyapp: I'd hesitate to offer an opinion as I'm not that well-versed in ClojureScript dev as yet.

19:08 bitemyapp: weavejester: I'm a little more so, I'm trying to figure out if it's solving the two-way binding problem or something bigger than that.

19:08 I need to get noprompt to look at this.

19:08 weavejester: I'm still trying to set up a cljs environment for my first cljs library :)

19:09 noprompt: what's?

19:09 bitemyapp: so far it looks like it's eval + two-way binding + stateful vars getting smashed over and over.

19:09 noprompt: http://hoplon.io

19:09 weavejester: Without much luck, I might add...

19:09 bitemyapp: no event stream/core.async/FRP though.

19:09 noprompt: bitemyapp: oh yes, i've seen this. a while back.

19:09 bitemyapp: noprompt: are my impressions accurate?

19:09 DOM event streams smashing var state?

19:09 weavejester: I'm unable to get a REPL up that can load in any code. And I get weird warning messages.

19:10 noprompt: bitemyapp: i haven't looked at the code however.

19:11 reiddraper: shep-home: yeah, you definitely bring up a good point, and some custom output for when a test fails is on the roadmap. you wanna file an issue about it so it can be public?

19:11 weavejester: Does anyone happen to have an example of a working cljs environment with a REPL?

19:11 bitemyapp: weavejester: https://github.com/swannodette/mies

19:12 technomancy: it's really distressing that people are asking that question in what is nearly 2014 =\

19:12 weavejester: bitemyapp: I can get that far, but I can't get a good REPL working.

19:13 bitemyapp: technomancy: more distressing that those best positioned to solve the problem have made a habit of denying there's a problem.

19:13 weavejester: So "lein trampoline cljsbuild repl" works

19:13 But I was trying to use something tied in with nREPL

19:13 bitemyapp: weavejester: getting brepl/austin REPL working is a "building your lightsaber" rite of passage for CLJS.

19:13 technomancy: especially coming from someone who has been doing clojure web programming since before I even heard of clojure

19:13 weavejester: Like piggyback or austin

19:13 I do feel very much like a newcomer to cljs :)

19:14 bitemyapp: weavejester: https://github.com/cemerick/austin/tree/master/browser-connected-repl-sample this is the example project for austin.

19:14 weavejester: Ironically I've avoided it for so long precisely because it seemed so hard to set up and so tricky to debug.

19:14 bitemyapp: the debugging story is better than Clojure once you actually get it working

19:14 shep-home: justin_smith: good call. Unfortunately, it doesn't help that much. Also, I'd really like to have the arguments included

19:14 bitemyapp: spoiled bastards have a stepping debugger.

19:14 weavejester: bitemyapp: Yeah, I've looked at that, too. But I can't get the (ns blah (:require ...))

19:14 to work

19:15 * bitemyapp scrunches face

19:15 shep-home: reiddraper: can do. You want an issue for the generic (custom output) or the specific (partial functions)?

19:16 reiddraper: shep-home: custom output please, not sure there is much we can do for printing functions. but feel free to motivate with that specific case

19:16 weavejester: Austin also gives a strange warning: "WARNING: Symbol IDeref is not a protocol"

19:16 shep-home: Yup

19:16 weavejester: Which isn't present when I run the REPL through Rhino

19:17 bitemyapp: weavejester: can mostly ignore the warning IIRC

19:17 justin_smith: shep-home: well (fn invert [x & args] (apply - x args)) will print more readably than #(partial - %) and does the same thing

19:17 weavejester: bitemyapp: Oh, okay

19:17 justin_smith: invert is a terrible name for it though

19:17 bitemyapp: weavejester: what's the actual error/problem?

19:18 weavejester: bitemyapp: I'll just gist it...

19:18 bitemyapp: eggscellent.

19:18 weavejester: bitemyapp: https://gist.github.com/weavejester/8048564

19:19 Maybe it's because I'm not using "src" for my cljs?

19:19 Except the warning implies it did load it up.

19:20 bitemyapp: weavejester: lein-cljsbuild has special source dir / prefix parameters.

19:20 weavejester: you need to specify them so it knows where to find your namespaces.

19:20 fair warning: I write clojurescript approximately once a month. I've actually written more clojure-py than CLJS in the last 30 day interval.

19:21 weavejester: bitemyapp: Oh, cljsbuild works fine. Let me show you the branch

19:21 https://github.com/weavejester/reagi/tree/clojurescript

19:21 bitemyapp: weavejester: "works fine" is relative, you could be working with a brepl that doesn't have your namespaces rolled in.

19:22 weavejester: bitemyapp: Well, what I mean is that it compiles and works with "lein trampoline cljsbuild repl"

19:22 Actually, let me just double-check that.

19:22 bitemyapp: weavejester: well, normally it wouldn't matter, but yeah, IDeref isn't a protocol.

19:23 weavejester: bitemyapp: what is it?

19:23 I know in Clojure it's an interface.

19:24 But in cljs?

19:24 bitemyapp: weavejester: do something for me first, unfuck that code long enough to test accessing your namespace as if it was a dumb one with a hello-world inside of it

19:24 weavejester: get that working first, then we can broach the subject of your deftype.

19:25 one thing at a time.

19:25 (defn muh-fn [] (println "lol"))

19:25 weavejester: Okay - hang on, rhino-repl is still loading.

19:25 bitemyapp: I want to get your namespace loading and working in Austin.

19:26 since that's the workflow you'd most likely want to work with long term.

19:26 weavejester: Yeah.

19:26 bitemyapp: when you mentioned the warning, I thought it was those generic ones you get sometimes when firing up a CLJS repl, I didn't know you were depending on that actual behavior in your code.

19:26 weavejester: Confirmed it all works fine with rhino-repl

19:27 Yeah, I assumed IDeref was a protocol, since: https://github.com/weavejester/reagi/tree/clojurescript

19:27 bitemyapp: k, comment out the deftype/protocol crap

19:27 weavejester: Oops, I mean: https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L274

19:27 bitemyapp: try calling a hello-world fn from your namespace in austin

19:27 weavejester: In CLJS-land, nothing is true and everything is permitted.

19:28 weavejester: Okay

19:28 Just got one function now: (defn hello [] "Hello world")

19:28 bitemyapp: perfekt.

19:28 and requiring + invoking does?

19:29 weavejester: Just checking. Wiped my out and target dirs, starting up lein repl

19:31 bitemyapp: weavejester: in case you end up needing this information, I've started using clojure-py at work and it's pretty credible.

19:33 weavejester: bitemyapp: https://gist.github.com/weavejester/8048656

19:33 No joy

19:33 Same error as before

19:34 shep-home: reiddraper: done, thanks! https://github.com/reiddraper/simple-check/issues/45

19:34 weavejester: I'll try wiping out .repl, then restart. See if it's something wrong with temporary files left around.

19:35 shep-home: Now that I've done the hard part of creating the issue, I've no doubt it will be fixed soon :-)

19:37 justin_smith: is there a way I can do (fn (...construct-a-name...) []) ?

19:39 reiddraper: @shep-home much appreciated

19:40 weavejester: Nope, same problem

19:41 Although there's no sign of my function in "out" or ".repl"

19:41 Raynes: shep-home: You'd need a macro for that.

19:41 weavejester: cljsbuild compiled it correctly into "target/main.js"

19:41 But I don't know how Austin knows about that.

19:41 bitemyapp: weavejester: nuts.

19:43 weavejester: bitemyapp: Maybe Austin assumes a source path of src/cljs ?

19:43 shep-home: Raynes: yeah, I found a mailing list post and was skimming through that. Thanks!

19:43 bitemyapp: weavejester: I think it only cares about the build artifact from cljsbuild.

19:44 weavejester: bitemyapp: But how does it know where cljsbuild put it?

19:44 bitemyapp: weavejester: why isn't austin in your profile plugins?

19:44 weavejester: also set optimizations to simple

19:45 weavejester: bitemyapp: Well, it wouldn't make any difference if it was in profile plugins or at the top level.

19:53 bitemyapp: setting optimizations to simple doesn't work. I'm taking the config from the sample app directly now. Then I'll try changing directories.

20:03 Bronsa: technomancy: ping

20:06 weavejester: Hm, now my system is dying. brb

20:07 technomancy: Bronsa: hi

20:09 Bronsa: technomancy: hi :), I'm trying a branch of tools.analyzer.jvm which requires core.memoize 0.5.6, unfortunately when I try to use "lein eastwood" (a linter that now uses t.analyzer) it crashes because it looks like an older version of core.cache than what core.memoize 0.5.6 needs is in leiningen's process

20:11 technomancy: Bronsa: huh, so the analyzer doesn't run in project-space?

20:12 Bronsa: technomancy: I'm.. not really familiar with how plugins work in leiningen, are you saying I should look at the dependency issue in eastwood's dependencies?

20:14 technomancy: we can bump the version in Leiningen, but I don't have any plans to cut a release in the near future. doing as much as possible in the project's JVM isolates you from problems lik ethis though.

20:14 I guess the analyzer doesn't need to actually eval any code or access any dependencies?

20:15 so technically it could run in either (modulo dependency conflicts)

20:15 and running inside Leiningen's own process is certainly faster

20:17 Bronsa: hm, ok so removing the :eval-in-leiningen true solved the issuse, I guess we'll go with that for now

20:18 technomancy: oh, I see. eastwood uses eval-in-project, but for plugin projects that's not going to help?

20:22 Bronsa: technomancy: I honestly have no idea on how leiningen plugins works and what the eastwood one does. I'll let Andy or jonase handle this, sorry for bothering you

20:23 technomancy: I would definitely recommend removing :eval-in-leiningen unless you are writing a plugin.

20:24 Bronsa: technomancy: eastwood is a plugin

20:25 technomancy: oh I see; the plugin needs the analyzer; you're not hacking on the analyzer itself

20:26 yeah, it is pretty silly that Leiningen pulls in core.cache just for its templating engine, which is pretty much guaranteed to not need it =\

20:27 weavejester: Hum, I'm giving up on trying to get ClojureScript to work for now.

20:28 I'll need to ask how people actually develop in ClojureScript on the mailing list. It's not nearly as straightforward as Clojure.

20:31 technomancy: Bronsa: feel free to inc: https://github.com/davidsantiago/stencil/issues/18 =)

20:31 logic_prog: argh

20:31 how do I do macro expansion in cljs?

20:32 im getting errors of not ffinding cljs.compiler and cljs.analyzer

20:32 Bronsa: technomancy: one-upped, thanks

20:32 technomancy: Bronsa: I'm sure the debian folks would love that too

20:33 Bronsa: technomancy: are they packaging lein?

20:33 technomancy: yeah, they are pretty close to getting 2.x into sid it sounds like

20:34 Bronsa: That made me die a little inside

20:36 technomancy: the fact that it currently ships 1.x?

20:36 apparently there was a ton of cleanup they had to do

20:37 lots of projects that don't ship with license files; some with internally inconsistent licensing

20:39 weavejester: AHA!

20:40 The undocumented configuration option I was missing was to set the :source-paths to Clojure and ClojureScript

20:40 :source-paths ["src" "src-cljs"]

20:51 technomancy: it doesn't let you put them both in src/?

20:52 hiredman: technomancy: you can

20:54 he isn't clear about the option though, because while lein has a :source-path(s) so does cljsbuild

20:54 not sure how or if they overlap

20:54 cljsbuild's is certainly mentioned in the readme too

21:39 seangrove: What's the difference between :foreign-libs and :preamble for cljsbuild?

21:50 OldTree: Hi, clojure-noob here, was reading through source of "juxt" when I saw "reduce1." (doc reduce1) evaluates to nil, but I found one site that places reduce1 in clojure.core, clodoc.org. I'd appreciate any info on it.

21:59 alandipert: dnolen: nice work re: om! curious about https://github.com/swannodette/om/issues/9 - is this complection part of why react is so fast?

22:03 seangrove: OldTree: reduce1 is defined in the same file on line 882

22:04 OldTree: thanks

22:22 dobladez: Any suggestions for a CI solution for a Clojure + JavaScript project ?

22:23 seangrove: dobladez: CircleCI + Phantom/Sauce Labs via WebDriver?

22:24 + clojure.test + cemerick/clojurescript.test, depending on what kind of tests

22:24 dobladez: sounds like an option, thanks

22:24 do you have experience with CircleCI ?

22:24 vs., say, Jenkins ?

22:24 seangrove: Sure, used both

22:25 Also, worked at Sauce for quite awhile, so a bit biased in that regard

22:25 dobladez: great... so, any pros/cons between Circle and Jenkins ?

22:27 seangrove: Same argument with Heroku vs Linode. Circle is slick, pretty easy to get setup, and you don't have to worry about it. And when they add things on, they do it in a sustainable way. Jenkins has a much more vast ecosystem of varying quality, it takes longer to tweak and get right, but it very flexible and you can really drill down into the box running it.

22:39 bitemyapp: arrdem: mumbur?

22:40 arrdem: bitemyapp: yeah hang on glue in hand building minis

22:48 bitemyapp: solid evening.

22:48 arrdem: iknowrite

22:49 bitemyapp: arrdem: do you like tactical shooters?

22:49 arrdem: bitemyapp: I mean I played MWO, but I don't usually go in for milsims

22:50 bitemyapp: arrdem: hum, what I'm thinking of is more realistic than CounterStrike, but similarly structured - but more fun and focused than ArmA

22:50 it's on sale.

22:50 I've been playing it for 4-5 years, they have a new early access thing.

22:50 arrdem: bitemyapp: title?

23:23 SegFaultAX: dobladez: I've used CircleCI and Jenkins extensively, let me know if you have any questions.

23:25 dobladez: SegFaultAX: I have quite a bit of experience with Jenkins (from past Java projects)... just wondered if it's easy to make it work with lein and the rest of the Clojure and JavaScript testing ecosystem

23:25 so, was looking for recommendations/caveats or other options besides Jenkins and CircleCI

23:27 SegFaultAX: dobladez: It's trivial to make Clojure projects work with Jenkins.

23:27 Especially if you've done it with a similar build system before.

23:27 dobladez: great

23:27 I see there's a leiningen plugin for it

23:28 SegFaultAX: CircleCI is /really/ expensive, and the UI, while pretty, has some pretty big issues.

23:29 One of our biggest annoyances with Circle in general was a) it ran builds pretty slowly b) it didn't do a good job of collapsing enqueued jobs for multiple commits on the same branch.

23:29 dobladez: so, with Jenkins is it easy to capture test runs from, say, Midje ?

23:29 SegFaultAX: Yes. Just archive the artifacts (which includes stdout)

23:30 Then you can go back and look at the at your leisure.

23:30 We initially started using Circle as a stopgap while we looked for a permanent CI solution. We didn't really realize how expensive it would be.

23:30 dobladez: oh with "capture" I just meant to auto-detect build failures with at least some minimal reporting about it

23:31 SegFaultAX: In the end we just built two custom machines with lots of ram and CPU.

23:31 dobladez: The easy way to do that is return a non-zero exit code.

23:31 Jenkins has extensive reporting and tracking features.

23:32 dobladez: right. OK... looks like I'll play with Circle a bit... (has a 14-day trial)... but knowning I might endup with my own Jenkins on Digital Ocean

23:32 SegFaultAX: Ugh. How big is the sweet?

23:32 I would say don't do cloud-based CI.

23:33 If you can avoid it.

23:33 Our suite is mid-sized, maybe 13 - 17k tests. It took like 24 - 30 minutes per run on Circle.

23:33 ~16 on dedicated boxes ($800 each)

23:33 clojurebot: Excuse me?

23:34 dobladez: well... it's a small project... we are only 1.5 developers... and we don't own (nor plan to purchase) hardware

23:35 SegFaultAX: Oh, well then whatever works.

23:35 Probably circle will be fine.

23:35 Or travis.

23:36 dobladez: travis is much more expensive it seems

23:37 SegFaultAX: Just use whatever works to get CI going.

23:37 dobladez: What I like about a custom Jenkins is that with DigitalOcean I can probably start fine with the $5/mo. option... and easily bump it if needed... and if that ever becomes slow, simply move the installation to local hardware

23:37 SegFaultAX: For small projects it mostly doesn't matter, and the costs of switching is low.

23:39 dobladez: Yea, plus it's easy to slave builds with Jenkins.

23:39 dobladez: SegFaultAX: curious: what are you working on? looks like a pretty big Clojure project

23:40 SegFaultAX: dobladez: Well the big one I'm referring to is Rails.

23:40 dobladez: ah, ok

23:43 SegFaultAX: dobladez: One thing I've been thinking about for a while is using Jenkins to run builds inside of docker.

23:44 dobladez: yep... I think there's already support for that

23:45 on a prior project, we configured it with an internal "cloud" (CloudStack) using Jenkins' jclouds plugin (if I remember correctly)

23:45 so, it launched new slaves as need

23:45 docker containers are much faster to start though... perfect fit

23:55 SegFaultAX: dobladez: Yea, that's pretty awesome.

23:56 dobladez: SegFaultAX: gotta go... 2am here. thanks again

Logging service provided by n01se.net