#clojure log - Feb 12 2014

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

0:01 benkay: ,(.byteValue 60002)

0:01 clojurebot: 98

0:11 technomancy: is anyone using user-env-compile on a clojure heroku app?

0:17 teslanick: I might now that I know about it.

0:31 technomancy: no, don't

0:31 it's going away

0:31 Raynes: technomancy: Careful, damn it! With great power comes... you know this already.

0:33 glosoli: What's going away ?

0:37 technomancy: glosoli: an experimental beta feature is getting replaced with something less janky

0:37 possibly alpha, actually

0:38 glosoli: Is there some link one could read (might be of an interest)

0:38 :?

0:39 dsrx: more official support for anvil would mean most cases of user-env-compile I can think of would be obsoleted

0:39 technomancy: sure, https://devcenter.heroku.com/articles/labs-user-env-compile

0:39 dsrx: there are issues with making config values inputs to the build

0:39 glosoli: technomancy: thanks sir

0:39 technomancy: because we don't force a rebuild when your config values change

0:40 which we really should if you think of them as arguments to a function

0:40 (which is the right way to think about builds)

1:34 * quizdr waves hello

1:37 xsyn: *waves*

1:42 sm0ke: what is the function which basically does a reduce but returns the list of each steps result?

1:42 arrdem: sm0ke: ... what? there's iterate...

1:42 sm0ke: but idk about a reduce that shows intermediaries...

1:43 sm0ke: for sure there was something like that in haskell

1:43 its prefectly viable isnt it?

1:43 bob2: what was it called in haskell

1:43 arrdem: I mean I can see implementing it pretty easily...

1:43 sm0ke: and useful too

1:43 bob2: let me check on lyah

1:45 bob2: scanl scanr

1:45 ,(doc scan)

1:45 clojurebot: Huh?

1:46 arrdem: sm0ke: it's just gonna be a recursive lazy-seq... not to hard to build.

1:46 sm0ke: arrdem: yea, wanted to know if its already available

1:46 arrdem: ,(doc reductions)

1:46 clojurebot: "([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."

1:47 arrdem: gotcha.

1:47 * arrdem bows

1:47 arrdem: sm0ke: ^^

1:47 sm0ke: ,(reductions + 1 [1 2 3 4])

1:47 clojurebot: (1 2 4 7 11)

1:47 sm0ke: ,(reductions + [1 2 3 4])

1:47 clojurebot: (1 3 6 10)

1:47 sm0ke: awesome!

1:48 (inc arrdem)

1:48 lazybot: ⇒ 20

1:48 arrdem: holy shit. 20 karma?

1:49 sm0ke: what i particularly like is the lineage starts from the first element

1:50 exactly what i wanted :D :D

1:51 quizdr: wow that's a useful little function to know about.

1:51 (inc arrdem)

1:51 lazybot: ⇒ 21

1:52 arrdem: two karma... a new (to me) clojure.core function... dogecoin through the roof... is it my birthday?

1:53 sm0ke: heyyy inc my karma too, i was the one who asked

1:54 :P

1:54 Raynes: Well shit arrdem I could have taught you about reductions.

1:54 ;p

1:54 arrdem: <3

2:02 quizdr: (inc sm0ke)

2:02 lazybot: ⇒ 4

2:08 sm0ke: haha

2:08 ok

2:18 alew: reduced is a pretty crazy function

2:30 amalloy: alew: well, it's nice, but compared to, eg, haskell, where you don't even need reduced because of laziness, reduced is nothing special

2:30 sm0ke: so guys, one more question is dont know if this makes sense

2:30 szymanowski: i would like to create a map where field are constrained to each others by relations, so i can change one field value and the change is propagated to other fields via pre-defined relations, does it make sense?

2:31 arrdem: szymanowski: so you want writes with side-effects?

2:31 szymanowski: :)

2:31 arrdem: (dec so) ;; yes I'm still downvoting that guy

2:31 lazybot: ⇒ -7

2:32 arrdem: szymanowski: there isn't any really idiomatic way to do exactly that.. I mean you could fake it by using an atom with watchers but ugh

2:32 szymanowski: better would be to just have an update function that recomputes the fields

2:32 szymanowski: yes i see

2:33 amalloy: what? he didn't say he needed to mutate anything at all

2:33 arrdem: amalloy: he said he wanted parametric fields... that's an implicit update to me...

2:33 amalloy: uhhh...no he didn't? he said he wanted a map with fields in it

2:33 it can be an immutable map

2:34 sm0ke: so i wanted something like apply, (+ (flat [1 2 3]))

2:34 arrdem: "where field are constrained to each others by relations, so i can change one field value and the change is propagated"

2:34 sm0ke: is see that apply is pretty limited

2:34 amalloy: and given such a map, you can certainly write a function (update-firstname m "mike") which updates the first name and then also the full name

2:34 maravillas: szymanowski: not sure if it's quite what you have in mind, but you might look at https://github.com/tailrecursion/javelin/

2:34 sm0ke: why isnt there something which just flattens in place

2:35 arrdem: ,(flatten [1 [2 [3 [4 [5]]]]])

2:35 clojurebot: (1 2 3 4 5)

2:35 arrdem: sm0ke: works fine over here...

2:35 ~flatten

2:35 sm0ke: arrdem: no i want an apply like functionality

2:35 arrdem: clojurebot: flatten |is| almost certainly not the tool you are looking for

2:36 sm0ke: you get my point

2:36 ?

2:36 amalloy: sm0ke: you want ruby/python's splat?

2:36 sm0ke: amalloy: sorry i dont know about it

2:36 * arrdem has no idea what sm0ke is shooting for

2:36 amalloy: cool, cause you can't have it. it just doesn't work in a language with macros

2:36 but it's what you're asking for

2:37 sm0ke: amalloy: why cant we have (defmarco splat [body] ~@body)

2:37 hmm ok that didnt made any sense

2:37 macros are compile time

2:38 amalloy: hey then how does apply works?

2:38 * sm0ke is puzzled

2:38 amalloy: apply is a language primitive, and of course you can do anything with apply that you'd rather do with splat

2:38 sm0ke: amalloy: for starters apply doesnt take other macros

2:38 amalloy: but it has to be a function, it can't be an infix operator that works in the middle of any old crazy mess

2:39 apply isn't a macro either

2:39 sm0ke: amalloy: i really need to look into splat if you mean what i mean

2:39 brb

2:39 amalloy: cool, have fun. i'm going to bed

2:44 sm0ke: ok i read about it and seems to be what i want, but some how this doesnt works for me in pyhton

2:44 print(*[1,2,3])

2:45 arrdem: so my point was print(*[1,2,3]) == print(1,2,3)

2:45 you see?

2:45 arrdem: sm0ke: apply does that....

2:45 ,(apply println [1 2 3 4 5])

2:45 clojurebot: 1 2 3 4 5\n

2:46 sm0ke: yes but apply is hardcoded to some level before the last argument

2:46 you see its not ideal solution

2:46 szymanowski: i would like to be able create a map like that (def rm (rel-map {:a 1 :b 2 :c ?} :where (= :c (+ :a :b)))) => ({:a 1 :b 2 :c 3}) and then be able to (assoc rm :b 3) => {:a 1 :b 3 :c 4}

2:46 sm0ke: more over (apply somemacro list) wont work either

2:47 arrdem: okay... amalloy just told you we don't feature the "

2:47 ideal solution"

2:47 so what's the problem

2:47 this is what you've got.

2:48 and of course (apply somemacro) doesn't work.

2:48 that's what `(do (somemacro ~@list)) is for

2:49 szymanowski: you can't mix your data and code that way unless you want to write new updater operations which will respect your update rules.

2:49 why the hell am I up. I'm going for a run. good luck.

2:52 quizdr: if I need to serialize some stuff into JSON, should I just generate it myself using functions like str, etc to concatenate it manually?

2:52 szymanowski: arrdem: thank you

2:53 arrdem: quizdr: does data.json not _have_ a serializer already?

2:53 $google clojure.data.json

2:53 lazybot: [clojure/data.json · GitHub] https://github.com/clojure/data.json

2:55 mduerksen: quizdr: a lot of clojure libs are listed here, JSON parsers/serializers as well: http://www.clojure-toolbox.com/

2:56 quizdr: nice toolbox site

2:57 mduerksen: yes, it has helped me uncounted times

2:58 and it is updated regularly. it does not give guidance for choosing though, thats up to you/google

3:17 _eric: is there a way to get the current index when using (line-seq)?

3:17 I'm looking for something like ruby's each_with_index

3:18 and I'm sure there's a simple way I could do something with zip, but I can't reason it out

3:20 mduerksen: _eric: not sure how you use line-seq, but you could something like (map-indexed f (line-seq rdr)). then f gets the index and the element

3:22 _eric: sweet

3:25 quizdr: I want a string of a long random number not including its first two digits (which are usually "0.") and this just seems inelegant:

3:25 ,(clojure.string/join (drop 2 (str (rand))))

3:25 clojurebot: "08478211199316987"

3:25 mduerksen: _eric: alternatively you could do this: (map f (line-seq rdr) (range)) . this way, you can have the index paramter second if you like. using map with multiple arguments is something i sometimes forget is possible

3:25 quizdr: Is this an idiomatic way to achieve this?

3:28 sm0ke: ,(.substring (str (rand)) 2)

3:28 clojurebot: "15675975031956557"

3:28 mduerksen: quizdr: there is a function rand-int, so you could do (str (rand-int n)). if you need it 0-padded, you could do (format "%012d" (rand-int n)). not sure if i got the format syntax right

3:29 edbond: quizdr, long random number? ,(doc rand-int)

3:29 quizdr: ok. rand-int is no better as I'd just have to specify a very large int to get same precision.

3:30 edbond: or you can rand-nth from string "123456798"

3:30 clojurebot: Titim gan éirí ort.

3:30 mduerksen: does your random have to be cryptographically secure?

3:31 edbond: ,(repeatedly 5 #(rand-nth "123"))

3:31 clojurebot: (\3 \3 \3 \2 \2)

3:31 quizdr: no nothing fancy is required, just want to ensure totally unique file names

3:31 sm0ke: quizdr: why not use uuid?

3:31 ,(str (java.util.UUID/randomUUID))

3:31 clojurebot: "782469d1-fff0-40cd-88c9-11dd9a9afce4"

3:32 quizdr: ah, didn't know about that one. nice.

3:32 (inc sm0ke)

3:32 lazybot: ⇒ 5

3:34 edbond: korma question: how to select date from DB? I have 'date' column, contains "2013-03-14". Korma select returns #inst "2013-03-13T22:00:00.000-00:00" that is of java.sql.Date type.

3:34 any way to get correct Date? without hour / minute /second ?

3:41 wink: sounds like a UTC problem

3:41 I don't think it's incorrect

3:42 edbond: do you know about https://github.com/clj-time/clj-time ? :)

3:43 edbond: wink, I think that may help. It seems that date converted to UTC from my local TZ +2

3:44 I expected to have something like <LocalDate 2013-03-14>

3:44 wink: can't help you with your specific problem unfortunately, but have a look at joda, it usually solves my woes :P

3:46 edbond: wink, thanks

3:47 wink: yw

3:51 mklappstuhl: how can I install a lein dependency straight from git?

3:53 sm0ke: mklappstuhl: you can use lein-git-deps plugins

3:53 but its ugly

3:57 edbond: mklappstuhl, create checkouts dir and clone project there

3:58 mklappstuhl, https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies

4:01 sm0ke: edbond: i dont see the point if you are doing that much manual work

4:01 you can directly do `lein install` from the cloned project instead

4:02 or mvn install or whatever build system that project is using

4:03 edbond: sm0ke, yes I think you right. If you not going to edit deps or update frequently

4:07 mklappstuhl: edbond: I setup a checkout dir and linked etc, but does that take the HEAD and not the version which is specified in the project.clj?

4:08 edbond: mklappstuhl, it will use version you have in the directory

4:09 mklappstuhl: edbond: cool

4:23 edbond: how can I check if that lib is actually being used then? somehow there is no effect and I'd like to double check if I've done it correctly

4:24 edbond: mklappstuhl, remove it from project.clj, lein clean, lein repl, require/use

4:45 quizdr: here's an odd one

4:45 https://www.refheap.com/36884

4:45 it actually returns a lazy collection in quotes?

4:45 what's weird is if I don't include the "[" then it returns an actual collection as a string as you'd expect

4:46 as if the act of making a string causes evaluation to occur of the entire string

4:52 tazz: Hey guys I am trying to convert a filter (filter #(= "foo" ) to start accepting regex

4:52 right now I get "java.lang.ClassCastException: java.util.regex.Pattern cannot be cast to clojure.lang.IFn" type of exceptions.

4:56 edbond: ,(apply str "[" (interpose "," (map #(str "\"" % "\"") [1 2 3])) "]")

4:56 clojurebot: "[clojure.lang.LazySeq@5fd031bd]"

4:56 edbond: ,(apply str "[" (interpose "," (map #(str "\"" % "\"") [1 2 3]))

4:56 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

4:57 edbond: ,(type (map inc [1 2 3]))

4:57 clojurebot: clojure.lang.LazySeq

4:59 edbond: quizdr, nice trick. Looks like a bug to me

5:00 or not, interpose returns lazySeq

5:00 ,(type (interpose "," [1 2 3]))

5:00 clojurebot: clojure.lang.LazySeq

5:02 edbond: ,(str "[" (apply str (interpose "," (map #(str "'" % "'") [1 2 3]))) "]")

5:02 clojurebot: "['1','2','3']"

5:02 edbond: quizdr, ^

5:02 tazz, use re-find

5:02 tomjack: wow, I just looked at const__i in a fn

5:03 edbond: ,(filter #(re-find #"foo" %) ["foo" "bar"])

5:03 tomjack: guess I sorta knew this was happening but not how exactly

5:03 clojurebot: ("foo")

5:07 quizdr: edbond i think i figured it out

5:07 i was not using apply correctly

5:07 the last argument to apply must be a list

5:13 pyrtsa: quizdr: To use apply with a non-list as last argument, make it not-last by appending () to the arguments. ;)

5:14 edbond: pyrtsa, then you don't need apply

5:31 pyrtsa: edbond: Haha, indeed.

5:44 danielcompton: I have a question about do which is a little basic. When do you need to use do and when can you wrap the forms in parens without a do?

5:45 i.e. (do (side-effect 1) (side-effect 2)) vs ((side-effect 1) (side-effect 2))

5:45 pyrtsa: You use do to evaluate multiple expressions for side effects.

5:45 danielcompton: Won't the second expression still evaluate both side effects though?

5:46 pyrtsa: Wrapping anything in a pair of parentheses executes it as a function. ((side-effect 1) (side-effect 2)) will only work if (side-effect 1) returns a function that can be called with the result of (side-effect 2) as its single argument.

5:46 algernon: the second will evaluate (side-effect 1), and try to call the result as an fn with (side-effect 2) as argument.

5:46 danielcompton: ah of course

5:46 I knew I was missing something

5:46 obvious

5:47 Thanks!

5:47 pyrtsa: danielcompton: You *don't* need do when there's an implicit do, like in the bodies of (when x ...) or (fn [...] ...).

5:48 edbond: I find do needed with (if) when you have several thing in one branch. (if <cond> (do .. ..) <else>)

5:48 danielcompton: Is there something like when that will work for true and false?

5:49 So you don't need to wrap if bodies in do?

5:49 pyrtsa: edbond: In those cases, it might make sense to create an own function of the body of the if-true branch.

5:50 edbond: pyrtsa, sure. sometimes I just what to (prn) and remove later :)

5:51 pyrtsa: danielcompton: What would separate the else branch from the body of the if-true branch then?

5:51 arrdem: ,(println "arrdem: pong")

5:51 clojurebot: arrdem: pong\n

5:52 danielcompton: pyrtsa: there would still be (if expr true-form false-form) but inside true-form you wouldn't need to wrap them inside another do

5:53 pyrtsa: danielcompton: You can write your own macro for that.

5:53 danielcompton: so (when-if expr ((side-effect 1) (side-effect 2)) (side-effect 3)))

5:53 pyrtsa: That's what I started thinking as I was typing it :)

5:53 arrdem: ... so saving two characters for what?

5:53 pyrtsa: In my opinion, it doesn't read well. The outer (...) still looks like a function call.

5:54 edbond: danielcompton, just add do )

5:55 Anderkent]away: danielcompton: yeah that looks really confusing. What if you had ((partial foo) x) as your expr - wrap that in another set of parens? Just use do, or prefferably dont use if

5:55 danielcompton: Yeah, it's not the best idea

5:55 Anderkent: cond is your friend

5:56 danielcompton: even for either or scenarios?

5:57 Anderkent: well, if you can fit at least one branch on a single line, then (if expr (short branch) (do long branch)) is fine

5:58 but if both are long, and you don't want to pull the contents out to separate defs, (cond (expr) (first-branch) :else (second-branch)) is nicer imo - much clearer where the branches end

6:25 ohcibi: when using core/remove on a set it returns a list. what is the idiomatic way of passing a collection to a function like remove and get a collection of the same type as result?

6:26 (set (remove ...)) would work for sets but this looks kinda verbose to me

6:28 AimHere: ,(disj #{:a :b :c :d} :b :c)

6:28 clojurebot: #{:a :d}

6:28 AimHere: That the sort of thing you want?

6:29 Oh wait, perhaps not

6:31 Anderkent: ohcibi: (set (remove ...)) is unfortunately right; a generic form is (into (empty coll) (remove pred coll)), which will work for 95% of use cases

6:31 and when it doesnt it'll give you back a list because fuck reasonable apis

6:33 ,(let [c (first {:a 1})] [c (into (empty c) (map identity c)])

6:33 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>

6:33 Anderkent: ,(let [c (first {:a 1})] [c (into (empty c) (map identity c))])

6:33 clojurebot: [[:a 1] (1 :a)]

6:36 ohcibi: Anderkent: thanks

6:38 jowag: Is it correct to say that Atom, Ref and Var are 'stateful' types?

6:38 AimHere: Mutable is probably a better word

6:38 Anderkent: to the first approximation yes

6:40 clgv: Anderkent: are you performing a taylor analysis on that definition? :D

6:44 jowag: thanks, and what about Agents, can they be considered 'stateful' too?

6:45 Anderkent: yes, agents have mutable state too

6:46 clgv: is the Hickey word "state (change) management types" or similar?

6:50 jowag: an what about Futures? :) they have a internal state, however not directly mutable by user, but you can use realized? to see if it is computed.

6:54 clgv: immutable but not necessarily immediately accessible. same category as delay or promise

7:00 jowag: yeah but can i call them 'stateful'?

7:01 cleatoma: That depends what your definition of "is" is.

7:03 clgv: jowag: I would not since you can not change their "state" after they have one in contrast to refs, atoms, agents

7:05 jowag: clgv: that's what mutable is. I wanted to express the fact that there is some state which you can at least query and that can change between two calls.

7:18 sveri: haha, nice topic

7:26 noidi: ,`()

7:26 clojurebot: ()

7:27 noidi: ,`(~@[])

7:27 clojurebot: nil

7:27 noidi: isn't this a bug?

7:27 Anderkent: eh, nil and empty list are kinda almost the same thing

7:28 ,(do ~@'())

7:28 jowag: I've found an interesting blog about this problem: http://lalitpant.blogspot.sk/2008/01/object-state-identity-immutability-and.html

7:28 clojurebot: #<IllegalStateException java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/unquote-splicing>

7:28 Anderkent: ,§(do ~@'())

7:28 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: � in this context, compiling:(NO_SOURCE_PATH:0:0)>

7:28 Anderkent: ,`(do ~@'())

7:28 clojurebot: (do)

7:28 Anderkent: fffs

7:28 ,`(do ~@[])

7:28 clojurebot: (do)

7:28 noidi: Anderkent, no, they're not

7:28 ,(boolean `(~@[]))

7:28 clojurebot: false

7:28 noidi: ,(boolean `())

7:28 clojurebot: true

7:28 jowag: "an object has state if its behavior (as defined by its methods) may observably change over the course of time. In other words, the output of (the methods of) a stateful object is determined not only by the input received, but also by some modifiable internal state."

7:29 Anderkent: as i said, kinda almost

7:29 algernon: noidi: ~@ unpacks, there's nothing in [], therefore nil

7:29 AimHere: Anderkent, again, no

7:29 noidi: having the opposite truthiness is not almost the same :)

7:29 AimHere: (if nil "Truthy" "Falsy")

7:29 ,(if nil "Truthy" "Falsy")

7:29 clojurebot: "Falsy"

7:29 AimHere: ,(if '() "Truthy" "Falsy")

7:29 clojurebot: "Truthy"

7:29 Anderkent: ... that's the same exact example


7:30 that's why I didn't say they're the same thing

7:30 noidi: algernon, it didn't unpack nil, it replaced the containing empty list with nil

7:30 AimHere: nil and false are much more similar

7:30 Anderkent: I said they're kinda almost the same thing; many core functions treat nil as empty list

7:30 algernon: noidi: you unpacked an empty list. that doesn't make sense => nil

7:31 noidi: no, I unpacked an empty sequence into a list

7:31 Anderkent: why do you say unpacking an empty list makes no sense?

7:31 noidi: so I expect to get the empty list (as nothing was unpacked into it)

7:31 instead the list is replaced with nil

7:31 Anderkent: ,(seq '())

7:31 clojurebot: nil

7:31 Anderkent: empty list being replaced with nil is idiomatic

7:32 algernon: ,`[~@[]]

7:32 clojurebot: []

7:37 noidi: ,(list? `())

7:37 clojurebot: true

7:37 noidi: ,(list? `(1))

7:37 clojurebot: true

7:37 noidi: ,(list? `(1 2))

7:37 clojurebot: false

7:37 llasram: ,`(1 2)

7:37 clojurebot: (1 2)

7:37 llasram: ,(class`(1 2))

7:37 clojurebot: clojure.lang.Cons

7:38 llasram: There's the case where Anderkent (IIRC?) had suggested earlier where the reader produces non-list?s

7:38 Cool

7:39 Anderkent: Yeah! Ta.

7:40 llasram: Oh, but I bet it isn't, not exactly

7:40 ,'`(1 2)

7:40 clojurebot: (clojure.core/seq (clojure.core/concat (clojure.core/list 1) (clojure.core/list 2)))

7:41 llasram: Yeah, so the reader is producing *code* for syntax-quote, which then evaluates to a non-list? seq

7:41 Oh, you crazy LispReader you

8:18 pellis: hello

8:18 i'd like to process in parallel a list of tasks. however i only have N threads. let's say 2

8:18 when new items enter, id like to free up busy threads by force, and make them process the new items instead of the old ones

8:19 any mechanism to do this? what is this called?

8:20 edbond: pellis, why do you want to free threads? throw away results?

8:20 cleatoma: I think you want interrupts: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

8:21 pellis: edbond: yes throw away results

8:21 i want to limit parallelism. however new items are more important to me

8:21 jph-: pellis, seems like you need some sort of queuing

8:21 pellis: so i want some kind of job stealing to happen

8:22 llasram: That's not quite what job-stealing usually means :-)

8:22 cleatoma: Hmm, actually interrupts looks like it's just some standard messaging. You still have to write the processing code so that it repeatedly checks whether to stop.

8:22 pellis: jph-: yes, i think priority queue that i have items i can change priority for. once i change priority these items will be closer to the end of the queue

8:22 however now i need to orchestrate the 2 threads i have

8:22 llasram: pellis: I think you just want your queue to actually be a stack

8:22 So that whenever threads get a new work item, they always get the most recent

8:23 pellis: llasram: correct. how do i cancel the old items? remember i only have 2 "heads" that can process items off the stack

8:23 edbond: he want to free threads as soon as new tasks arrive

8:23 pellis: if new items are entering the stack, they get priority and need to be processed instead of current ones

8:23 jph-: you'll need a watchdog or equiv

8:23 to halt current processing when new jobs appear

8:23 edbond: I think you need to use java Threads and interrupt

8:24 pellis_: sorry

8:24 jph-: if new jobs appear at known intervals, you could simplify by using a timeout

8:24 pellis_: once item rate is "relaxed", the threads are free to do the entire stack worth of jobs

8:24 jph-: if existing tasks dont complete within timeout, they die

8:24 pellis_: this is like some sort of reverse-throttling

8:24 jph-: yep, that idea also crossed my mind. what if i'm not willing to even wait the timeout?

8:25 jph-: pellis_, i'd argue you start with a timeout rather than increasing the complexity too fast

8:25 llasram: pellis_: Just make the stack bounded size. I think the Java std lib has something which will do that for you automatically, but worst case just have your insertion function drop off the oldest work-item if the stack is too large

8:26 pellis_: jph-: you are right in this argument. i want to explore the more complex solution as well :)

8:26 i just thought my Java isn't that polished in order to express what i need

8:26 i guess I'm looking for a "RingExecutor"

8:27 where new items in the ring will kill old items

8:27 and the ring's size is the size of the threadpool

8:32 llasram: pellis_: I think you'll need to write something relatively custom... The Java std lib has most of the parts, but not all put together the way you want

8:32 pellis_: yep, ok that's good enough. i just needed to know i'm not reinventing the wheel

8:32 edbond: pellis_, look at futures and future-cancel

8:33 pellis_: why does the abstraction of future solve this?

8:34 edbond: it runs on thread, you can cancel it.

8:34 llasram: I'm pretty sure the pellis_ doesn't actually want to cancel in-progress work items

8:34 pellis_: llasram: yes, i do

8:35 llasram: Really? Because then you aren't guaranteed to actually ever produce any results

8:35 edbond: "id like to free up busy threads by force, and make them process the new items instead of the old ones"

8:35 pellis_: i need to do everything i can to process the newer items first

8:35 llasram: I know, but I believe they are mistaken

8:35 clgv: jowag: no in my opinion you can call atom, ref and agent "stateful". but a narrow definition for this "stateful" from the clojure perspective will not fit delay, future, promise. anyway, it is all about how you define "stateful". without a definition attempt it is almost impossible to discuss it reasonably

8:36 llasram: pellis_: If work items are arriving at a slower rate than the rate at which you can process them, then you don't need any of what you've described

8:36 pellis_: If they are arriving at a faster rate, and you interrupt in-progress work-items, then you'll never finish processing any given item, and never produce any results

8:36 pellis_: they are arriving order of magnitues faster, however there are periods of time where there is a "low" and inactivity time

8:36 they are arriving in bursts so to speak

8:37 and i never know whats the size of a burst

8:37 llasram: So you want to produce 0 results during bursts?

8:37 Anderkent: pellis_: then you can't do newest first or you'll never produce any results until burst ends

8:37 rather, you want to finish the current work item then take the newest item on the stack

8:37 pellis_: for a burst of 10 items, and 2 processing threads, when the burst "relaxes" i want the last 2 items processed

8:37 llasram: (inc Anderkent)

8:37 lazybot: ⇒ 7

8:38 edbond: maybe async sliding-buffer is all you need. You can't be sure which items you process

8:38 pellis_: this is like a 'debouncing' algorithm. when you do a text-completion and they don't really go to the network immediately

8:38 llasram: pellis_: Why not just have threads work on the most-recent item each time they become free? They're still guaranteed to process the two most-recent items, and to produce their results last

8:38 Anderkent: llasram: the sad thing bout helping newbies 90% of the time is they don't know about inc :(

8:38 llasram: Anderkent: Haha. Yeah

8:38 jowag: clgv: I agree. the term 'stateful' is not clearly defined

8:39 pellis_: llasram: let me think about that scenario

8:39 llasram: Anderkent: OTOH, it prevents the "Stack Overflow" effect

8:39 Anderkent: :D

8:39 pellis_: llasram: that might be a mid-way solution, yes.

8:39 jowag: clgv: I've found one that fits my purposes, "an operation is said to be stateful if you can observe that its state has changed, e.g. by repeating the same operation with the same arguments but getting different results. Such an operation depends on state which is not provided as part of invoking the operation."

8:40 clgv: jowag: do you want to explain clojure's building blocks to newcommers with that categorization?

8:45 jowag: clgv: I'm designing a library for IO resources which plays nicely with Clojure's concepts of references, reducers, channels, and I need to get some concepts straight

8:46 clgv: jowag: ah ok. then I'd categorize in mutable concepts (atom, ref, agent) and asynchronous concepts (delay, promise, future)

8:47 jowag: clgv: but delay is lazy, not asynchronous :)

8:49 clgv: jowag: yeah lazily triggered. but somehow that is asynchronous as well, since you do not know who computes its value when

8:52 jowag: clgv: same can be told of a lazy sequences, lazy seqs are not realized by those who create, but those who consume first.

8:54 clgv: jowag: humm right. but I wouldnt call delay a lazyseq. because of that and that it shares a lot (querying whether a value was realized ...) with promise and future I'd call it async as well.

8:56 jowag: though Joy of Clojure has futures and promises in the "Mutation" chapter

8:58 jowag: "Clojure Programming" groups delay, future and promises together in "shifting computation through time and space"

8:59 jowag: clgv: now you see there is no clear categorization :)

8:59 Anderkent: well, they're mutable in a very restrictive way; I think that's worth distrinuishing. The core operation @ will always return the same result, just might or might not block. realized? is the mutable part, but often you don't care.

9:01 tbaldridge: clgv: it's not asyn as a deref of a delay will cause the delay to be executed on the caller's stack

9:01 clgv: from a user point of view they are not mutable by the user. the user can just trigger computation or wait for the computation to finsh. he can not mutate the values ;)

9:01 tbaldridge: *async

9:01 jowag: Anderkent: deref takes optional timeout, in that case it can return different result based on whether the future is realized or not.

9:02 Anderkent: ah, fair enough

9:02 tbaldridge: I think the world needs a term for "mutable, but will only be mutated once"

9:02 Anderkent: tbaldridge: lazy?

9:02 clgv: tbaldridge: yeah we had that before. but some other thread might deref it first the it would be async. so has an async characteristic in general

9:02 tbaldridge: I suppose....I guess I could say "hashmaps have lazily computed hash value caches"

9:03 clgv: it depends how you define async. I don't define it as "computed somewhere else" but as "can I continue doing work while this computation completes"

9:04 In that case, I don't think delay really qualifies.

9:04 clgv: saying promise, future, delay are mutable is more a view on implementation details then on the user perspective I'd say

9:04 tbaldridge: ah, delay does not support timeout deref?

9:04 jowag: clgv: I would not say that future is mutable, but that it is stateful

9:05 clgv: delay does not block

9:05 clgv: jowag: humm ok, so we need those definitions to be clear ^^

9:05 jowag: delay sort of blocks when it does the computation. but right that is splitting hairs again

9:06 tbaldridge: clgv: the question of mutability of delays will only really hit you when you try to write delay in a completely pure statically typed language.

9:06 so yeah, it doesn't matter most of the time.

9:08 clgv: I think I am just arguing to group atom, ref, agent together and promise, future, delay in another group when presenting them to newcommers

9:08 jowag: clgv: yeah, I wanted to say that it does not block in sense that a thread does not wait for something to finish.

9:40 gfredericks: does anybody happen to remember how to make a c.j.jdbc query to postgres load the result set lazily?

9:40 generic postgres googling suggests doing .setBatchSize on the Statement; does this require hacking c.j.jdbc or is there an option I'm not seeing?

9:40 quizdr: I just noticed I've been putting my doc strings after the parameter list in defn and it's been working fine, but looks like the doc should got before the parameter list?

9:41 edbond: gfredericks, could you use limit+offset to load in batches?

9:41 Anderkent: quizdr: 'works fine' as in doesn't break, or is the :doc metadata set properly?

9:42 gfredericks: I don't think you can be fully lazy with jdbc; once you close the connection the resultset is invalidated

9:43 quizdr: well, doesn't break. I didn't check meta.

9:43 gfredericks: Anderkent: I know this would be before closing the connection

9:43 quizdr: I'm refactoring now anyway.

9:43 Anderkent: as in you just want to only return the first N elements from (query)?

9:43 gfredericks: edbond: I don't know for sure that wouldn't work but it doesn't sound like the most performant

9:44 Anderkent: you can do that with :result-set-fn set to something like #(doall (take 25 %))

9:44 gfredericks: Anderkent: I can't fit the results in memory, so I want to process them as they're coming in

9:44 Anderkent: ah.

9:44 do the processing in result-set-fn

9:44 gfredericks: right

9:44 but jdbc loads it all eagerly anyhow

9:44 Anderkent: huh.

9:45 that doesn't sound right; are you maybe using as-arrays?

9:45 gfredericks: nope

9:45 it's pretty vanilla

9:45 edbond: gfredericks, https://stackoverflow.com/questions/19728538/clojure-java-jdbc-query-large-resultset-lazily

9:46 gfredericks: edbond: that looks quite relevant, thanks

9:46 edbond: yw

9:47 Anderkent: gfredericks: that's exaclty the as-arrays issue i mentioned

9:47 if you're not doing as-arrays that shouldnt happen

9:48 gfredericks: did you play with :fetch-size ?

9:48 gfredericks: Anderkent: I'm working on that now

9:48 Anderkent: jdbc will fetch :fetch-size results at once

9:48 gfredericks: trying to figure out how it fits into the api

9:49 since now I have to use prepare-statement instead of query

9:49 Anderkent: I believe the default fetch size is 10 anyway

9:49 so it shuoldn't be the issue

9:49 gfredericks: in which case I still don't know what the issue is

9:49 quizdr: what's the best way for me to use a source file in a new project, where the file is in an entirely different project? the ns seems to make idiomatic referencing of other source files in the same project, but the path would get rather long otherwise?

9:50 Anderkent: gfredericks: can you post your query code just in case?

9:50 (in case there's something obvious you're missing :P)

9:51 edbond: quizdr, lein install other project and add it to dependencies

9:52 gfredericks: Anderkent: (jdbc/query db ["SELECT foo FROM bar WHERE baz = ?" quuz] :result-set-fn (constantly :foo))

9:53 if I add LIMIT 5 to the query it returns :foo immediately; otherwise it OOMs

9:53 Anderkent: hm okay, that's pretty straightforward

9:54 try adding :fetch-size 5 to the sql query then I suppose?

9:54 quizdr: edbond run lein install inside the project directory already created with lein?

9:54 edbond: quizdr, yes, the one you depends on

9:54 gfredericks: Anderkent: adding it where?

9:55 Anderkent: ["SELECT foo FROM bar WHERE baz = ?" quuz :fetch-size 5] is where it goes I think

9:55 miiight be wrong

10:01 gfredericks: Anderkent: okay so it goes in a map at the front like [{:fetch-size 5} "SELECT ..." quux]

10:01 but setting the fetch-size still gets me an OOM, though setting max-rows doesn't

10:01 but max-rows truncates the result set

10:03 mskou72: hi

10:03 gfredericks: google suggests I need to turn autocommit off

10:04 mskou72: I have an argument to a function which is either a string or vector. How can i convert it so I'm sure its a vector?

10:04 gfredericks: mskou72: what should "foo" be as a vector?

10:04 Anderkent: gfredericks: I guess that's something with the oracle driver not discarding the previous resultset as you ask for a new page?

10:04 though you don't even ask for the next page

10:05 gfredericks: afaik it's just plain ole eager

10:06 Anderkent: well, c.j.jdbc isn't; but the underlying driver might be

10:06 mskou72: the vector should just contain the one string.

10:06 Anderkent: in which case you're screwed I guess?

10:06 gfredericks: Anderkent: that's been my assumption the whole time

10:06 mskou72: ##(let [arg "foo"] (cond-> arg (not (vector? arg)) (vector)))

10:06 lazybot: java.lang.RuntimeException: Unable to resolve symbol: cond-> in this context

10:07 Anderkent: I remember talking with someone yesterday about a similar issue, except he got :result-fn #(doall (take 25 %)) to work, so the underlying driver had to be at least page-level lazy

10:07 gfredericks: ,(let [arg "foo"] (cond-> arg (not (vector? arg)) (vector)))

10:07 clojurebot: ["foo"]

10:07 mskou72: ok, thanks!

10:07 gfredericks: Anderkent: yeah I figured it's the PG driver; I can't imagine why this is the default behavior, though maybe it's some ACID detail

10:08 Anderkent: gfredericks: http://stackoverflow.com/questions/984073/java-jdbc-lazy-loaded-resultset might help?

10:08 I guess thats what you found, they mention auto-commit

10:08 gfredericks: yep

10:09 Anderkent: thanks!

10:15 xificurC: ,(re-seq #".\*." "ab*b*c")

10:15 clojurebot: ("b*b")

10:15 xificurC: how can I change this ^ to return ("b*b" "b*c") ?

10:16 Anderkent: xificurC: you'll need lookahead

10:16 hm actually

10:17 quizdr: what is idiomatic way to slurp in a collection from a file and work with it? slurp returns a string, which is not the same thing.

10:17 xificurC: Anderkent: dont know lookahead yet

10:17 Anderkent: no I was mistaken, lookahead doesnt do it

10:17 lemme think

10:17 CookedGryphon: hey, I'm trying to get native android libs out of a fat jar using lein-droid

10:18 edbond: quizdr, reader/read-string maybe?

10:18 quizdr: edbond ah of course, thanks

10:18 (inc edbond)

10:18 lazybot: ⇒ 2

10:19 CookedGryphon: does anybody have any tips? In lein-droid/create-apk there's a .addNativeLibraries call which takes a file

10:19 `cbp: xificurC: Can't be done with regex afaik

10:19 CookedGryphon: but the native file I want is inside a jar in a dependency and I don't know how to get the path

10:20 if I had the path I could make it look through and extract all the native deps in all the jars

10:20 `cbp: xificurC: regex can't backtrack their steps

10:20 xificurC: `cbp: thought so but gave it a try. How would you solve it then?

10:22 `cbp: xificurC: Implement your own pattern matching

10:23 cleatoma: re-seq is applying the regexp over and over, but it's only trying from where the previous match ended.

10:23 You could re-use most of the regexp matching stuff, it's just if you get one match you want to start looking again from one character after the start of that match, not after the end of it.

10:24 xificurC: `cbp, cleatoma: well thats a pain, I was thinking of something more lightweight. Anyway dont go too far helping me out, this is just an exercise

10:24 edbond: ,(filter #(= (nth % 1 false) \*) (partition-all 3 1 "ab*b*c"))

10:24 clojurebot: ((\b \* \b) (\b \* \c))

10:24 edbond: xificurC, ^^

10:25 :-P

10:25 xificurC: edbond: yeah I just wrote that myself

10:25 or something very similar

10:25 mklappstuhl: I tried to add a git repo as a checkout to my local repository to work on the most recent state but I have no idea if that worked. Is there any way to figure out what dependencies are used when running lein ...

10:25 ?

10:26 `cbp: Well I guess it depends on how fast you want it :P

10:26 Anderkent: `cbp: xificurC: it's definitely doable with the raw java api

10:26 just not sure if there's a clojure abstraction for it

10:26 in java you can tell the matcher at which point to start looking

10:27 edbond: mklappstuhl, lein classpath | grep checkouts

10:27 Anderkent: so you basically do (while (.find m (.start m 1)) ...)

10:27 edbond: mklappstuhl, also you can check lein deps :tree

10:29 xificurC: Anderkent: thanks, good to know

10:32 oh I'd have another question (not about clojure per se) - vim, emacs, lighttable, ..., use percentage / recommendation?

10:32 I'm new to coding but I used emacs exclusively in the last year, didnt know any editor before

10:33 `cbp: i use emacs 100% for clojure

10:33 lighttable feels better for clojurescript but its still buggy as a dog

10:34 mklappstuhl: xificurC: I used vim for Clojure and it works pretty well

10:35 xificurC: mklappstuhl: with a repl in vim as well?

10:35 Anderkent: a full repl in vim is always awkward

10:35 xificurC: I just see this constant vim vs emacs battle on the net

10:35 `cbp: like right now it's been dling version 0.6.4 for 10 minutes now even though i updated yesterday..

10:35 Anderkent: I've used foreplay without issues

10:35 uhm, I mean fireplace

10:36 xificurC: and thinking if there really is anything to fight about or its just preference

10:36 Anderkent: well, yeah vim vs emacs is a thing

10:36 xificurC: I mean, are the vim commands THAT faster and more powerful?

10:36 Anderkent: emacs I'd say is a bit better suited for clojure; but if you already know vim the pain of switching might not be worth it

10:36 mklappstuhl: Anderkent, xificurC yeah fireplace is really good. but if you've been using emacs for the last year, there is not really a reason to use vim now..

10:36 Anderkent: oh, sure.

10:36 elfenlaid: xificurC, why not to try it yourself :) but, ghm, light table is quite interesting

10:36 xificurC: Anderkent: i know emacs only actually

10:36 Anderkent: then I don't think changing just to use clojure in vim is worth it

10:37 xificurC: I tried vim for 2 days now, going through some tutorials, just to know the difference

10:37 Anderkent: i've been playing with lighttable from time to time too

10:37 mklappstuhl: edbond: lein deps :tree just renders whats in project.clj — I have a more up to date dependency in checkouts, that I'd like to test on, but I don't know if it's properly loaded

10:37 xificurC: but havent created an opinion yet

10:37 Anderkent: think trying both is pretty hard; both have a steep learning curve

10:37 you'll spend a lot of time just getting proficient in both

10:38 xificurC: Anderkent: well i love a challenge :)

10:38 edbond: mklappstuhl, remove dependency from project.clj

10:38 Anderkent: sure, but why not pick a challenge that will actually acomplish something :P

10:38 edbond: mklappstuhl, did you try lein install? maybe an easier option if you don't plan to hack checkouts source.

10:38 xificurC: its true that i don know all of emacs yet but I can do the code editing just fine. What I lack is knowledge of advanced features

10:38 Anderkent: eh, well, if you find it fun feel free :)

10:38 mklappstuhl: edbond: no I didn't. how would I do that?

10:39 edbond: mklappstuhl, go to project dir and run 'lein install'

10:39 mklappstuhl: to the project I want to use?

10:39 would I leave it in the :dependencies array?

10:39 edbond: then update dependencies in your project to use latest version. -SNAPSHOT

10:39 mklappstuhl: err, list

10:39 xificurC: Anderkent: actually i was thinking of trying viper on emacs, I dont want to switch to vim completely

10:39 but to work with viper you gotta know the vim commands

10:40 edbond: mklappstuhl, yes, install project you want to use and update your deps

10:41 mklappstuhl: edbond; is lein install global or would I do that in the same dir where the depending project is?

10:42 Anderkent: mklappstuhl: it's global. it puts it into your ~/.m2/repository

10:42 mklappstuhl: Anderkent: ah, ok. that explains it

10:43 `cbp: xificurC: http://emacsrocks.com/

10:43 vim is too ghetto imho

10:43 * `cbp hides

10:43 Anderkent: let's not turn this into a flamewar

10:43 xificurC: `cbp: yeah I saw them

10:44 Anderkent: not my attention at all, I just wanted to know more about both sides

10:44 Anderkent: xificurC: I was adressing `cbp more than you :P

10:45 xificurC: Anderkent: i know but indirectly it would still be my mistake bringing up the topicc

11:06 TimMc: xificurC: Don't worry, this channel is fairly... mature about the topic.

11:07 Lots of people here use vim *and* emacs, for that matter.

11:10 xificurC: TimMc: thats what I expected anyway, just like people are willing to learn multiple languages they should be willing to learn multiple editors/IDEs

11:10 its funny tht

11:11 that even after a year of trying the functional I still find it often simpler to write something the imperative way

11:11 not all of course, many things are much simpler when written functionally

11:12 devn: TimMc: Yeah, I use both.

11:12 I have both open right now.

11:13 cark: many things are easier to express in the imperative style... functional programming really only shines for larger projects in my opinion

11:14 hum that's not entirely true ... what i really mean is that you reap the benefit later for a little suffering right now

11:15 CookedGr1phon: I find it's really easy to hack together something that works for this particular case you're looking at with imperative... but as soon as you throw something out of the ordinary at it it'll break, where with functional for only a little more though, you get something that's resilient and works in all sorts of cases you hadn't even thought of

11:15 cark: yes

11:15 CookedGr1phon: just generally a lot less brittle

11:15 though that's a lot to do with types too I guess

11:16 Anderkent: I find cases where it's easier for me to write imperatively rare, unless we count stuff like firing of a python repl to do a scan through a file or something

11:16 that I do a lot.

11:18 cark: there are so many cases where just doing it imperatively is so much easier

11:18 like maybe expressing a graph

11:18 circular references

11:19 sure it's easy to have a map from id to node and express your dependencies that way ... but you have to admit, imperative is alluring in such case

11:22 BobSchack: cark have you seen Brandon's talk about graphs?

11:23 cark: i haven't

11:23 do you maybe have a link ?

11:23 BobSchack: cark: http://www.youtube.com/watch?v=j649Tr25RyA

11:23 cark: thanks i'll check it out right away !

11:24 BobSchack: he talks about how circular reference are evil and how to do trees functionally

11:24 Anderkent: weeeell, but that's assuming your data can be modelled as a tree

11:25 cark: yep sometimes there's no way around it, there has to be some circular references

11:56 Anderkent: anyone know an algorithm for finding minimum crossing arrangement between two rows of points (connections are between points on seperate rows or the same row)

11:57 my initial attempts are like O(n^6) worst case

11:57 clgv: Anderkent: I am not sure I understand the problem description fully.

11:58 do you have a small example of that problem or a formal description?

11:59 Anderkent: imagine two lines of points one above the other

12:00 and some links between your points - you can assume the graph is connected

12:00 you can only swap a node with a node in the same row

12:01 get minimum number of links crossing

12:01 it's easier to draw than describe

12:01 clgv: ah ok

12:06 I dont recall a similar graph problem right now. graph layout algorithms may face similar problems

12:07 but the good ones for large graphs are mostly inexact heuristic algorithms

12:09 `cbp: oh lighttable you mess everything up for international keyboards!!

12:14 moquist: I've been using emacs+EVIL+cider for a while now, but I haven't taken full advantage of cider's keyboard shortcuts. AFAICT, I just don't have them bound. For example: "C-c M-e is undefined" I'm using cider. I'm in clojure-mode. Where should I look to figure out what's breaking (e.g.) "C-c M-e"? I'm actually new to emacs itself, so don't shy away from telling me basic things that may be obvious to others...

12:20 broquaint: moquist: 'C-h m' might be a good place to start, also 'C-h k' generally.

12:21 stuartsierra: moquist: you probably to add some initialization to allow CIDER to add keybindings to clojure-mode. Check the CIDER docs.

12:26 moquist: broquaint, stuartsierra: OK, thx. I'll see what I can figure out.

13:10 semperos: can't seem to get Om's om.dom/option onChange handler to fire, no problem with other elements; anyone had experience or have insight?

13:16 dnolen_: semperos: I don't believe it's option that fires on change, rather select

13:16 teslanick: When would an option change?

13:16 ^

13:18 dnolen_: I mentioned this in #clojurescript, but probably worth mentioning here as well - there's a new txq branch which lets you listen on all transactions on the app state

13:19 so in Om you will be able to observe every change to the app state and you get a tag, a root cursor, and a map containing change path, old / new value on that path, as well as the old and new app state

13:19 (think rollbacks)

13:19 the breaking bit is that every transact! or update! call must be given a tag, since often there's not enough information in the previous/new value

13:20 if you're feeling adventurous give :tx-listen a try and feedback would be most welcome - the counters example in the txq branch uses :tx-listen if you're looking for an example.

13:21 https://github.com/swannodette/om/blob/txq/examples/counters/src/core.cljs

13:21 signature for anonymous fn on line 59 should be (fn [tag root tx-data] ...)

13:21 will fix that later today

13:29 gfredericks: I have a seemingly simple streaming problem that I can't tell how to solve with built-in java stream stuff

13:30 given a lazy seq of strings from a jdbc query result, lazily concat & gzip, presenting the result as an InputStream to an http request

13:31 I can't think of anything that doesn't involve siphoning between input streams and output streams and then the requirement to keep it lazy seems to require a lot of manual effort

13:31 i.e., I'm going to end up subclassing something

13:33 pjstadig: gfredericks: use piped streams?

13:33 amalloy: gfredericks: well like, SequenceInputStream

13:33 and for gzipping, i think you do have to use one piped stream

13:33 gfredericks: amalloy: yeah I started with that

13:34 amalloy: pjstadig: are piped streams a built in thing or a technique?

13:34 amalloy: built in

13:34 pjstadig: at least with piped streams at least you don't have to do the siphoning yourself

13:34 amalloy: they take more work than unix pipes, because you have to fork the thread to read them yourself, as opposed to the process starting implicitly

13:34 pjstadig: gfredericks: https://github.com/pjstadig/es/blob/master/src/pjstadig/es.clj#L101-L120

13:35 llasram: gfredericks: If you want to live on the edge, there's also https://github.com/ring-clojure/ring/pull/115

13:35 gfredericks: I'm gonna have to pipe twice, won't I? SequenceInputStream -> GZIPOutputStream -> SomethingInputStream?

13:36 llasram: Oh, HTTP request, not ring HTTP response

13:36 amalloy: gfredericks: there's also https://github.com/amalloy/ring-gzip-middleware/blob/master/src/ring/middleware/gzip.clj#L38

13:37 i haven't worked out whether this is quite what you need, but it's related

13:37 gfredericks: amalloy: it looks eager

13:37 the doseq in the future

13:37 amalloy: oh, for sure

13:38 well

13:38 but also piped input streams have a limited buffer size, and block if it gets too far ahead

13:38 so it's not quite as eager as you might think

13:38 gfredericks: clojurebot: the doseq in the future |would be| a great name for a rock band

13:38 clojurebot: Ik begrijp

13:38 gfredericks: amalloy: oh that's good to know

13:39 thanks amalloy pjstadig llasram; not sure how I forgot about these

13:40 amalloy: gfredericks: sounds more like a movie or novel title

13:41 gfredericks: and flatland/io has concat-input-streams, so you don't have to deal with SequenceInputStream yourself: https://github.com/ninjudd/io/blob/develop/src/flatland/io/core.clj#L30

13:43 i had forgotten this, but apparently we even make Seqable participate in clojure.java.io, so that you can just call (input-stream [a b c])

13:43 llasram: wha

13:43 What does that even do?

13:44 amalloy: llasram: if a, b, and c are input streams, it yields a nwe input stream which is the concatenation of them

13:45 llasram: Interesting

13:48 semperos: dnolen_: thank you for the feedback (and your continued progress on Om), will give it a look

13:49 danneu: Are there any options for getting a part-time job as a developer?

13:50 dacc: does anyone have a mixed java/clojure lein project working? i tried following these instructions, but precomp compile still does javac -- not sure how to disable that https://github.com/technomancy/leiningen/blob/master/doc/MIXED_PROJECTS.md

13:50 amalloy: i'm pretty sure this universe does contain people who work part-time as developers, danneu

13:50 dacc: (i tried :java-source-paths [] inside the profile)

13:50 .. but i think it's merging anyway. maybe need two profiles

13:51 technomancy: dacc: maybe :prep-tasks ^:replace ["compile"] if you want java that depends on clojure

13:51 dacc: hyPiRion blogged about this a few days ago

13:51 hyPiRion: devn: woah, nice timing there

13:51 dacc: technomancy: thanks i'll look

13:51 hyPiRion: *decc

13:52 dacc: http://hypirion.com/musings/advanced-intermixing-java-clj

13:52 danneu: amalloy: haha, right. I mean to ask what kind of avenues are available? I've never seen a listing for a part-time developer gig.

13:52 Maybe someone here works part-time

13:53 gfredericks: amalloy: a movie or novel based on the rock band of course

13:53 dacc: hyPiRion: cheers, just found it =)

13:53 hyPiRion: You can also do https://github.com/technomancy/leiningen/blob/master/doc/MIXED_PROJECTS.md, but I feel it's a bit over the top if you only need one or two compiled Clojure namespaces before javac

13:53 dacc: hyPiRion: ok thanks

13:54 llasram: Wow, these make Java 8 look like it might actually be a language for programming: http://www.java8.org/

13:58 gfredericks: java is the new clojure

13:58 ystael: looks more like the new scala though

13:58 TimMc: llasram: Hey, maybe now *Clojure* will get method references.

13:59 hyPiRion: gfredericks: what, Java uses s-exps now?

13:59 llasram: TimMc: I'm just going to start actually using https://github.com/llasram/method-fn

14:00 danneu: My Github is mostly a dumping ground for unfinished/exploratory projects from my ~/Code folder. Do yall think it does more damage than it's worth to have sloppy repos when looking for employment?

14:02 technomancy: danneu: no one sensible would penalize you for posting learning projects; you should be judged on your best work, not your early stuff

14:02 jconnolly: i have a private github account where i have what i consider my "please don't judge me for employment on these" private repos

14:02 hyPiRion: danneu: No, but don't use GH as a resume. Insteead, specify some projects you are satisfied with in your resume.

14:02 jconnolly: rather, paid github account

14:02 danneu: What if your best stuff is all running in production?

14:03 rather, the code isn't released

14:03 jconnolly: and proprietary... welcome to my world

14:03 hyPiRion: jconnolly: if it's for yourself only, you could consider using bitbucket

14:03 technomancy: danneu: then you convince folks to relicense it

14:03 jconnolly: hyPiRion: good call.

14:03 TimMc: heh

14:03 technomancy: the idea that your competitors will eat your lunch if they can see it is completely preposterous 90% of the time

14:04 hyPiRion: danneu: either what technomancy said, or you could get a reference from them along with what you have done/do

14:04 jconnolly: we try to carve out parts of our codebase that might be useful to open source, but it's not a mandate by any means

14:04 danneu: technomancy: well, it's stuff i've written and i host it. i just don't like having production code sitting in the open

14:04 technomancy: danneu: well, that's going to make things harder

14:04 ystael: technomancy: what about the idea that competitors will eat your lunch if you spend the necessary time to make it a publishable release?

14:04 TimMc: There's a difference between publishing the source and making a project of it, yeah.

14:05 technomancy: ystael: what's the difference between "publishable" and "high quality"?

14:05 TimMc: "Here's a giant pile of code I've filed the serial numbers off of" vs. "here is a project we are publicly maintaining"

14:06 danneu: yeah, i guess getting a development job isn't magical. i should extract an open source project from my production code so i have something to show.

14:07 technomancy: the project I hack on at work is used by direct competitors

14:07 hyPiRion: danneu: At work, I tend to decouple some parts which seem to be completely irrelevant to what we do from the "main" projects. I then publish those on GH if I get an ok from my boss.

14:07 technomancy: http://blog.appharbor.com/2013/07/01/introducing-realtime-logging

14:07 ystael: technomancy: TimMc and I have been working for some time on a major project that we'd _like_ to open source, but there's a substantial distance between "feature complete for business needs" and "feature complete for the standard we purport to implement". And I don't know that we're going to get the time to traverse that distance.

14:08 technomancy: ystael: I don't understand why feature-completeness is a prerequisite to changing the license

14:09 TimMc: I think the biggest part of open-sourcing it would be teasing out the business logic.

14:09 technomancy: TimMc: which you should be doing anyway, right?

14:10 TimMc: Unfortunately, that's not necessarily what I would get paid to do.

14:10 hyPiRion: technomancy: yes, but time

14:10 technomancy: the things you need to do to make it "presentable" is a subset of the things you need to do for proper engineering

14:11 hyPiRion: sure; "we don't have time to do it properly" is fine, but then you shouldn't be implying that the codebase is something you'd like to show to someone interested in hiring you =)

14:11 hyPiRion: technomancy: It's not fine, but it's stupid bosses and marketing guys assuming we can get stuff done in half a second =/

14:12 technomancy: yeah =(

14:12 TimMc: So let's say we release it, and then someone else submits a big PR to make the code more general. That would probably require a partial rewrite of our business logic to make it mate with the FL/OS component again. That "needlessly" (from a business standpoint) perturbs a service that was doing just fine.

14:13 teslanick: hyPiRion: http://www.youtube.com/watch?v=8xRqXYsksFg

14:13 technomancy: TimMc: it sounds like you're getting other people to pay off your technical debt for you?

14:13 TimMc: Another option is to release it without references to the company so that if it decays or isn't maintained, it doesn't reflect badly on the company. :-P

14:13 technomancy: haha

14:13 TimMc: technomancy: There's debt and there's debt.

14:14 technomancy: well, once it's released, it gives you more leverage to spend time to do the right thing from a technical perspective

14:14 ystael: I don't know that we have enough of an institutional commitment to open source yet to make that a true statement

14:16 TimMc: Yet.

14:16 dacc: i've had opportunities to release internal stuff open source, but the extra effort to get it into a form someone else could reasonably use always seems to come out of my own hide =)

14:18 technomancy: it's not always practical for a given organization, but most of the immediate objections people have to it don't make sense

14:18 and it's a ton easier to do it in the open from the start

14:19 TimMc: llasram: That's the first plausible use of tagged literals I've seen so far.

14:19 llasram: TimMc: Haha

14:20 technomancy: oh dang

14:20 that is very slick

14:21 TimMc: llasram: I mean, (mfi String/toUpperCase) would also work as a macro, but... plausible.

14:21 srruby: I'm running into a case where (= parsed (postwalk identity parsed)) is returning false. parsed is a vector. Am I using postwalk incorrectly?

14:21 sdegutis: Declarative programming? More like declariawesome.

14:21 srruby: parsed is returned by the instaparse parser.

14:22 llasram: TimMc: That's true :-)

14:22 AeroNotix: how to check if a variable is undefined?

14:22 seems like such a silly question

14:22 llasram: AeroNotix: Like find out if a var exists?

14:22 AeroNotix: but isn't there something like: (unbound? ...)

14:22 llasram: yeah

14:23 llasram: Not just?: (nil? (resolve sym))

14:23 AeroNotix: ,(def c) (nil? (resolve sym))

14:23 clojurebot: #'sandbox/c

14:23 AeroNotix: derp

14:23 ,(def c) (nil? (resolve c))

14:23 clojurebot: #'sandbox/c

14:23 AeroNotix: ,(nil (resolve c))

14:23 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0:0)>

14:23 AeroNotix: ffs

14:23 ,(nil? (resolve c))

14:23 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to clojure.lang.Symbol>

14:24 AeroNotix: ,(nil? (resolve 'c))

14:24 clojurebot: false

14:24 llasram: That said, mucking w/ `resolve` etc frequently means you're going against the grain

14:24 What's your use-case?

14:24 AeroNotix: llasram:

14:24 sorry, I've had a few beers. Fat fingers

14:25 llasram: TimMc: That's a really, really good point, actually. Adding those macros now

14:25 AeroNotix: So, a library I use defines a global default connection parameter which it (alter-root-var)'s when a connection is made

14:25 it blindly assumes in some areas that the default connection exists

14:25 (def *default-connection)

14:25 (def *default-connection*)

14:26 perhaps it'd be better to just patch it to give *default-connection* an initial value

14:26 like :omfg-dont-use-me-ffs

14:27 llasram: AeroNotix: Which library is this, so that I may never use it? :-)

14:27 AeroNotix: llasram: no comment.

14:27 llasram: hah, fair enough

14:27 AeroNotix: and I'll bet you already do

14:28 if you do any LOLWEBSCALE work

14:28 llasram: nope

14:28 AeroNotix: ah ok

14:28 llasram: I prefer to store my data in a database

14:28 TimMc: Is there anything like data-writers?

14:28 Somethign that produces tagged literals?

14:28 llasram: TimMc: I think someone had a library... Struggling...

14:28 AeroNotix: llasram: nosql databases are still databases, just ones with differing goal.s

14:29 technomancy: TimMc: why not print-method?

14:29 TimMc: I should answer this question myself actually.

14:29 llasram: It really should work that way though -- some way of getting the tag+literal objects instead of just the printed string form of the same

14:30 AeroNotix: just out of interests sake, *is* there actually a way to see if a variable is unbound

14:30 ?

14:30 danneu: jcromartie: A while back you said you were experimenting with HTML templating libs. Which one did you settle on? I recall you've mentioned Enlive since then.

14:31 TimMc: technomancy: A print-method impl that emits a string with a space in it? :-(

14:31 llasram: AeroNotix: So the var exists, and you just wan to know if it has a root binding already?

14:31 AeroNotix: llasram: exactamundo

14:31 llasram: ,(do (def foo) (.hasRoot #'foo))

14:31 clojurebot: false

14:31 llasram: ,(do (def foo :value) (.hasRoot #'foo))

14:31 clojurebot: true

14:31 AeroNotix: oh .hasRoot

14:31 llasram: cheers

14:31 pjstadig: bound?

14:32 ,(doc bound?)

14:32 clojurebot: "([& vars]); Returns true if all of the vars provided as arguments have any bound value, root or thread-local. Implies that deref'ing the provided vars will succeed. Returns true if no vars are provided."

14:32 llasram: Haha!

14:32 Even better

14:32 jowag: bound?, .hasRoot is undocumented

14:32 AeroNotix: God damnit, I was trying (unbound? ..)

14:32 pjstadig: that won't tell you if it's a root binding

14:32 llasram: That's true

14:32 AeroNotix: ,(def c)

14:32 clojurebot: #'sandbox/c

14:32 pjstadig: for that you'd have to do something like (and (bound? x) (not (thread-bound? x)))

14:32 AeroNotix: ,(bound? c)

14:32 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to clojure.lang.Var>

14:32 AeroNotix: ,(bound? 'c)

14:32 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.Var>

14:33 pjstadig: ,(bound? #'c)

14:33 clojurebot: false

14:33 AeroNotix: hmm ok

14:33 llasram: I'd peeked recently at the implementation of `defonce`, so that's what I remembered

14:33 AeroNotix: llasram: ah of course

14:34 pjstadig: <obligatory mention of (one of) my open Jira issues http://dev.clojure.org/jira/browse/CLJ-1077>

14:35 hugod: is there a list of forms that core.async's go macro supports/doesn't support?

14:35 AeroNotix: hugod:

14:35 misclick

14:36 hugod: just wondering about `for` and `doseq`

14:37 patrkris: is guns (github.com/guns) on this channel?

14:40 danneu: hugod: are you having an issue?

14:41 hugod: danneu: Assert failed: <! used not in (go ...) block, when using (doall (for [c cs] (<! c))) inside a go block

14:42 danneu: hugod: can you gist the code

14:44 hugod: danneu: https://www.refheap.com/37228

14:44 oops, ignore the doseq comment

14:47 replacing the (doall (for …)) with loop works

14:49 Anderkent: ,(require '[clojure.core.async :as a])

14:49 clojurebot: #<FileNotFoundException java.io.FileNotFoundException: Could not locate clojure/core/async__init.class or clojure/core/async.clj on classpath: >

14:49 Anderkent: meh

14:49 anyway

14:49 (go (doall (for [x [1 2 3 4]] (>! c x))))

14:49 has the same issue

14:50 danneu: hugod: i have a weak understanding of core.async and this limitation, but i run into this assert when i have <! nested within anonymous functions, for one. which the `for` macro is rife with.

14:50 Anderkent: seems like core.async macroexpands the body before picking out <!?

14:51 TimMc: patrkris: A user by that name does show up sometimes.

14:51 Anderkent: there's a bot command to say when someone was last seen, right?

14:52 seen guns

14:52 TimMc: last showing up ~4k lines ago

14:52 Anderkent: ,seen guns

14:52 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: seen in this context, compiling:(NO_SOURCE_PATH:0:0)>

14:52 Anderkent: damnit :p

14:52 TimMc: $seen guns

14:52 lazybot: guns was last seen quitting 3 days and 14 hours ago.

14:52 Anderkent: right!

14:52 i'd get there eventually

14:55 hugod: yeah looks like core.async can't work with a for loop

14:55 which is a shame

14:57 danneu: Why doesn't apt-get install leiningen install 2.x

14:57 hugod: Anderkent: Indeed - not sure if that warrants an issue. At least I can use loop.

14:57 danneu: I have no idea how the package ecosystem works

14:58 rplaca: danneu: there's always a lag and it also depends which Ubuntu you have

14:58 danneu: rplaca: I have 13.0x

14:58 rplaca: technomancy would know more

14:58 Anderkent: danneu: because it takes forever to update anything

14:58 in debians repos

14:58 danneu: Ah, got it.

14:59 Anderkent: also I'm not sure if anyone here actually cares

14:59 :P

15:00 danneu: Yeah exactly. I asked because if it was just a matter of sending a pull request somewhere, I'd do it

15:00 Anderkent: nah, it's a Process.

15:06 danneu: I bet it ensnares newcomers frequently. Running `lein` in Ubuntu even tells you to `apt-get install leiningen`. And doing so installs a very incompatible version of leiningen.

15:09 sdegutis: I just learned a new emoticon... :v

15:09 It's that face! Like when you move your lips to the side in a skeptical but lighthearted fashion!

15:10 borkdude: :v

15:14 danneu: someone recently defended their use of the insufferable "%)" as a "programmer-brained optimization" since % combines eyes and a nose into a single character. but i think the real optimization is just ")" which my russian friends all use.

15:15 dacc: >=-)~

15:16 danneu: although they must have paredit-mode disabled in their irc buffer

15:27 akurilin2: Quick question: is it weird to def from within a defn? E.g. I have an "initialize" routine in my ring app where I need to fetch some stuff from a db and initialize a set of vars to the corresponding values (effectively caching some data)

15:28 I'm thinking that running a def from within that init routine would get the job done

15:28 This is a one-time caching and the data isn't expected to change, or I'd use atoms

15:31 dsrx: write once? you could use a promise

15:32 TimMc: akurilin2: def inside a def is basically always bad

15:34 akurilin2: Ok so how do I create a run-time var then that's namespace visible?

15:34 gfredericks: TimMc: yo dawg, I heard you like vars in your vars so I

15:35 akurilin2: This would be only done at initialization time

15:35 stuartsierra: akurilin2: `intern`

15:35 gfredericks: o_O

15:35 TimMc: stuartsierra: What no don't

15:35 stuartsierra: I didn't say it was a good idea.

15:35 TimMc: If someone says "I need to remove this door", you don't hand them a chainsaw.

15:36 ruzu: you don't?

15:36 akurilin2: So you guys are thinking more along the lines of atoms here?

15:36 As far as "good solutions" go?

15:36 rplaca: TimMc: depends how much entertainment you want

15:36 stuartsierra: We already handed them Clojure, what more damage could we possibly do? :)

15:36 TimMc: Fair.

15:36 akurilin2: I think I'm aiming for low entertainment value right now :)

15:36 rplaca: just pr it into a string and `eval` :)

15:37 TimMc: akurilin2: You want your defs out in the open where they are highly visible to readers and to tools.

15:37 Initializing something at startup (with low entertainment value) means you'll need an extra layer of indirection: delay, atom, ref, promise...

15:38 promise sounds like the most useful here

15:39 gfredericks: would stuartsierra make a defrecord and put stuff in there?

15:39 akurilin2: TimMc: ok let me try that one

15:40 stuartsierra: My approach is https://github.com/stuartsierra/component but it is more elaborate.

15:42 SegFaultAX: stuartsierra: Does the capture part of what you described in your blog post?

15:43 gfredericks: stuartsierra: when I tried this style it made me feel a little gross that I couldn't update my record; I don't have any better ideas though

15:43 I don't remember why I would have wanted to

15:43 stuartsierra: gfredericks: Just because the record is immutable doesn't mean it can't contain mutable references like Atoms and Refs.

15:44 SegFaultAX: I'm sorry, I don't understand your question.

15:44 gfredericks: stuartsierra: I know but it feels like a weird mix, since you have to be careful

15:44 about duplicating references to stateful objects

15:44 stuartsierra: gfredericks: Yes, you do have to be careful. The component library is designed to help with that.

15:45 SegFaultAX: stuartsierra: Sorry, that was a fragment. Referring to http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

15:45 gfredericks: stuartsierra: I probably just need to try it with more determination

15:45 SegFaultAX: Is that a library that tries to encapsulate the workflow described in that article?

15:45 TimMc: stuartsierra: I neded multiple instances of your component framework.

15:45 (kidding, kidding)

15:45 sdegutis: How do you verify in your integration tests that business data are never created in an inconsistent or incomplete state?

15:45 stuartsierra: SegFaultAX: The 'component' library is an extension of the ideas expressed in that blog post. They are complementary, but not necessarily dependent on one another.

15:46 SegFaultAX: stuartsierra: Awesome.

15:46 sdegutis: I imagine you use preconditinos and postconditions to verify state within relevant functions?

15:48 gfredericks: stuartsierra: have you combined this with core.async much?

15:49 by which I just mean using both at the same time

15:49 stuartsierra: gfredericks: A little bit, experimentally. There's nothing about the model that forbids it.

15:49 sdegutis: Oh snap, deja vu.

15:52 gfredericks: stuartsierra: yeah; I found myself needing to e.g. shutdown threads that were writing to channels, since they can't tell that the channel has closed, so I had a separate system for managing core.async components, and abandoned the stuartsierra style due to not wanting a confusing hybrid; so currently I don't feel good about anything :/

15:52 TimMc: Could component be used to help provide instancing of namespaces?

15:53 stuartsierra: gfredericks: Assuming the threads themselves are managed by a component lifecycle there should be a place to shut them down correctly.

15:53 TimMc: Not as such, but components behave somewhat like parameterized modules.

15:54 TimMc: Might be close enough.

15:54 stuartsierra: I certainly use them that way.

15:54 gfredericks: stuartsierra: by having the threads poll a flag?

15:55 stuartsierra: gfredericks: That's one option. Or shut down on a 'poison' message. Or have a separate 'shutdown' channel.

15:55 gfredericks: stuartsierra: right. okay I will probably revisit this. thanks.

15:55 stuartsierra: gfredericks: you're welcome

16:00 tjd: I'm trying to output a (defrecord ...) record as edn, but prn is giving the tag as #packagename.type { ... } as opposed to #packagename/type {...}, and as i understand it from the edn spec, tags must contain a prefix component. not sure if the dot qualifies as a prefix componenet

16:05 stuartsierra: tjd: You need a custom printer. clojure.edn doesn't have one yet.

16:06 tjd: cool. can do.

16:06 SegFaultAX: Ah so component is essentially just DI for Clojure?

16:06 (I'm looking over the docs now)

16:07 llasram: tjd: If you just want it to work for individual record types, you can just define `print-method` for that type

16:07 stuartsierra: SegFaultAX: It's a means to achieve DI, yes.

16:08 `cbp: tjd: https://github.com/miner/tagged

16:09 technomancy: danneu: there are people working on lein2 for debian, but the number of dependencies they need to package is huge. also there are issues where the licensing of certain libraries are incorrect that they have to fix before it can be included

16:09 *ahem* and licensing issues with Leiningen itself =/

16:09 tjd: `cbp: oh, awesome! just what i was looking for. thank you.

16:10 danneu: technomancy: thanks

16:31 rhg135: \\

16:31 oops

16:34 dacc: akurilin2: delay is a lazy promise i believe, if that helps

16:44 justin_smith: ,@(delay 1)

16:44 clojurebot: 1

16:47 dacc: or rather, a lazy future

17:03 sdegutis: wow, so functions, very data, much immutable, nice lazy

17:05 socksy: what's the current best practice for deploying something to run on AWS? lein uberjar and java via chef etc? or is there a more idiomatic way?

17:06 technomancy: socksy: uberjar+runit is the way to go

17:08 socksy: forgive my ignorance — is this runit? https://github.com/hw-cookbooks/runit

17:08 technomancy: that's a runit cookbook, yeah

17:09 socksy: what is runit? difficult to google for

17:09 gtrak: is there a way to set AOT bytecode versioning in the project.clj?

17:09 socksy: or is it this? http://smarden.org/runit/

17:10 which would be an odd thing to specify, given ubuntu has upstart and others have sysv/systemd... so I'm guessing that's not what you're referring to

17:10 technomancy: systemd is kind of an eldritch horror, and upstart is pretty limited

17:11 but if your requirements are simple upstart is fine too

17:11 I've used upstart enough to be reluctant to recommend it

17:11 clojars uses it

17:12 socksy: I know systemd is supposed to be terrible, but it also looks to be somewhat ubiquitous in the future :)

17:12 technomancy: distopian nightmare future

17:12 stuartsierra: gtrak: You mean class file versions like JDK 1.5, 1.6? I think Clojure always sets 1.5.

17:13 gtrak: yea, hmm.

17:13 I'm getting Exception in thread "main" java.lang.IncompatibleClassChangeError: Implementing class, comp...

17:13 at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3463) ...

17:14 been playing with java8

17:14 stuartsierra: That's a new one on me.

17:26 * gfredericks runs into the closures+head-holding thing again

17:27 oskarkv: Does anyone know what's going on here? http://stackoverflow.com/questions/21714704/my-logging-with-robert-hooke-does-not-work-properly-with-tools-namespace-refre

17:28 amalloy: i mean, robert.hooke mangles vars, and you replaced those with brand-new non-mangled vars

17:29 brehaut: gfredericks: ive run into javascript + css head-holding again. /me despairs

17:30 amalloy: that's basically all there is to it? it's as if you didn't have robert.hooke at all, after you refresh the values it mucks with

17:30 brehaut: any time i deal with javascript and css i have to hold my own head too

17:32 brehaut: amalloy: responsive design (while a good thing) makes it so much worse :/

17:33 seangrove: brehaut: Doesn't bootstrap pretty much make it a non-issue?

17:33 brehaut: lol

17:34 systemfault: bootscrap...

17:37 brehaut: seangrove: maybe if you are just a developer who needs to ship some stuff on the web then bootstrap is fine. for design agency stuff its not going to fly

17:38 seangrove: however, for basic responsive stuff, bootstrap doesnt really provide anything if you know what you are doing. basic responsive is easy. its complicated the design changes drastically at different breakpoints responsive that is just hard

17:39 oskarkv: amalloy but I run add-hook each time I run the code. It's just that the code that calls add-hook can't even find a var with the correct name in the namespace. In the summary I don't even mention robert hooke

17:44 amalloy Hm, maybe robert hooke has something to do with it anyway. I did just try it for vars that had been subject to robert hooke. But, is there a solution? How do I find the correct vars after refreshing?

17:52 amalloy Hm the problem happens even if I don't use robert.hooke

18:07 gfredericks: brehaut: I predict that by 2017 "slash me" is going to be part of the standard teenager lexicon

18:08 brehaut: gfredericks: they're bound to pickup something far more obtuse

18:08 gfredericks: like "colon slash slash"?

18:09 brehaut: sounds painful

18:09 gfredericks: maybe something from swearjure

18:15 shriphani: hi. any advice on getting the cljs repl to speak to the browser. It takes 5-ish mins to connect.

18:16 pbostrom: shriphani: refresh your browser after connecting the repl

18:16 shriphani: pbostrom, done that

18:17 (+ 1 1) hasn't returned yet

18:17 clojurebot: 2

18:17 pbostrom: sorry that's all I got

18:20 ivan: shriphani: did you try austin?

18:20 shriphani: ivan, no. I am just following the modern-cljs tutorials and I was not sure if it would interfere.

18:20 should I use austin ?

18:20 ivan: probably; not certain it will solve your problem though

18:20 could be a browser issue

18:22 shriphani: so how do I check if it is a browser issue ?

18:22 I restarted my browser

18:22 visited the page in question

18:23 ivan: use the Firefox inspector or Chrome Dev Tools to look for errors; try a clean browser profile

18:25 shriphani: I can open the js file and see the compiled stuff

18:25 in the browser i.e.

18:27 pbostrom: shriphani: you can also look at the network tab to make sure your app is connecting back to the repl

18:27 acron: Hi everyone

18:27 I'm having difficult with clj-mail 0.1.5

18:27 Keep getting the following warning

18:27 Warning: *session* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *session* or change the name. (clj_mail/core.clj:6)

18:28 shriphani: goog.require could not find: domina

18:28 that's neat

18:28 technomancy: acron: probably the library is designed for clojuer 1.2 or older

18:28 acron: Bah :(

18:29 sdegutis: womp womp

18:29 acron: How can I actually see the src?

18:29 The version on github looks like it *does* define session as dynamic...

18:30 https://github.com/MayDaniel/clj-mail/blob/master/src/clj_mail/core.clj

18:30 shriphani: pbostrom, I don't see a repl process

18:33 acron: Alternatively then, can anyone recommend any decent mail libraries?

18:34 pbostrom: shriphani: your cljs source should have (repl/connect "http://localhost:9000/repl") somewhere, and then when you load the compiled js in your browser you should see that connection loaded in the network tab (if using chrome)

18:34 shriphani: yep I have that call to connect

18:34 akurilin2: technomancy: just checking with you: does it make sense that a ring app started with lein trampoline won't pick up changes in checkouts/ ?

18:35 shriphani: so I do lein deps and it checks out

18:35 but it can't find domina

18:35 how is that.

18:35 technomancy: akurilin2: not really, trampolining shouldn't affect the classpath

18:35 it might affect auto-reloads; those are kinda iffy

18:35 but the changes should be visible

18:36 bob2: is there a style consense on which of (:foo somemap) (somemap :foo) and (get somemap :foo) to generally use?

18:37 broquaint: The first is idiomatic, bob2.

18:37 bob2: ah, thank you

18:38 akurilin2: technomancy: yeah I could only see changes in the local dependencies after running lein install

18:38 without trampoline it works just as expectred

18:39 sdegutis: bob2: whoa you're here too

18:39 akurilin2: Not really a dealbreaker for me since in production it uses the local repo anyway

18:39 technomancy: akurilin2: does reading the classpath under `lein trampoline repl` show you src/ of the checkouts?

18:40 bob2: not a coincidence - I've used emacs for like 15 years, and python for 10, and clojure reminds me of a lisped python with a much happier deployment story

18:40 sdegutis: bob2: :)

18:40 bob2: Except that ->> makes it way prettier to transform collections than in Python maybe.

18:41 (oh no he didn't!)

18:41 bob2: yes

18:41 I agree

18:41 finding python increasingly tedious

18:41 gtrak: I had a j2ee job, tried to escape via jython, but jython made me sad... clojure was a nice surprise.

18:41 sdegutis: bob2: Welcome aboard good sir, welcome aboard.

18:41 gtrak: simply because jython was dying and out of date.

18:42 sdegutis: That seems to be an inherent problem with bridges. They're overambitious assuming the maintainers will have infinite steam to keep up.

18:42 bob2: it seems to be a fair bit better off these days

18:42 akurilin2: technomancy: yeah seems like it

18:42 socksy: potentially a silly question, but can I send something to an agent without printing to the terminal? I am doing a lot of these send to update a map and rlwrap is hanging.

18:43 gtrak: socksy: could always wrap it in a (do blah nil)

18:43 bob2: I do wish the jvm had better event-driven network stuff, though, instead of making me throw walls of threads at problems (even if clojure makes the wall much nicer)

18:44 sdegutis: bob2: future?

18:44 gtrak: bob2: taken a look at netty and friends?

18:44 sdegutis: Oh. Yeah never mind.

18:44 I'm thinking of core.async or core.logic or something.

18:44 bob2: gtrak, yeah, netty is the sort of thing, but seemingly has really tedious apis

18:44 core.async just hides the threads from you

18:44 socksy: gtrak: I thought of that, but the way send works is to apply the function to the agent state, and then set the agent to the return value of that applied function. Returning nil will set it to nil

18:45 gtrak: bob2: you'd want aleph maybe, it's a clojure wrapper

18:45 bob2: which is good, I think in most cases you want an abstraction above threads, but when I want to just do 100 000 slowish http requests as quickly as possible, I don't need to block them in threas

18:45 gtrak: not sure where threads have to enter into it

18:45 bob2: gtrak, ah, I had heard of but not looked at it yet - cheers

18:46 gtrak: there's a wrapper over the async httpclient

18:46 bob2: https://github.com/neotyk/http.async.client

18:46 and I think this can do it too: http://http-kit.org/

18:47 you can throw that into core.async without threads in between.

18:47 gfredericks: gtrak: our lunch group (15-20 people) spent an hour playing with your disassembler on monday; great fun

18:47 gtrak: :-)

18:47 I showed it to a group of rubyists last night.

18:48 along with reducers over a proc.

18:48 jruby proc..

18:48 gfredericks: do you know why (disassemble (def foo 42)) is so crazy? is it disassemble's fault or def's fault?

18:48 gtrak: hrm.. well it would be disassembling the return value, which is the var, yea?

18:48 bob2: ah, it wasn't clear to me based on http://martintrojer.github.io/clojure/2013/07/07/coreasync-and-blocking-io/#httpkit whether go-ing httpkit was sensible or not

18:48 gfredericks: I guess; don't know what that means wrt what it will do though :)

18:49 gtrak: Var.java would be the thing

18:49 that is disassembled

18:49 it's got a lot of stuff in it

18:50 bob2: he's using a go block in the callback.

18:53 gfredericks: it was the most heinous thing I could think of in a short amount of time: https://github.com/gtrak/jvmrubyists/blob/master/src/jvmrubyists/core.clj#L129

18:54 bob2: is there anything sensible to point flymake at for clojure code?

18:54 sdegutis: Hmm, I've never used flymake.

18:55 bob2: I can't think of anything offhand. Even if there were, they'd probably require loading a new JVM just to work, unideal for this task.

18:55 bob2: well, I'm ok with telling cider to load ma file and do a thing to it

18:55 or having cider run something

18:56 gtrak: bob2: if you can think of a good nrepl middleware, it goes here: https://github.com/clojure-emacs/cider-nrepl

18:56 bob2: basically, I don't want to find out about typoes at 'lein test' time

18:57 sdegutis: Hmm, you may be able to write a little function that tries calling "(read)" on whatever Clojure forms you give it, and report on the error it gieves.

18:57 Sounds like it could work, with a smart enough mind.

19:00 justin_smith: bob2: maybe lein check?

19:01 bob2: justin_smith, can I invoke that in the repl?

19:01 justin_smith: well, you could just have a dedicated process that calls load on the file

19:02 technomancy: doesn't flymake assume you'll keep going after a compilation failure?

19:02 justin_smith: you likely wouldn't what to do that in a repl that you were using for general interaction though

19:02 technomancy: I think it re-invokes when you save?

19:02 could be wrong

19:03 technomancy: yeah, I guess only getting one failure at a time isn't a big deal

19:04 bob2: ah, 'lein check' just does a load on each file anyway

19:04 justin_smith: https://github.com/illusori/emacs-flymake oh, someone's been improving flymake

19:05 and I guess it's not just a question of running when it saves, - though with clojure, for sanity's sake, you may want to only capture / only check when you have balanced forms

19:05 bob2: yeah, it's a lot better than it used to be

19:05 technomancy: check also turns warn-on-reflection on

19:06 justin_smith: shouldn't be too hard to launch a grench load with warn-on-reflection

19:06 bob2: can I have something else show me unbalanced forms? paredit mode only seems to complain when I'm on the form

19:06 justin_smith: with the load being done on a temp file derived from the state of the buffer

19:06 technomancy: bob2: reindenting helps with that

19:07 bob2: technomancy, hm, what specifically do you mean?

19:07 justin_smith: hit tab to make emacs indent the line

19:07 if it indents weird, your parens are weird

19:08 bob2: hah

19:08 justin_smith: (or indent-buffer, indent-region etc.)

19:08 bob2: it's usually the trailing ones that are screwed for me

19:08 technomancy: if you don't close your parens, the next defn will not be in column zero

19:08 justin_smith: bob2: indent-buffer will make trailing parens indent other forms afterward

19:08 (missing trailing parens that is)

19:08 bob2: true

19:09 justin_smith: looks like as far as I can tell flymake is still not modular - though that doesn't mean it wouldn't be hard to add a new flymake setup from the outside

19:09 bob2: I guess I really want what I had for python - run flake8 from flymake and it'll show syntaxerrors, indentation errors, unused imports, some style mistakes

19:10 justin_smith: maybe you want kibit

19:10 bob2: I want it even more now 'lein checkall && lein test' takes 10x longer than 'nose' did

19:10 justin_smith: https://github.com/jonase/kibit

19:10 bob2: I use kibit, it's more about a) having it overlay the buffers, as the awesome clojure-test stuff does, and b) not eating jvm start time so often

19:11 justin_smith: be sure to turn on the option that emails technomancy to tell him you are using when for the return value

19:11 so he can judge you

19:11 technomancy: M-x look-of-disapproval

19:11 bob2: that sounds like a great fit for nrepl-discover actually

19:11 http://p.hagelb.org/clojurewest-2014.org.html

19:12 justin_smith: bob2: I'd say whatever you want to flymake, you need to extend flymake for that tool, just suggesting kibit could be a tool / the tool to use

19:12 bob2: technomancy, yeah, you mentioned it yesterday, was hoping there'd be code today ;p

19:12 justin_smith, right

19:12 technomancy: there's code!

19:12 https://github.com/technomancy/nrepl-discover

19:12 it's kind of scattered all over the place

19:14 bob2: oh, awesome

19:18 technomancy, ah, btw, nrepl-discover.el is lacking a dep on nrepl

19:18 technomancy: ah, thanks

19:20 bob2: probably a stupid question, but is cider a fork of nrepl, and both are maintained?

19:20 technomancy: it's just a rename

19:20 bob2: ah

19:21 dsrx: it's a rename along with a hundreds of comments long bikeshedding issue deciding on a new logo

19:21 bob2: obviously

19:21 gotta tackle the big issues first

19:22 what action will trigger 'lein' to install dependencies listed in ~/.lein/profiles.clj {:user {:dependencies ?

19:22 technomancy: bob2: anything calculating the classpath

19:22 run, compile, check, test, classpath, deps, maybe more

19:25 bob2: http://bpaste.net/show/gBq1mDKPdh8RTHGQk6Wt/

19:26 technomancy: bob2: miiiiight need to lein install from source

19:26 bit of a mess right now; sorry

19:26 simplest actualyl to just `lein repl` in the nrepl-discover project itself

19:27 bob2: oh, no worries, just interested in trying to implement the stuff above :)

19:29 hah, Exception in thread "main" java.lang.UnsupportedOperationException: nth not supported on this type: core$require

19:30 amalloy: bob2: (ns foo require ...) instead of (ns foo (require ...))

19:31 from your tone i think you knew that already, but just in case

19:31 or, well, i guess that would be a different error, wouldn't it. i'm curious what was actually wrong

19:36 bob2: ah, I see what's happening

19:38 missing char in instructions, and me missing that I need to do 'lein repl' in the source before I can edit profile.clj :)

19:39 nrepl.discover.sample still seems unimportable

19:42 technomancy: bob2: are you running 0.1.0? that one doesn't have that ns; you need master

19:43 benkay: so I have a vector of byte-arrays, and I'm failing to come up with a sensible way to collapse them into a single large byte array short of iterating across each byte in each array and aset-byte'ing everything. what's a better way to accomplish what i'm trying to do here?

19:44 bob2: technomancy, yeah, this is 'lein repl' in master of it

19:45 technomancy: weird

19:47 bob2: erk, I lie, sorry - 'lein repl' is fine, it's requiring nrepl.discover.sample that fails, and that's one of the lines the README.md suggests putting in profile.clj

19:50 socksy: playing with agents some more, I don't think I'm fully understanding them

19:50 in this mock example, it prints "{}" — how come? https://www.refheap.com/37614

19:51 amalloy: benkay: https://github.com/ninjudd/io/blob/develop/src/flatland/io/core.clj#L50

19:52 i don't remember if it's perfectly optimized or has some unnecessary slowness, but it does exactly what you wanted, at least

19:52 benkay: oooooo

19:52 thanks amalloy

19:54 amalloy: second time today someone's wanted a function that already exists in flatland/io. weird

19:59 ninjudd: amalloy: good thing i didn't delete that repo yesterday. i was wondering why it existed

20:04 socksy: just realised map is done lazily, so putting a doall around it solves the example I gave

20:04 * socksy feels like a bit of an idiot

20:13 kristof: java 8 has first class functions, zomg

20:13 sdegutis: I have an overwhelming urge to post only serious deep thoughts on reddit and only funny gifs on hackernews.

20:13 kristof: will clojure's compiler get a deep refactoring accordingly?

20:15 technomancy: kristof: no; clojure is a long way away from requiring java7 features, much less java 8

20:15 kristof: oh okay :(

20:18 bob2: sdegutis, wouldn't want to the lower the considered and open tone of hn like that

20:20 sdegutis: I think it's some weird kind of existential angst mixed with disillusionment settling in, possibly caused by burnout.

20:24 kristof: programmer burns out

20:24 posts gifs to hn

20:24 sounds reasonable.

20:29 sdegutis: the serious deep thoughts to reddit is more far-fetched to me

20:29 dacc: project lambda just looks like syntax sugar for Callable and friends, no? well, besides the additions to the library.

20:33 amalloy: "just"

20:33 dacc: yeah, i guess that's all it takes...

20:34 was trying to clarify if kristof knew of some jvm optimizations for it clojure could take advantage of

20:35 amalloy: the clojure compiler will probably never see any large changes to its java code again. it works, and nobody wants to do lots of work to it; if anyone does decide to put in effort like that, they'll probably port it to clojure instead

20:36 dacc: and of course (fn [x] (* 2 x)) is "just" syntax sugar for (reify clojure.lang.IFn (invoke [this] (throw (ArityException. ...)) (invoke [this x] (* 2 x)) (invoke [this x] (throw (ArityException. ...))) ...)

20:37 dacc: wasn't trying to belittle syntax sugar, by any means =)

20:39 gfredericks: syntax protein

20:46 aka: any opinions on enlive vs hivvup for my first clojure web dev project?

20:47 brehaut: aka: hiccup is simpler to grasp, enlive is a more powerful abstraction but harder to get into

20:53 aka: enlive looks like an awesome solution especially since I have a designer providing static html pages. I guess I'm just gonna have to give enlive a whirl.

20:54 see if I can grok it quickly or not

21:08 holo: hi

21:08 oskarkv: hi

21:09 holo: I have a simple (heh) question: why keep is called that way?

21:09 dacc: holo: called how?

21:09 holo: dacc, keep

21:10 gfredericks: I think dacc means why is it named that

21:10 dacc: ooh i see

21:10 gfredericks: or holo means

21:10 holo: gfredericks, yes it's me :D

21:10 dacc: hmm, i guess it returns the keepers =)

21:11 clojurebot?

21:11 clojurebot: clojurebot is not very good at indicating the difference between a return value and an exception

21:11 dacc: hmm, how to have him evaluate things?

21:11 gfredericks: ~keep

21:11 clojurebot: It's greek to me.

21:11 gfredericks: ,(str 'evaluate :things)

21:11 clojurebot: "evaluate:things"

21:11 dacc: ,(keep identity [1 nil 2 nil 3])

21:11 clojurebot: (1 2 3)

21:11 dacc: cool

21:12 holo: oh i see.. that's a good mnemonic :D

Logging service provided by n01se.net