#clojure log - Feb 18 2014

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

0:25 logic_prog: where is tbaldridge?

0:25 I have a core.async question

0:25 ,(ns-lookup 'clojure-wizards 'tbaldridge)

0:25 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ns-lookup in this context, compiling:(NO_SOURCE_PATH:0:0)>

0:25 logic_prog: ,(ns-find 'clojure-sages 'tbaldridge)

0:26 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ns-find in this context, compiling:(NO_SOURCE_PATH:0:0)>

0:31 ddellacosta: logic_prog: why don't you ask your question and see if anyone else can answer it

0:32 logic_prog: sure, https://groups.google.com/forum/#!topic/clojure/ApJPmJfijpU :-)

1:14 kyled: Hey there! I'm trying to figure out the best way to determine how deep a list goes.

1:15 http://pastebin.com/raw.php?i=FjzZE1fv is the answer I came up with . I want to make it more succinct, and smaller if possible, any ideas?

1:15 can the howDeep function be re factored into a tail-recursion call somehow?

1:18 dsrx: ,(max 10 5)

1:18 clojurebot: 10

1:19 sm0ke: ,(def max min)

1:19 clojurebot: #<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)>

1:19 kyled: o, one lass function definition is always good =)

1:23 technically, i think i can remove the (if (seq? fl) part

1:24 so for (if (nil? .. i can just ask (if (notSeq? )) maybe

1:25 TEttinger: kyled, maybe take a look at how core.matrix does it

1:25 kyled: Tettinger: will do! =) thanks

1:26 TEttinger: https://github.com/mikera/core.matrix/blob/develop/src/main/clojure/clojure/core/matrix/impl/sequence.clj hm...

1:27 https://github.com/mikera/core.matrix/blob/develop/src/main/clojure/clojure/core/matrix/impl/sequence.clj#L89 they do it by recursively checking each dimension, I believe scalars return 0

1:42 seangrove: It's infuriating that most of the html5 tags don't seem to work with attributes properly

1:42 You have to call audioTag.mute() rather than <audio muted="true" />

1:56 kyled: TEttinger: whoops, didn't see your reply, willl look at the links =)

2:39 szymanowski: is there a way to test arity of an anonymous function in clojure?

2:39 devn: ,(#(count %&) 1 2 3 4 5)

2:40 clojurebot: 5

2:40 amalloy: szymanowski: no

2:40 voldyman: ,(count (list 1 2 3 4 5))

2:40 clojurebot: 5

2:43 szymanowski: i'm trying to build an higher-order-fun that behaves differently accordingly to the arity of the given function

2:43 does it make sense?

2:43 devn: (defn foo ([x] ...) ([x y] ...) ([x y z] ...))

2:44 szymanowski: yes i know this construct :) but it doesn't help

2:44 s

2:50 sm0ke: szymanowski: you can write a macro which counts the arity

2:50 but it can be hairy if destructuring is involved

2:50 szymanowski: great, i will check this, thank you

3:14 fredyr: szymanowski: simplest would be to just wrap a macro to convert the args to a vector

3:14 (defmacro wrapper [& rest] ..)

3:16 szymanowski: i will try that, thank you

3:16 fredyr: oh, ofc you don't need to use a macro at all

3:16 & rest works on defn just as fine

3:16 lazybot: ⇒ #<core$rest clojure.core$rest@2835c8>

3:18 fredyr: (defn sum-times-nargs [& xs] (* (count xs) (reduce + xs)))

3:18 ,(defn sum-times-nargs [& xs] (* (count xs) (reduce + xs)))

3:18 clojurebot: #'sandbox/sum-times-nargs

3:19 fredyr: ,(sum-times-nargs 1 1 1 1 1)

3:19 clojurebot: 25

3:19 TEttinger: nice fredyr

3:19 (inc fredyr)

3:19 lazybot: ⇒ 4

3:19 fredyr: :)

3:28 amalloy: you guys know you're not solving szymanowski's problem at all, right? he wants a function or macro arity, such that (let [f #(inc %), g #(+ % %2)] (map arity [f g])) returns [1 2]

3:28 which he can't have because functions don't know their arity

3:28 szymanowski: actually the thing i'm trying to do is: (arity (fn [a b] ... )) => 2

3:28 ok

3:29 thank you amalloy :)

3:29 amalloy: szymanowski: i don't really believe that's what you want, because it only works if you put the lambda literal right inside the arity call (ie, in a context where you already know it takes two args)

3:29 (let [f (fn [a b])] (arity f)) => 2 ;; you want this too, right?

3:30 szymanowski: yes!

3:30 amalloy: right. that's what you can't have

3:30 fredyr: (dec fredyr)

3:30 lazybot: You can't adjust your own karma.

3:30 szymanowski: ok :)

3:30 fredyr: :/

3:30 amalloy: you can have the easy version, which only works if you already know the answer :)

3:30 TEttinger: (dec fredyr)

3:30 lazybot: ⇒ 3

3:31 TEttinger: there's always call with 21 args, then 20, then 19, catching all the exceptions it throws. but I wouldn't recommend it

3:31 szymanowski: wow sounds dirty

3:31 amalloy: TEttinger: but what if the function accepts 8 args, and then throws an arityexception because it called something else with the wrong number of args?

3:31 or when you call it with 20 args it deletes your hard drive

3:32 szymanowski: :)

3:32 Pupnik_: who do + and * give 0 and 1 with 0 parameters?

3:33 eliyak: maths

3:33 amalloy: because those are the answers that make sense, Pupnik_. 0 is the additive identity, and 1 the multiplicative identity

3:34 Pupnik_: thanks

3:35 eliyak: szymanowski: maybe this will be useful : http://stackoverflow.com/questions/3782970/how-can-i-display-the-definition-of-a-function-in-clojure-at-the-repl

3:39 szymanowski: thank you but i do not want to know the arity for myself calling the function, i want to know it when this function is passed to an higher-order-fun in order to make differents things based on the arity

3:39 atyz: Hey all. I'm using a -> macro but I need to change the position of the value being passed around teh function. i seem to remember there being an as-> or something whcih allows you to define a var for the value being passed around. Does anyone recall this?

3:39 szymanowski: (as-> 1 x (inc x))

3:41 fredyr: ,(doc as->)

3:41 clojurebot: "([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form."

3:42 fredyr: or the diamond wand in swiss arrows, if you're looking for something even more funky

3:44 zoldar: szymanowski: do you have any practical example of a situation where a dispatch on arity would be needed?

3:45 eliyak: szymanowski: if you have control over all the functions involved, you could keep a record of how many args each takes in a Map. not sure if that's practical

3:47 szymanowski: the function that i want to implement maps over a hash-map, if single arity fun is passed then apply this fun to all keys and all values, else if the given fun is arity two, map each map entries with it

3:50 https://www.refheap.com/41209

3:50 i would like to merge those two functions

3:53 TEttinger: szymanowski, what about fns that take 1 arg or 2 args

3:53 or variable args

3:53 szymanowski: https://www.refheap.com/41209

3:53 just edit my paste

3:53 one helper function was missing

3:53 zoldar: szymanowski: just by the way, are you aware of reduce-kv?

3:54 szymanowski: i probably have to check that know

3:56 TEttinger: szymanowski, they seem like different concepts

3:56 not sure why you'd even want them under the same name

3:56 szymanowski: maybe you're right

3:56 :)

4:06 TEttinger: my interpretation would be ##(let [kv-map (fn [f coll] (into {} (mapv (fn [[& kv]] (mapv f kv)) coll)))] (kv-map inc {1 10 2 20 3 31}))

4:06 lazybot: ⇒ {2 11, 3 21, 4 32}

4:12 dsrx: test test #(+ 1 3)

4:12 test test ##(+ 1 3)

4:12 lazybot: ⇒ 4

4:12 TEttinger: hey dsantiago

4:12 dsrx sorry

4:13 dsrx: ###(+ 1 %)

4:13 lazybot: ⇒ #<sandbox12094$eval21574$fn__21575 sandbox12094$eval21574$fn__21575@f21ab5>

4:13 dsrx: hello

4:13 TEttinger: ,``[]

4:13 clojurebot: (clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat)))

4:52 allenj12: hey im making a centroid fucntion and im a little stuck.. what would be the best way of taking in a vec of points [[1 1] [2 2] [3 5]] and returning the corresponding sums [6 8]

4:52 bars0: Hi all. I try to run nrepl in emacs but I got: "Lisp error: (wrong type argument stringp nil) get-buffer(nil) nrepl-sentile(#<process nrepl> "connection broken by remote peer"

4:53 I've copied my .emacs.d from windows to centos

4:53 on windows I hava oracle java 32 and on centos openjdk 64

4:53 Seems like emacs cannot get buffer name of nrepl

4:54 does anybody have same problem?

4:58 ivan: allenj12: (let [points [[1 1] [2 2] [3 5]]] [(reduce + (map first points)) (reduce + (map second points))])

4:58 bars0: Ok, when I start nrepl like this: M-x nrepl-jack-in, nrepl starts. But when I open .clj file first and then C-c M-j I've got error mentioned.

4:58 ivan: now wait a few seconds for someone to code golf that

4:59 allenj12: ivan: only works with specific dimension tho,

5:01 ivan: ,(mapv #(reduce + %) (let [points [[1 1] [2 2] [3 5]]] (apply map vector points))) ; allenj12

5:01 clojurebot: [6 8]

5:02 allenj12: ivan: that will work!

5:10 quizdr: i'm trying to figure out how to require a namespace with an alias, except for one function, which is refer

5:13 alew: (:require [my.namespace :as me]) ?

5:14 quizdr: alew i figured it out. it uses both :as and :refer

5:15 (:require [namesp :as myalias :refer [somefn]])

5:26 voldyman: how salable is hiccup? my web app will get 500 concurrent users for about an hour, i don't want it to fail

5:26 AeroNotix: what webserver does it user internally?

5:26 or is it something custom?

5:26 He

5:26 Jetty will handle that with ease

5:26 voldyman: i'll run ningx in the front and lein ring uberjar

5:27 since its luminus its jetty.

5:27 AeroNotix: So should be fine.

5:27 voldyman: AeroNotix: the only problem i faced was very high CPU usage when testing on my computer

5:27 AeroNotix: how did you test?

5:27 how did you generate load?

5:27 if it's all local, then you fail hard.

5:27 voldyman: umm, wrote a script to fetch 4 pages * 200 users concurrently

5:28 AeroNotix: Fail

5:28 you cannot test webservers all on the same box and expect to find any meaninful results.

5:28 voldyman: AeroNotix: why?

5:28 AeroNotix: ^

5:28 voldyman: i tried to run the same thing on a remote server to which caused the server to terminate the java process

5:28 AeroNotix: well this is different

5:29 You mean you ran the jar remotely and generated load locally ?

5:29 voldyman: yes

5:29 AeroNotix: And what was the stacktracE?

5:29 voldyman: there was none, it was a message like [memory limit reached]

5:30 AeroNotix: What was the spec of the remote machine?

5:30 voldyman: (there was no nignx in front though)

5:30 its a shared server, i plan to run this on a cheap 5$ VPS (512mb ram)

5:30 AeroNotix: Jetty uses a thread pool to scale load, afaik. So high peaks may cause high numbers of threads to spawn (do NOT quote me on that.)

5:31 512mb ram for a JVM process is not going to cut it

5:31 voldyman: jvisualvm agrees with you

5:31 AeroNotix: *especially* if you have high numbers of concurrent users

5:31 voldyman: AeroNotix: where should i deploy, running cost is a bit thing

5:31 AeroNotix: Why?

5:31 clojurebot: Why is the ram gone

5:31 AeroNotix: if you have high peak, you have a need to spend money.

5:32 You can't have ponies

5:32 I would at least have 2gb for a server running a jvm process.

5:33 voldyman: AeroNotix: what specs would you recommend? or a PaaS?

5:33 oh, that would be too costly

5:33 AeroNotix: AWS using whichever is 2GB.

5:33 voldyman: what's the application doing?

5:33 a 2GB box is pittance

5:33 voldyman: mostly fetching data from a sqlite db and generating hiccup/json response

5:34 (i plan to move to Postgres or mysql later)

5:34 AeroNotix: voldyman: you know sqlite doesn't deal with concurrency well, right?

5:34 voldyman: yes,

5:34 AeroNotix: Good.

5:34 voldyman: its just for testing, can easily swap db's

5:34 AeroNotix: So, you have to choose between price and performance. You cannot, cannot, cannot, cannot have both.

5:34 There are no free ponies in programming.

5:35 voldyman: AeroNotix: the only thing that bothers me is that if this were written in php or python, i wouldn't have faced any problems

5:35 AeroNotix: voldyman: you would also be writing in PHP

5:35 so there's that

5:36 * voldyman hasn't written php in many years

5:36 AeroNotix: It's an inherent problem with the JVM, very well known.

5:36 voldyman: i wanted to use lisp for real world applications but as you said there are no free ponies

5:36 *too well known*

5:36 AeroNotix: Exactly. You're making the choice between horrible languages (Python's ok though) and a somewhat higher system requirements

5:37 voldyman: :( i spent a week writing this one and had planned another that was supposed to start an hour a go

5:38 AeroNotix: voldyman: just get a m3.medium on AWS. It's really cheap

5:39 Anderkent: AeroNotix: depending on the type of threadpools, peaks might either spawn additional threads or simply queue more jobs for the existing threads to pick up

5:39 AeroNotix: Anderkent: gotcha, ok

5:41 voldyman: AeroNotix: so to conclude, Jetty can handle 1000 connections easily, it just needs loads of RAM (?)

5:41 Anderkent: and yeah, I agree with the 2gb recommendation. Memory is cheap

5:41 AeroNotix: voldyman: pretty much, but 2gb isn't 'loads'

5:41 it's a pretty trivial amount of memory

5:41 Anderkent: It's not even that. There's just a significant memory overhead; I wouldn't expect 1000 connections to eat much more ram than 10

5:41 AeroNotix: voldyman: is this a school project or something you don't have business funding for?

5:42 Anderkent: but running jvm on 512mb is an exercise in futility

5:42 voldyman: college project. no funding

5:42 Anderkent: run it on your home machine? :P

5:42 AeroNotix: Nice idea

5:42 zilti: Is there a way to execute a piece of code on the main thread while I'm on another thread?

5:42 voldyman: its for conducting tests around the college

5:43 (+ i am in india, so internet is not good enough)

5:43 AeroNotix: Unfortunate but that is just your roll of the die in this world.

5:43 Anderkent: zilti: you'd have to have the main thread watch some kind of queue and pick up tasks from it.

5:43 voldyman: I think you can find a 2 gb vps much cheaper than amazon

5:44 AeroNotix: Digitalocean's is $20/mo

5:44 voldyman: Anderkent: that would be awesome

5:44 Anderkent: I'd expect 10$ / mo at most, probably 5

5:44 AeroNotix: Anderkent: lolwat

5:44 where?

5:44 clojurebot: see logs

5:44 zilti: Because the problem I have is that Clojure seems to lose track of what's "require"d as soon as I'm on another thread

5:44 AeroNotix: zilti: post evidence

5:45 Anderkent: zilti: that's unlikely; are you maybe switching namespaces?

5:45 voldyman: oh shit, Anderkent i could run it on 5$ instance most of the time and switch to 2Gig instance and use hourly rantes

5:45 Anderkent: AeroNotix: quick google brings up http://www.2gbvps.com/ for example

5:45 zilti: AeroNotix: Well if this is not the normal behaviour (other thread wasn't started by Clojure code) then I have a problem with my code ^^

5:45 llasram: zilti: Which namespaces are loaded is definitely global

5:45 voldyman: Digitalocean 2gig vps is 0.030$/hr

5:46 llasram: zilti: How is the other thread started?

5:46 Anderkent: llasram: doesn't clojure use its own classloaders though?

5:46 if you start a thread in java you might not have access to that classloader? not sure, guessing here

5:46 llasram: There are some weird situations you can get into if you start calling Clojure code before the Clojure runtime is initialized (static class initializer)

5:46 zilti: llasram: If I haven't overlooked anything, by the Reactor framework (using Meltdown)

5:47 llasram: Anderkent: the custom class loaders are only used for defrecord/deftype by-name classes. You can get yourself in trouble with AOTed references to named classes, but normally not

5:47 zilti: llasram: So what's happening is that I have a function that gets called in a Meltdown thread apparently, and when evaluating code there Clojure can't resolve symbols relying on "require" statements in the ns-form

5:48 AeroNotix: zilti: can you reduce it to a test case?

5:48 llasram: zilti: By "evaluating" do you mean literally "calling `eval`"?

5:48 zilti: AeroNotix: Oof. Could get very tricky

5:48 llasram: Yes.

5:50 Anderkent: voldyman: AeroNotix: https://bluevm.com/cart.php?gid=42 scroll down to BLUE4, 2gb for $7USD/mo

5:50 llasram: zilti: Ah. Yeah, so the current namespace _is_ a per-thread-binding dynamic var (`*ns*`), and there is some complexity there.

5:50 * llasram needs to drink the rest of his coffee

5:50 zilti: llasram: Okay... Well I get back to tinkering around then. Thanks!

5:51 AeroNotix: Anderkent: and do you have root access on those?

5:51 Anderkent: AeroNotix: don't know

5:51 voldyman: Anderkent: woah thanks.

5:51 Anderkent: I mean I assume you get what you pay for, i.e. not much :P

5:51 llasram: zilti: Oh, no need to wander off. I just need to drink some more of this coffee before remembering how this works w/ `eval` :-)

5:51 AeroNotix: I'd probably re-evaluate whether I need eval in the first place.

5:51 Anderkent: llasram: zilti: surely (eval '(do (in-ns 'my.ns) (magic))) should work then?

5:52 llasram: Anderkent: Probably

5:52 zilti: Anderkent: Thanks, I'll try that!

5:52 llasram: Oh, no!

5:52 Well, maybe

5:53 AeroNotix: zilti: can you not solve the problem without eval?

5:53 zilti: llasram: ??

5:53 lazybot: zilti: Uh, no. Why would you even ask?

5:53 llasram: So in normal Clojure code you use syntax-quote, and the forms are expanded to the namespace active at compile time

5:53 So even though *ns* might be some arbitrary other namespace when `eval` actually runs, all the symbols are already expanded to point at what was available in the namespace of the code containing the `eval`

5:54 Anderkent: ha, fair point

5:55 zilti: AeroNotix: Hmm. Maybe, I don't know... I'd have to rewrite a lot of stuff

5:57 llasram: Anderkent: Quick REPL-checking suggests your approach works, which makes sense. If the symbols are not namespaced and not locals, the compiler resolves them against *ns*, and the `do` hack causes the compiler to consider each form w/in a `do` as a separate top-level form

5:57 zilti: So there you go! I am also curious though -- why `eval`?

5:58 zilti: Anderkent: Usin "in-ns" now gives me "IllegalStateException: Can't change/establish root binding of: *ns* with set"

5:58 Anderkent: llasram: but you'd expect it to work without (in-ns) if I used ` instead of '

5:59 zilti: llasram: Well I have a helper macro that writes a function which in turn uses the arguments given to add them to the code before evaluating it

5:59 llasram: zilti: Why not just have the macro-expanded code be compiled normally?

5:59 zilti: llasram: Here's the macro in question: https://www.refheap.com/41226

6:00 llasram: Oh my. You do not want this

6:00 zilti: Hmm.

6:01 Anderkent: ,(.start (Thread. (fn [] (eval '(do (in-ns 'user) (println 'foo))))))

6:01 clojurebot: #<SecurityException java.lang.SecurityException: no threads please>

6:01 Anderkent: bah

6:01 anyway, that's a repro

6:01 llasram: zilti: You're using a macro to generate a function which calls `eval` every time the function is invoked?

6:01 zilti: llasram: Yes, it's invoked once for every UI element it has to generate

6:02 llasram: What is it about creating these elements which necessitates `eval`?

6:03 zilti: llasram: Basically 1. calling "cell" with the argument id# and 2. replacing those :%ID% things.

6:04 llasram: Ok, but why can't you do that in a function?

6:04 Why do you need to `eval` new code?

6:04 zilti: Well how else can I do it when I want to do it inside that macro?

6:05 AeroNotix: just call the function?

6:07 llasram: zilti: Maybe it would help if you also show an example use of this macro

6:10 zilti: llasram: Updated https://www.refheap.com/41226

6:12 llasram: zilti: I don't believe anything in the macro needs to be a macro, or the evals need to be evals

6:13 The pre-walk for the `cell` forms could just be a local function. The `%ID%` could just be a normal local identifier

6:14 zilti: llasram: How a local function? The 'cell' forms aren't necessarily on the top level, they can be scattered throughout a nested form

6:16 llasram: Yes, but lexically within the form. If that whole form were in a function which took a function-argument `cell`, then your `(cell ...)` forms would just be calls to that function

6:18 If you want to just hack `eval` to work -- you can try wrapping at some level with something like `(binding [*ns* *ns*] ...)`

6:18 But I think you're very much on the wrong track

6:18 zilti: llasram: You mean that the "cell" forms would be calls to another function (which they already are btw, cell is a function) to retrieve the id? I'd imagine hell of a lot of messy code for that?

6:19 llasram: zilti: Uh. Versus a macro which creates a `defn` which calls `eval`? :-)

6:20 zilti: llasram: about 20 lines of code versus probably 50 lines of complicated code?

6:21 llasram: Point is I can't really imagine what you have in mind

6:21 llasram: Alas, for lack of telepathy. I've exhausted my IRC helpfulness budget for the morning, I'm afraid, so at this point must just wish you luck!

6:22 zilti: Thanks

6:34 AeroNotix: is anyone using lein-ver?

6:35 I'm having trouble with it telling me it cannot find the VERSION file in an uberjar

6:35 llasram: AeroNotix: Well, is VERSION ending up in your uberjar :-)

6:36 AeroNotix: llasram: looks like it, let me triple chjeck

6:37 llasram: Huh. That's an odd plugin. I'm not quite clear on the value

6:37 AeroNotix: llasram: it makes programmatically bumping versions easier

6:37 so I can have my CI do the release/tag/deploy cycle for me

6:37 and then be able to inject the version into my release artefact, too

6:37 (well that's the idea)

6:38 llasram: So you let your CI system determine the version to release the artifact?

6:38 AeroNotix: llasram: no, my CI bumps the :patch version and deploys to stage

6:38 I manually bump :minor/:major depending

6:38 :minor when I release to prod

6:38 :major when we hit a new release stage

6:39 llasram: Well, I consider bumping the minor to be "determining the version," but point taken

6:40 Is that how your CI/deploy/release cycle works for other languages?

6:40 AeroNotix: llasram: kind of, we homegrew the tooling for that since there are no tools out there for it (Erlang)

6:40 llasram: and yes, the VERSION file is in the jar

6:41 I jar xf'd the jar file and even read the VERSION file. So it's there.

6:41 Caused by: java.lang.IllegalArgumentException: Not a file: jar:file:/home/xeno/dev/payments/target/payments-0.0.1-standalone.jar!/VERSION

6:41 sm0ke: hello hello

6:41 AeroNotix: llasram: I wonder what that !/ comes from?

6:42 llasram: AeroNotix: That's the syntax Java overlays on URLs to indicate a file w/in a jar

6:42 AeroNotix: llasram: ok, but the file is there.

6:42 llasram: But the error points at the problem

6:43 AeroNotix: llasram: which is?

6:43 llasram: The entry is in the JAR and (presumably) accessible by the URL, but is not a *file*

6:43 File == OS file on a filesystem

6:43 AeroNotix: ok

6:44 hmm, so I think maybe this project didn't test with uberjars?

6:44 because it works in `lein repl'

6:45 as in, it should use getClass().getResource(...)

6:45 llasram: That seems very likely -- This code is broken: https://github.com/jgrocho/lein-ver/blob/master/src/lein_ver/version.clj#L5

6:45 AeroNotix: Well, it needs to do that effect, but not exactly that

6:45 AeroNotix: llasram: exactly what I was thinking

6:45 llasram: In the code posted, just dropping the `file` would work

6:46 AeroNotix: sec

6:46 llasram: `io/resource` does the `.getResource()`, returns a URL, which `io/reader` knows how to open

6:46 AeroNotix: ok gotcha

6:46 Anderkent: (inc llasram)

6:46 lazybot: ⇒ 17

6:46 Anderkent: for going over budget

6:46 llasram: Haha

6:47 I got curious about the CI deployment process :-)

6:47 Anderkent: yeah I need to figure that out myself, currently doing everything by hand and that seems error prone

6:47 AeroNotix: llasram: it works for us. It means that we always know what's running in production.

6:47 Anderkent: plus, having travisci push snapshot builds from master would be so nice

6:47 AeroNotix: Anderkent: it is (though we use jenkins)

6:48 llasram: yeah that fixed it

6:48 allenj12: hey, ive been using clojure for a while now and ive been mainly using light table for learning and its been great. but i wanna move on to a more advanced editor. ive never used either emacs or vim before but would one be better for clojure than the other?

6:49 llasram: I considered having our system manage versions, but rejected it for libraries, in part because it seems to be very uncommon and little tooling for any language supports automatically altering versions

6:49 Anderkent: mildly off-topic: I always feel so naughty when I hand-edit a third party clojure jar in my maven repo just to try something out. Tee-hee

6:49 cark: allenj12 : emacs is easier to get into and has probably better support for clojure

6:49 Anderkent: allenj12: I think the consensus is that emacs is a bit better, but probably not enough for someone well versed in vim to switch. They both get the job dnone

6:49 jonathanj: ivan: that solution you gave earlier (summing columns in a matrix) seems kind of verbose, is there not a less wordy solution?

6:49 Anderkent: (said as a vim user)

6:49 llasram: I'm pretty happy with where I ended up though -- libraries have version numbers managed by humans, but just changing the version number in a commit triggers a release

6:50 Anderkent: llasram: oh, that's pretty cool. Is that specific to some ci system?

6:50 cark: allenj12 : there is also an eclipse plugin which is now very good

6:50 allenj12: hmm cool so ill try emacs then. emacs dosnt have live coding just to make sure right?

6:50 jonathanj: ivan: my Python solution ended up being pretty terse, surprisingly: map(sum, zip(*[[1, 1], [2, 2], [3, 5]]))

6:51 allenj12: cark: hmm cool ill check that one out to

6:51 Anderkent: allenj12: not to the same degree as LT, I think

6:51 cark: allenj12 : the name of the plugin is counterclockwize

6:51 llasram: Anderkent: It's specific to the company-internal CI tooling glue I wrote, yeah :-)

6:51 Anderkent: bah :P

6:51 have you not heard of code reuse!? I'd totally like to reuse your code. :P

6:52 allenj12: Anderkent: dam :( lol i guess it will be good enough tho although i really will miss it

6:52 cark: allenj12 : in emacs, you have a live repl and completion using cider

6:52 allenj12: cark: ahh kk, would you recommend eclipse or emacs if im split on the two?

6:52 Anderkent: well, eclipse is easier to get started with I'd think

6:53 llasram: Anderkent: Haha. I've thought a few times about cleaning it up for an open source release, but I'm not sure how general it is. It pretty directly codifies all of my teams practices w/o much room for customization

6:53 cark: allenj12 : i'm using emacs... but it's surely isn't as easy to get into than eclipse

6:53 AeroNotix: point and click to create codez

6:53 Anderkent: llasram: my general answer to such questions is publish it anyway, even if it's too specific it can serve as a template for other people to start with

6:53 cark: allenj12: in particular, the setup is quite a lengthy process

6:54 allenj12: Anderkent: what about long term tho will i be happier with emacs? i have an easy semester so jumping into a bunch of things like slackware

6:54 cark: o i see

6:54 cark: allenj12:long term, go for emacs ... it will serve you well over the years

6:54 not only for clojure

6:54 Anderkent: allenj12: depends. Are you planning to do java development? then you want to learn eclipse (or intellij) anyway. Are you planning to manage your life email and stuff from emacs? Then learn emacs :P

6:55 *life, email, and stuff

6:55 sm0ke: llasram: hello, do you have plans for providing a higher level api on top of abracad?

6:55 cark: but then again, if talking long term... vim is worth learning too =)

6:55 llasram: sm0ke: In what sense?

6:55 Anderkent: more seriously, I recommend learning at least one command line editor for at least basic competency, they make life easier

6:55 llasram: sm0ke: I've quietly added a few under-documented schema-definition helpers

6:55 AeroNotix: Anderkent: nano

6:56 sm0ke: llasram: like consolidating data files, vertical partitioning data according to schema

6:56 Anderkent: AeroNotix: eh, if you have to. the point is being able to do simple changes to config files / whatever on a bare system

6:56 reading logs, debugging data issues, etc.

6:57 allenj12: Anderkent: lol nano :) but yea i think i will give emacs a try then. i mean light table is pretty minimalistic so i doubt it will take me long to get me back at that point

6:57 llasram: sm0ke: I hadn't considered it before, but a datafile-consolidation function might make sense -- that's something I find myself doing relatively frequently on the results of MR jobs. Not sure what you mean by the latter though

6:58 cark: allenj12:follow the install info from the cider github page to the letter and it should go qell

6:58 well*

6:58 mark[oz]: hey guys... just curious how i can use a function in my core.clj file (namespace is robot.core) in the REPL in my lein project and call a defined function (read-file) ??

6:58 lazybot: mark[oz]: Uh, no. Why would you even ask?

6:59 allenj12: cark: awsome thanks!!

6:59 sm0ke: llasram: so if a avro schema is type which is union of many subtypes it would be great i could write data to a path , and each subtype goes to its own directry

6:59 llasram: like namespace/typename

6:59 llasram: Oh. Huh

6:59 I don't know... That one feels out-of-scope to me, but that may just be because I haven't needed it :-)

6:59 Anderkent: mark[oz]: run (use 'robot.core) in your repl

7:00 sm0ke: llasram: also i wanted to ask if you are using it atop hdfs?

7:00 llasram: sm0ke: Yep

7:00 Anderkent: mark[oz]: or you can tell lein that robot.core is your main ns and then it'll automatically load it and switch to it when you start a repl

7:00 llasram: sm0ke: Ooof, which is something I need to add -- right now there isn't a clean way to read Avro files directly from HDFS

7:01 sm0ke: I keep working around it using Parkour's ability to `reduce` a dseq backed by an Avro Hadoop InputFormat

7:01 quizdr: if you are interested in the side effects of the map function in a map rather than the actual sequence that map returns, then you should just wrap map in dorun, right? or is there a better alternative?

7:01 mark[oz]: Anderkent: I've set :main in my project.clj file, and when i load the repl the namespace is robot.core =>

7:01 Anderkent: then you should be able to just call your functions in there

7:01 sm0ke: llasram: oh ok thats right, but write is fully supported?

7:01 mark[oz]: Anderkent: but when i (read-file "afile") I receive "CompilerException java.lang.RuntimeException: Unable to resolve symbol: read-file in this context"

7:02 AeroNotix: llasram: aha, stupidly I just sent a pull request for this change. But it seems it's already there. Weirdly it's not up on clojars, they probably forgot to do a release.

7:02 mark[oz]: Anderkent: I've defined read-file like so (defn read-file [] (dostuffhere))

7:02 sm0ke: llasram: so how is that the data-file-wrtier can be given a hdfs:// path too?

7:02 llasram: sm0ke: Yeah, write is fine. Avro can write to any old OutputStream, but needs it's own SeekableInput for input

7:02 Anderkent: mark[oz]: do you get any errors on repl startup? I'd check for typos

7:03 llasram: sm0ke: Well, you can open an output-stream on it via any of the HDFS interfaces. I forget if Hadoop registers a Java URL handler for `hdfs://`, although I think those are read-only?

7:04 sm0ke: And Parkour adds Hadoop `Path` handlers to the Clojure IO functions, so you can just call `io/output-stream` on a `Path`

7:04 mark[oz]: Anderkent: I've got an error I'm trying to work through in that file. It's not within that function though... will an error in one function render each function within that namespace unavailable?

7:04 Anderkent: mark[oz]: it might if it stops the namespace from compiling

7:05 sm0ke: llasram: nice, is that done internally via extend-type?

7:05 llasram: AeroNotix: Huh, really? The github link I sent was from me just poking at the source in master. That's weird

7:05 mark[oz]: Anderkent: thanks.. I'll have another look at cleaning that namespace up

7:06 llasram: sm0ke: Yep -- clojure.java.io internally uses a few protocols and type-based multimethods for everything, so they're all extensible to new types

7:07 sm0ke: llasram: so i wanted to ask if it makes sense if instead of writing to individual files, abracad can write datafiles to a folder location? which could be then merged into each other

7:07 llasram: i mean apart from writing to*

7:09 mark[oz]: Anderkent: you were right. it was a compilation error... thanks for your help

7:09 llasram: sm0ke: I'm not really clear on what that would mean, and I don't think it's a use-case I've had yet myself. Is this something you're doing currently yourself?

7:11 sm0ke: llasram: yea kind of, i just think that append to a single file is not as efficent as writing to a number of files and moving them under a common location

7:11 llasram: although i may be wrong,

7:11 Anderkent: sm0ke: shouldn't matter unless your file system is degenerate

7:12 uhm, or unless you have tons of threads competing for access to the file I guess

7:12 allenj12: cark: hey cider has it own keybindings im assuming?

7:12 llasram: sm0ke: Yeah, like if you have multiple threads?

7:13 sm0ke: llasram: yes, which is typical if you filesystem is hdfs, which is meant to have writes from different machines probabaly at same time too

7:13 llasram: sm0ke: You can already just have each thread write to a file in a directory, so yeah -- just not quite picturing what extra functionality in Abracad would do

7:13 sm0ke: llasram: well yea abracad does what its supposed to, its clean

7:13 llasram: sm0ke: I see. For that case, for all my uses so far, I'm producing that sort of output from Hadoop MapReduce, which handles that layer for me

7:14 Are you manually distributing tasks across a cluster somehow?

7:14 sm0ke: llasram: so how do you write data to hdfs which you are using in your mapred jobs?

7:15 llasram: sm0ke: Most of our ETL processes are themselves MR jobs :-)

7:16 atyz: szymanowski: thanks, I got distracted taking my father to the airport

7:16 szymanowski: np :)

7:17 llasram: sm0ke: For our main data feed, our appliances push data to S3. I have an MR job which gets a list of S3 *URLs* as input, then reads them, parses the binary format, and emits normal MR output to the Avro output format

7:18 We do have one feed which locally writes out files, but that one is relatively tiny -- just one serial process keeps up with it fine

7:19 sm0ke: llasram: makes sense, i see you do not really require to handle writes to S3

7:20 llasram: Yeah. We just use S3 as a reliable hand-off location. Amazon has better uptime than we care to manage at the moment :-)

7:20 sm0ke: llasram: makes sense, thanks

7:21 llasram: np

7:21 sm0ke: llasram: so you mapred cluster also runs on aws ?

7:22 your*

7:24 hmm stupid question. it should, it would take insane amount of time for mappers otherwise to fetch blocks

7:31 llasram: sm0ke: Actually, no. We just bounce the data through S3, so everything after the initial ETL job uses local cluster storage

7:34 sm0ke: llasram: so the whole data is copied on s3 as well as locally?

7:35 llasram: sm0ke: Kind of? It just passes through S3. We delete the S3 version after copying it down into our local cluster

7:35 sm0ke: hmmm, whats the denefit of having s3 in between then?

7:36 benefit*

7:36 i mean you are not useing it as data backup also

7:37 llasram: Just uptime of the service. The appliances need something to push to. We'll eventually just provide a service ourselves for them to push to directly, but right now there are other things we want to spend time on instead of making a reliable upload service which handle large bandwidth bursts

7:38 sm0ke: hmm makes sense

7:38 specailly with the recent ddos attacks,

7:38 500GB is normal they say

7:40 mark[oz]_: hey guys, one last question before i get to bed. when I lein repl, I can (-main) and I get some output due to the println, but when i run it from the command line I don't get anything. http://pastie.org/8745170 is the code... can someone explain what's going on here?

7:41 llasram: mark[oz]_: `for` returns a lazy sequence. When you run it in the REPL, the REPL forces the sequence to print it, causing the `println`s to evaluate. When run from the command-line, nothing forces the evaluation, so nothing happens

7:41 mark[oz]_: Try changing `for` to `doseq`

7:41 sm0ke: one last question , llasram , how is the data copied into local systems is it incremental or batch?

7:42 llasram: sm0ke: Batch right now. It's uploaded in batch, so it (mostly) makes sense to retrieve in batch

7:43 sm0ke: llasram: no i mean, batch as in the WHOLE data is copied again or just new batches of data

7:43 llasram: Um, the latter :-p

7:43 sm0ke: haha

7:43 mark[oz]_: llasram: thanks for the explanation! that makes sense

7:43 sm0ke: ok thanks

7:43 later!

7:44 llasram: later!

7:57 mdrogalis: Morning.

8:05 CookedGryphon: Hey, does anybody have any ideas about how to profile core.async code in a sensible sort of a way

8:06 without just firing up visualvm - i find the output pretty incomprehensible

8:07 I sort of want to look at it from a go-block level, see what is doing a lot (i.e. I have written badly and is spinning in a loop) vs sitting there locked, etc

8:07 can I get at the underlying state machine and track that sort of thing?

8:19 Anderkent]lunch: CookedGryphon: hm, you could try timbre, but I think you'd have to manually expand the profiling macros (because async won't let you do (profile (<! chan foo))

8:19 CookedGryphon: Anderkent]lunch: wouldn't that be weird, because it would be split across invocations of the state machine.......

8:19 or something

8:20 also, I don't really want to go through allll my code inserting (profile ...), because then I would want to remove it

8:20 and i'd like to leave this as an option to turn on and look at at any time

8:20 Anderkent: with timbre you don't have to remove it, you just change your logging level and it goes away :

8:21 I think the state machine would be transparent to timbre

8:21 i.e. it'd track time spent while parked as time of execution

8:21 hard to say if that's what you want or not

8:21 CookedGryphon: Anderkent: yeah, that's really not what I want

8:22 doing that, the most efficient functions which just sit there parked would show up as taking most time!

8:22 Anderkent: sure, so just look for functions with most invocations rather than most time spent

8:22 or don't wrap parking ops in profile

8:24 CookedGryphon: hmm

8:24 Anderkent: I guess I'm not sure what you're trying to find out; intuitively the costly functions (i.e. ones worth profiling) shouldnt live in go blocks, just be called from one. Is that intuition wrong?

8:25 CookedGryphon: yes that's correct - if I have coded it right :P

8:25 Anderkent: I haven't used core.async much, but always thought of it more as a communication mechanism than a processing engine

8:25 ah :P

8:25 CookedGryphon: the situation that's made me think of this

8:25 is I currently have a system which is getting hot while it should be idling

8:25 Anderkent: hm. Log more? :P

8:25 CookedGryphon: making me think that in one of my go-loops I'm accidentally recurring without doing any work

8:25 so it just spins

8:26 which would be easy to see if I could keep track of what's recurring when

8:26 I might just write a variation on go-loop which does just this

8:26 Anderkent: right, I see your point. You could swap your go blocks for thread blocks and then use a jvm profiler to see where the threads are spinning

8:26 CookedGryphon: tracks the number of invocations and sends it off to riemann or something

8:27 I'm actually on android, and the profiling isn't great

8:27 Anderkent: I guess I don't know how big your app is; my intuition is just go read your code :P

8:27 but if thats not feasible, sorry; can't help you

8:28 CookedGryphon: I think I'm going to tweak a go block

8:46 szymanowski: is there a way to have wildcard in multimethod dispatch values?

8:46 does core.match can help on this?

8:46 Anderkent: szymanowski: as in just a catch-all method? use :default as the value

8:47 szymanowski: yes i know that but it would be great to have wildcards

8:49 Anderkent: hm, can you provide an example? I guess I've never bothered with complicated hierarchy multimethod (always exact match, either on keyword or class)

8:49 mdrogalis: szymanowski: Arbitrary wild cards in multimethods: no

8:50 szymanowski: ok is there any implementations of sush a feature somewhere?

8:50 such

8:51 mdrogalis: szymanowski: Not that I'm aware of. But there might be.

8:51 Anderkent: I don't think so; seems a very weird thing to do to me

8:51 szymanowski: why?

8:51 clojurebot: szymanowski: because you can't handle the truth!

8:52 Anderkent: it just doesnt fit the way I think of multimethods, I suppose.

8:53 szymanowski: you're maybe right i will think more about it

9:24 quizdr: is it necessary to compile a source file before you require it another source file? the require call itself will not compile it for you?

9:24 it appears to be the case.

9:25 stuartsierra: quizdr: `require` will compile & load the source file for you. `compile` is only necessary for Ahead-of-Time (AOT) compilation, which saves compiled .class files on disk.

9:26 sritchie: seangrove: hey; I'm working through it now, I can show you the not-quite-working-yet code

9:26 seangrove: https://github.com/paddleguru/om-timer

9:26 quizdr: stuartsierra i get symbol not found errors relating to functions in a required namespace. when i go into that required namespace's source file and do a control-c control-k to compile that file, then go back to my original file, the issue is resolved.

9:27 Anderkent: quizdr: was that file required before and then edited? `require` will not reload a file from disk if it's already been loaded

9:28 stuartsierra: quizdr: clean out your compiled files (lein clean) and start a new repl

9:29 quizdr: stuartsierra anderkent would it make a difference that this other file I am requiring has been "lein install"ed previously and is not in my current project? would that require that I compile it separately?

9:30 sritchie: quizdr: that can happen from AOT compilation

9:31 quizdr: sritchie so when i restart a repl i will probably need to recompile any sources that are not in my project but i am requiring, yes? I assume AOT is in play here since perhaps that is what lein install does?

9:31 sritchie: quizdr: I've only seen that problem show up when AOT compilation's at play, yes

9:32 and only then when you have some dependency mismatch

9:32 (ie, you have a diamond dep, where you're requiring some version of a library, and the code you're requiring is compiled against a different version)

9:32 if you fix the mismatch in your project or remove the AOT compilation you won't have to recompile

9:35 CookedGryphon: aphyr: Hey, I'm trying to use your riemann-clojure-client and I'm getting an issue when I AOT compile because IDref is defined twice - once in clojure and once in the riemann-java-client

9:36 is that okay on the jvm? (I'm using android + dexer which complains and falls over)

9:38 Anderkent: is that IDref with the same qualified name? Then I would expect it to break in every jvm

9:38 (if they're loaded in the same classloader)

9:38 CookedGryphon: Anderkent: yeah it appears to be exactly the same name

9:39 Anderkent: except riemann-clojure-client seems to depend on riemann-java-client and not define its own IDref

9:39 so I think you're having a classpath issue or something

9:41 CookedGryphon: IDref is a clojure class - clojure.lang.IDRef

9:42 which riemann-java-client seems to have pulled in

9:42 Anderkent: hm, can you post exactly what error you're getting?


9:43 java.lang.IllegalArgumentException: already added: Lclojure/lang/IDeref;

9:43 Anderkent: on refheap pastebin or whatever

9:43 CookedGryphon: there's a stacktrace, but it's just internal dexer stack

9:43 Anderkent: do you know what your exact classpath is?

9:44 do you for example have multiple versions of clojure on your cp?

9:44 CookedGryphon: I already said, this is defined in riemann-java-client (a dependency of riemann-clojure-client) as well as in clojure itself

9:45 so I want to know if this works for anyone

9:45 Anderkent: ah, right I see it now

9:46 that's a very weird thing to do

9:47 it does load for me on the jvm, the secondary implementation is probably never picked up

9:48 i.e. when the jvm is looking for a clojure.java.lang.IDeref.class file on the classpath, it finds it in the clojure jar and stops looking

9:54 dnolen_: sritchie: btw, it's not possible to reproduce your issues, even with lein cljsbuild auto, timer button always works for me.

9:54 sritchie: dnolen_: yeah, saw that note - I get it every time, even after nuking .repl, out, target, lein cljsbuild clean -

9:54 dnolen_: sritchie: I'm inclined to close your ticket. One thought is that weird stuff happens if you have multiple lein cljsbuilds running at the same time - easy for this to happen.

9:54 sritchie: whatever it is, I'm very skeptical it's Om related.

9:54 sritchie: but hard to tell you have a complex setup and not a minimal case.

9:55 sritchie: dnolen_: yeah, trying to reduce it now. Thanks a lot for taking a look, and feel free to close - I'm working on pushing the example to heroku,

9:55 and cleaning out my .lein/profiles.clj

9:55 to make sure no extra code is getting in the mix. still shows up every time for me

9:55 dnolen_: sritchie: Chrome?

9:55 sritchie: yeah, and firefox

9:57 dnolen_: sritchie: yep if I edit, wait for recompile and refresh Chrome & FF, I can always start stop the timer

9:57 sritchie: and no errors in the console?

9:57 dnolen_: sritchie: no errors

9:57 sritchie: dnolen_: the timer was toggling, and I'd see the numbers change like they're supposed to,

9:58 dnolen_: sritchie: I do a goog.string multiple require error when the app loads, but seems unrelated to whatever problem you are having.

9:58 sritchie: there's something goofed about my setup, whether it's the way I initialize cljsbuild auto and lein repl :headless in separate terminals,

9:58 or the repl process...

9:58 yeah, I see that too, but that showed up when things were working as well

9:59 dnolen_: sritchie: k closing for now, feel free to open a ticket you have a more minimal case. More than happy to take a look when you do.

9:59 sritchie: dnolen_: you know, maybe it's the different clojurescript versions from austin.

9:59 dnolen_: sritchie: I don't use Austin - so that might be it?

10:00 sritchie: gotta say Austin really needs to support :none, your builds are criminally slow

10:00 11-13 seconds for me

10:00 should be .03 seconds

10:00 cemerick: ^

10:00 sritchie: yeah? that may just be my config goof.

10:00 dnolen_: sritchie: Austin doesn't work with :none

10:01 sritchie: dnolen_: austin was in my lein config, so this may be a JVM classloading issue

10:01 whichever cljs wins...

10:01 dnolen_: sritchie: yeah, Om needs 2156

10:01 cemerick: dnolen_: where are builds 11s?

10:01 sritchie: but yeah, thanks a lot for looking. I'll be much more suspicious of config going forward and try to isolate that stuff before reporting. will let you know how the investigation proceeds

10:02 dnolen_: cemerick: :whitespace + sourcemaps

10:02 sritchie: cemerick: yup

10:05 dnolen_: sritchie: fwiw, seems like a lot of people are using Om now, when I introduce a bug I get reports pretty quickly :)

10:05 Anderkent: dnolen_: hey, om looks cool! I saw that before but I didn't hear of react so I just figured it was an interface to some facebook api after the first line of the readme and stopped reading. Not sure if that might have happened to someone else before and is thus worth fixing!

10:05 invasmani: Om is great, thanks for all of your hard work

10:05 sritchie: dnolen_: yeah, our current stuff is in "reactive" style, and most of the code is watches and state updates

10:05 dnolen_: invasmani: no problem, thx

10:06 sritchie: dnolen_: this is a huge win

10:07 dnolen_: Anderkent: I'll think about it, but I think React is making some waves so not long before most people know what it is :)

10:07 cemerick: dnolen_: Where does that compile time come from in the context of a browser-REPL interaction?

10:08 dnolen_: cemerick: Austin requires at least :whitespace optimizations no?

10:08 Anderkent: dnolen_: I think just changing the first line to something like 'A clojurescript UI library built on top of Facebook's React' would mostly do it

10:09 cemerick: dnolen_: Rumor has it; but, surely it's not 11s per expression beign eval'd?

10:10 I've used source maps ~twice, so I'm generally not aware of the impact they have on the compilation process.

10:10 dnolen_: cemerick: it's significant, I think most people at this point use source maps all the time.

10:10 including myself.

10:11 sritchie: oh, yeah, nice. with :none, 0.76 seconds per change.

10:11 cemerick: dnolen_: yeah ok; but, where does the 11s-13s come from?

10:11 dnolen_: cemerick: :whitespace + source maps

10:11 cemerick: dnolen_: you mean in the context of cljsbuild auto?

10:11 dnolen_: cemerick: yep

10:12 cemerick: ok; what does that have to do with austin?

10:12 dnolen_: cemerick: do you think that people don't run REPL & auto at the same time?

10:12 cemerick: cljsbuild supports :none, source maps, etc

10:12 sritchie: cemerick: does austin support :none?

10:13 cemerick: dnolen_: it's never occurred to me, but they're in different processes, and have different configurations.

10:13 dnolen_: cemerick: oh ok, so Austin doesn't require you to build your *own* source with :whitespace?

10:13 cemerick: dnolen_: goodness no

10:13 michaniskin: dnolen_: cemerick: i'm using cljsc but not via lein-cljsbuild, and i'm seeing ~3sec compile times for one changed cljs source file, when it used to be a few hundred msec at most. i'm carefully preserving last-modified times of source files, i think. where should i look for issues that could slow down the cljs build?

10:14 dnolen_: cemerick: ok good to know - I was completely baffled by earlier conversation. Thanks for the clarification.

10:14 cemerick: dnolen_: That is, the austin server-side part has its own compilation env with its own compiler options; *those* need to be :whitespace/:simple, but that just doesn't matter in the REPL context.

10:15 :cljsbuild configs can have :advanced, :none, whatever, and have no impact on austin's operation

10:15 quizdr: when I ctrl-c ctrl-k a source file, why would another source file in the same directory not be found on classpath if I require that file? the namespace name is indeed correct, but I get an error that the clj file could not be located.

10:15 cemerick: sritchie: not AFAIK, though it's been a long time since I've tried

10:15 dnolen_: michaniskin: if you're not using lein cljsbuild than your need to preserve compiler environment between builds to get incremental compilation benefits

10:15 cemerick: got it

10:15 michaniskin: dnolen_: by "compiler environment" you mean the temp files in :output-dir?

10:16 cemerick: michaniskin: no; see cljs.env

10:16 dnolen_: michaniskin: no, the atom that holds analysis information needs to be bound.

10:16 michaniskin: cemerick: dnolen_: oh awesome thanks!

10:16 dnolen_: michaniskin: (cljs.env/with-compiler-env compiler-atom (cljs.closure/build ...))

10:16 cemerick: michaniskin: :-)

10:16 michaniskin: you guys just saved me who knows how much time. thanks!

10:17 cemerick: michaniskin: tribal knowledge FTW ;-P

10:17 dnolen_: BTW, I have a patch ready for 656, but I wonder if you have any input re: my prior comment?

10:18 dnolen_: cemerick: yeah I saw that, will need to think about it for a little bit, will respond on the ticket.

10:18 quizdr: does your project.clj need to list as a dependency all the namespaces created in the same project's src/ directory?

10:18 cemerick: dnolen_: ok; I'll put a prospective patch on there anyway

10:19 quizdr: no

10:20 quizdr: cemerick any idea what would cause a filenotfound exception when you require a namespace that is in the same src dir, just a different file?

10:20 cemerick: quizdr: typo, wrong filename extension, mismatch in filename and ns declaration

10:22 quizdr: cemeric thanks, obvious ideas that i've triple checked.

10:23 cemerick could a hypen in a clj filename cause a problem?

10:23 *hyphen

10:23 S11001001: quizdr: yeah; hyphens code as underscores when filenamifying

10:23 cemerick: quizdr: hyphens in namespaces need to be underscores in filenames

10:24 quizdr: ah ha! thanks guys

10:32 sritchie: dnolen_: fwiw, here's a recreation of the bug on heroku

10:32 http://omtimer.herokuapp.com/timer

10:32 dnolen_: no one seems to be stomping the cljs version

10:32 dnolen_: sritchie: your markup seems very problematic to me

10:33 React & your code loaded twice

10:33 sritchie: oh, that's a pretty huge neon sign, and almost certainly the problem

10:34 lvh: Hi

10:35 if I have a function that's more or less analogous to map, except it's doing multiple funcs over one coll (in a slightly involved way; I can't just spell it as "comp"), is it bad form to have the funcs arg come after the coll arg?

10:38 sritchie: dnolen_: fixed, and the goog.string error's gone too

10:38 ambrosebs: lvh: in most sequence functions, the collection comes last. good for threading with ->>

10:38 lvh: that said, the threading macros have improved, so this is less of an issue

10:39 quizdr: is it better or more idiomatic to wrap a map function in dorun or use doseq if i need side effects created from items in a collection?

10:39 i use map so much, that i also use it for side effects and often wrap with dorun, but now i'm wondering if this is a bad habit.

10:40 lvh: ambrosebs: Cool. So, inthis function, I should swap the args? https://gist.github.com/lvh/7b018a90cdafd119dc41

10:40 ambrosebs: ,(doc dorun)

10:40 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil."

10:40 ambrosebs: quizdr: do you mean doall?

10:40 Anderkent: on the other hand update-in etc. take the collection first

10:41 ambrosebs: quizdr: oh I see. I use doseq for side effects.

10:41 quizdr: ambrosebs no, dorun. the difference is that doall retains the head, which i wouldn't usually need.

10:41 Anderkent: quizdr: dorun is explicitly made for lazy seqs of side effects. It's okay to do that

10:42 quizdr: ok Anderkent i just find it easier to wrap a map in it than to pull out the doseq bindings. maybe like the sequence, i too am lazy?

10:47 lvh: Hi! How can I get a sorted list of [[(f x0) x0] ... ] given xs?

10:47 It's almost map, except not quite...

10:48 zipmap almost does what I want, I guess I can build a map and then seq it?

10:51 joegallo: ,(partition 2 [:a 1 :b 2 :c 3])

10:51 clojurebot: ((:a 1) (:b 2) (:c 3))

10:56 arohner: anyone remember that crazy ruby blog post where the guy monkeypatched everything to be in the same class? I'm trying to google for it and failing horribly

10:56 AeroNotix: arohner: I think that was titled: "How to be a moron"

10:56 arohner: well, my goal is to make fun of ruby :-)

10:56 AeroNotix: arohner: ruby doesn't need your help

11:01 szymanowski: what is the simplest way to create a function that always return true?

11:01 dnolen_: szymanowski: (constantly true)

11:01 szymanowski: great thank you

11:04 cemerick: dnolen_: I have a JS library I'd like to use that uses some reserved words as property names, which gclosure complains about. Would like to provide a compiler option corresponding to the constants in CompilerOptions.LanguageMode. Reasonable?

11:04 dnolen_: cemerick: pretty sure there's an existing ticket for this

11:04 cemerick: dnolen_: ok, I'll track it down and put something together

11:05 dnolen_: cemerick: http://dev.clojure.org/jira/browse/CLJS-743

11:05 cemerick: oh, even better

11:08 oskarkv: If I want to deref a reference and then set it without anyone else setting it inbetween, should I use a ref in a transaction? Or is there a way with an atom?

11:08 AeroNotix: oskarkv: ref+dosync

11:08 oskarkv: ok thx

11:11 hhenkel: Hi all...quick question...I managed to get a lazy-seq and now I'm wondering how to iterate over it...

11:11 I guess the key is doall?

11:12 oskarkv: hhenkel there are many ways, using map, reduce, loop/recur do name a few

11:12 to*

11:12 hhenkel what do you want to do with it?

11:13 hhenkel: oskarkv: first let me descibe what is in the lazy-seq...I read json data from a file, merge those data into each other and get it as a lazy-seq.

11:14 oskarkv: This seq holds config data for servers from which I want to create recuring jobs via at-at

11:14 Therefore I think I have to iterate over all items.

11:15 borkdude: hhenkel there are many functions that iterate over sequences

11:15 hhenkel map, filter, reduce, etc

11:16 hhenkel it depends on what you want to do

11:16 oskarkv: like one job for each element? Then maybe (map create-job the-seq), and if there are side-effects then use doall/dorun

11:16 hhenkel ^

11:16 borkdude: hhenkel doall is only used to realize all elements in a lazy seq

11:17 hhenkel: oskarkv: I don't think that I got side-effects as I want to schedule my network request with at-at (running in threads as far as I know).

11:18 I guess I was looking for something much more complicated then a simple (map create-job my-lazy-seq).... ;)

11:21 `cbp: hhenkel: (doseq [config my-lazy-seq] (create-job config))

11:25 hhenkel: oskarkv: `cbp: If I try your suggestions it seems like no data is given to my function.

11:25 I'll paste it in a min

11:29 oskarkv:

11:29 `cbp: https://www.refheap.com/41527

11:30 oskarkv: hhenkel you have missed a (

11:30 before the function, look at `cbp's example

11:32 hhenkel: oskarkv: yes, you're right....and what about your map example?

11:33 oskarkv: hhenkel but with map it should have worked. but note that the result of map is also a lazy seq, nothing will happen with it right away

11:33 hhenkel: oskarkv: I tried it with the same pprint function...

11:33 oskarkv: how?

11:33 clojurebot: with style and grace

11:34 hhenkel: It also looks like something is still wrong with my data...is it possible that I managed to create a lazy-seq within a lazy-seq?

11:34 oskarkv: yes that certainly possible :P

11:35 hhenkel: oskarkv: It's also in tn the refheap.

11:35 oskarkv: hhenkel I don't see any pprint in the code there :P

11:36 hhenkel: oskarkv: yes...the trace...sorry.

11:36 oskarkv: Also added the function that works on my data...

11:36 ...any hint how to not have to lazy-seq?

11:37 oskarkv: if you swapped trace for pprint? The schedule-request function will not run, because map is lazy.

11:37 (dorun (map ...))

11:37 or, doall if you want to retain it

11:39 hhenkel: oskarkv: missed the dorun / doall....any thoughts on the double lazy-seq?

11:39 oskarkv: hhenkel double lazy-seqs are not necessarily a problem

11:40 hhenkel: But if you look at my data strucutre that I get, do you think it's necessary that it is wrapped twice?

11:40 TimMc: Ticket filed for stupid clojure.string/split behavior: http://dev.clojure.org/jira/browse/CLJ-1360

11:40 (not that it will accomplish anything)

11:41 sveri: hi, is there a dedicated sum function for lists or should I use reduce?

11:41 sritchie: dnolen_: hey, one Q about that timing app

11:42 dnolen_: any advice on how I can be careful about isolating the timer DOM updates from other updates on the page?

11:42 hhenkel: oskarkv: the data contains to "objects" I would like to work on...therefore it seems like an overhead to me.

11:42 sritchie: I have a list of "result entries"; every time you click the mark button, I grab the current time and add an entry to {:stopwatch {:results <vector-of-results>}}

11:43 oskarkv: hhenkel I'm not sure what you are doing with your data

11:43 sritchie: dnolen_: :stopwatch has :results, :timestamp, :stopwatch-time, :active?… it looks like my :results rows are updated every 10ms. I feel like something about the way I'm passing cursors is triggering dom updates on :results changes...

11:44 dnolen_: probably I need to nest them differently?

11:44 oskarkv: hhenkel what is get-server-config, for example?

11:45 hhenkel: oskarkv: I added it to the refheap

11:45 oskarkv: hhenkel ok

11:45 hhenkel: oskarkv: That's what I was refering to earlier.

11:45 oskarkv: ah :P

11:50 dnolen_: sritchie: is your :results row a vector that isn't changing?

11:50 oskarkv: hhenkel and what was your question/problem? :P

11:51 sritchie: dnolen_: yeah, it is

11:51 hhenkel: oskarkv: Down below you see the result of "my work"...it is wrapped in (({ ...

11:51 sritchie: https://github.com/paddleguru/om-timer/blob/develop/src/cljs/paddleguru/client/timer.cljs#L207

11:51 hhenkel: oskarkv: all i want to do is iterate over those to objects...and it seems not right to have it double wrapped..

11:52 sritchie: dnolen_: and I'm trying to be careful to only pass that vector down into my build-all call;

11:52 :focus-cell is a piece of higher level state that leaks down, though. maybe that's triggering a re-render. Let me remove that and see if it helps

11:52 hhenkel: oskarkv: Or with other words, why should I pack it two times to unpack it twice later on.

11:54 oskarkv: hhenkel those come from `for`? So there is only one application and one server?

11:55 sritchie: dnolen_: yeah, it's still really sluggish after adding 100 results (even though that vector doesn't change)

11:55 dnolen_: http://omtimer.herokuapp.com/timer

11:55 hhenkel: oskarkv: nope, there are multiple applications that can have multiple servers ( a weblogic domain for example, one domain multiple managed servers and we got multiple weblogic domains).

11:56 dnolen_: sritchie: yeah so that's not going to work, you're triggering a re-render every time.

11:56 sritchie: you need to do the reverse "inside"

11:56 oskarkv: hhenkel but right now only 1? And those lists come from for?

11:57 or, seqs

11:57 dnolen_: sritchie: a bit of a wart at the moment with how Om works, we can't use Clojure's equality test yet because of some implementation details.

11:58 sritchie: basically in order to avoid re-renders identical? must be true, not =

11:58 sritchie: ah, gotcha

11:58 so I need to make sure to build the results vector in reverse as I add stuff

11:58 if I want those result entries to show up in reverse order

11:58 dnolen_: sritchie: no just do the reverse later

11:59 hhenkel: oskarkv: the description is in yaml files....there are two example objects in the data.

11:59 dnolen_: sritchie: like inside the component that shows it

11:59 hhenkel: oskarkv: first ends with :http-port 8080}

11:59 oskarkv: line 58

11:59 dnolen_: sritchie: even if I remove the wart, that will still be fastest

12:00 paulfedorow: why is it that i can't see the output of prn inside a go block when evaluating it in vim with fireplace?

12:00 sritchie: dnolen_: huh, I thought this was inside the component that shows it (finisher-rows)

12:01 finisher-rows shows the group of them

12:01 dnolen_: sritchie: no you are reversing then calling build

12:01 no way identical? check can work

12:01 oskarkv: hhenkel sorry, when you said "the result of my work" I think I misunderstood. What work? What function output that? And how did the double (( come about?

12:01 sritchie: yeah, for sure - just wasn't clear on the return type of build-all

12:01 so I can move the reverse outside

12:02 dnolen_: sritchie: build-all just returns a seq of components

12:02 sritchie: so you can use apply

12:02 hhenkel: oskarkv: The data shown is the result of "get-server-config"

12:03 oskarkv: ah, now i see

12:03 sritchie: dnolen_: nice. "ranked" is going to be a problem as well, I guess, since identical? will fail

12:03 dnolen_: though that's modeled after (defn people [app] …) in https://github.com/swannodette/om/wiki/Basic-Tutorial

12:03 dnolen_: sritchie: it's usually not a problem but for long lists of things yes, you're going to lose time comparing things that don't need to be compared

12:04 hhenkel: oskarkv: I gotta go - basketball time - be back later on.

12:04 oskarkv: So right now there are 1 app and 2 servers? Anyway you can do this in for: (for [app apps, server app] ...), that sould get rid of the double wrapping

12:04 hhenkel ^

12:04 hhenkel: oskarkv: I'll give it a quick shot.

12:04 paulfedorow: ah worked around it by wrapping the go block in a <!!. guess the go block wasn't executed fast enough for fireplace to grab the output

12:04 whodidthis: any way to destructure hashsets?

12:05 oskarkv: hhenkel note that comma is whitespace, no need for it

12:05 hhenkel: oskarkv: Perfect!

12:05 oskarkv: works now as expected.

12:05 oskarkv: Thank you!

12:05 oskarkv++

12:05 oskarkv: hhenkel great :p no problem

12:05 (inc oskarkv) :p

12:06 `cbp: (inc oskarkv)

12:06 lazybot: ⇒ 1

12:07 sritchie: dnolen_: the whole UI for this thing is poorly designed, anyway; since we insert at the top, you have to re-render everything below.

12:07 dnolen_: yeah, it's much faster without "ranked", presumably because you have to re-render everything to increment their rank by 1

12:10 dnolen_: the way forward is probably to implement that component that only re-renders items that are in the current window

12:10 dnolen_: thanks for the help. the fog is lifting.

12:15 bbloom: dnolen_: i think sritchie has your next blog post idea for you: you need to show how to implement a virtualizing stack panel

12:16 dnolen_: bbloom: heh, we'll see :)

12:16 sritchie: yes, this where if you came up with a generic component a lot of people would benefit.

12:17 sritchie: yeah, I'm planning on putting some time toward my Om + CLJS knowledge each day

12:17 I'll see what I can do with this

12:18 dnolen_: sritchie: that's really the thing I'm most excited about. As people build out their applications there will be legitimately reusable things that should be easy to spin out like I've done w/ om-sync.

12:19 bbloom: dnolen_: it would be pretty easy if you assume fixed height items and just absolute position them: then you basically just render N items where N is like the number of items that fit vertically * 3 or whatever

12:19 dnolen_: bbloom: yep

12:20 bbloom: legitimately reusable: as opposed to "we claim this is reusable, but nobody but us has ever reused it"

12:20 dnolen_: bbloom: most of the annoyances will simply be making it so that it works in every browser >= IE8

12:20 bbloom: dnolen_: if you just put a div in a scrollable div, set the inner div's height explicitly, and then absolutely position fixed height items within that: i see no reason why it shouldn't in any browser w/ minimal effort

12:21 dnolen_: bbloom: it should just work yes - but you know how these things are :)

12:21 bbloom: true story.

12:21 dnolen_: it works, except on Galaxy Tab or something

12:21 sdegutis: I think (id) would be a great name for some function.

12:21 Except then we could never name variables "id"

12:22 bbloom: sdegutis: which is likely why rich choose identity

12:22 sdegutis: haskell was more bold: http://hackage.haskell.org/package/base-

12:22 sdegutis: Well I already feel paranoid when I name a symbol "id", having to check lazybot to see if it's already a function.

12:22 bbloom: lol

12:22 sdegutis: So it might as well be unusable.

12:22 bbloom: sounds like an isolated problem...

12:22 sdegutis: bbloom: Doing Haskell lately?

12:23 bbloom: sdegutis: nope

12:23 sdegutis: no plans to either

12:23 sdegutis: !!

12:23 Why not?

12:23 bbloom: sdegutis: not gonna get in to a language war now....

12:23 sdegutis: No I mean, I just thought everyone in here was getting into Haskell lately.

12:24 (Except that one guy.)

12:24 technomancy: gentlemen. you'll have to wait till 1600 UTC for this.

12:24 =)

12:24 sdegutis: (yeah, him)

12:24 bbloom: i've been enjoying his absence

12:24 sdegutis: technomancy: I don't see it in the topic anymore.

12:24 bbloom: sdegutis: it's now well known policy, not a new announcement :-P

12:24 technomancy: hehe

12:25 sdegutis: I just saw a trend of Clojurians getting into Haskell. Not sure why it happened en masse like that. Kinda neat phenomenon.

12:25 technomancy: is Clojure big enough to have any "en masse" phenomenons happen in it?

12:25 phenomena

12:25 bbloom: sdegutis: this community believes in understanding PLT and, like it or not, haskell has a strong foothold there. you basically need to read ML and Haskell to keep up with the theory

12:25 sdegutis: (en-masse & people) only requires >= 3 arguments.

12:26 bbloom: sdegutis: and, if you're lucky, scheme :-P

12:26 sdegutis: PLT?

12:26 * sdegutis googles

12:26 sdegutis: $google PLT

12:26 lazybot: [Project Learning Tree] https://www.plt.org/

12:26 sdegutis: Oh.

12:26 bbloom: no

12:26 programing language theory

12:27 clojurebot: PLT is http://en.wikipedia.org/wiki/Programming_language_theory

12:27 clojurebot: In Ordnung

12:27 sdegutis: Oh dang, I'm off topic.

12:27 * sdegutis heads back to #clojure-social.

12:31 dnolen_: so w/ the React.js 0.9.0-rc1 changes, Om is 10X faster for initial render than the popular competitors :)

12:31 love it when perf is someone elses problems

12:32 bbloom: dnolen_: nice. what changed?

12:33 dnolen_: bbloom: bunch of internal tweaks, petehunt suspects JIT friendlier

12:33 petehunt: also innerHTML size is a lot smaller since we reduced the size of ids

12:33 probably has a lot to do with it

12:34 dnolen_: petehunt: nice

12:34 bbloom: petehunt: JIT friendlier means less runtime metaprogramming? more use of objects as structs?

12:34 petehunt: bbloom: we fixed a few places where we created obj keys in different orders

12:34 big thing was not accessing undefined props in a few places

12:35 bbloom: petehunt: gotcha. so the hidden classes optimizations don't bail out w/o warning

12:35 petehunt: right

12:35 bbloom: petehunt: and by ids smaller, you literally mean fewer character strings? heh. hilarious

12:35 petehunt: yeah

12:35 wei__: compojure handlers/wrappers are called from inside out right? so that means if I use the -> operator my handlers are actually called in the reverse order in which they appear?

12:36 sritchie: yup

12:36 wei__: that's correct

12:36 wei__: sritchie: thx

12:36 petehunt: go measure the # of html bytes in the dom ni 0.8 and 0.9

12:36 :)

12:37 nkoza: dnolen_: are you using Om in production?

12:37 bbloom: petehunt: go team

12:37 nice work

12:37 dnolen_: nkoza: not yet, but other people are

12:37 bbloom: nkoza: dnolen_ never uses his own stuff in production. where would the fun be in that? he just rathers you all gamble for him

12:37 dnolen_: haha

12:38 nkoza: I see, maybe I can be another guinea pig

12:40 `cbp: I cloned the stackoverflow new topic's add-tags-input for my app in about 250 lines of om. That was pretty nice.

12:41 dnolen_: `cbp: nice

12:43 `cbp: dnolen_: indeed, all i needed was the basic tutorial hehe

12:44 Once I port it to 0.4 i'll make a repo with my widgets

12:45 dnolen_: "we've replaced 17,000 lines of JavaScript with 2,000 lines of om/react" http://github.com/swannodette/om/issues/116#issuecomment-35410957

12:48 bbloom: glorious

12:48 ambrosebs: dnolen_: wow congrats!

12:53 whodidthis: is there a way to get ring to respond with status 400 if im not returning a status or body

12:53 so status 400 if my response-handler returns nil

12:53 ystael: whodidthis: sure, just interpose a middleware that replaces nil with a 400 response on the way back out

12:55 whodidthis: cool, havent lookd at any middleware yet

12:55 ystael: whodidthis: have you looked at Liberator?

12:56 something like that takes care of a lot of these concerns for you

12:56 whodidthis: im not planning on doing that many http end points so ill try something simpler

12:56 more interested in websockets

13:00 zanes_: Huh. Odd that max doesn't take a comparator.

13:01 hiredman: ,(doc max-key)

13:01 clojurebot: "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest."

13:01 zanes: I'm aware of max-key.

13:02 But thanks.

13:03 pyrtsa: clojure.core is really lacking in Comparator based functions. :(

13:03 llasram: pyrtsa: In what sense?

13:04 pyrtsa: Comparison operators only work on numbers. No min/max algorithms for collections of Comparables. etc.

13:04 llasram: Oh, that. Yeah, not sure why

13:05 pyrtsa: Fun fact: (< date1 date2) comparison works for java.util.Date when it's part of a Datomic query. But not when clojure.core/<.

13:09 justin_smith: ,(< (.getTime (java.util.Date.)) (.getTime (do (Thread/sleep 1) (java.util.Date.))))

13:09 clojurebot: true

13:09 jonasen: pyrtsa: < is for nums only (as per the docs).

13:10 pyrtsa: jonasen: I know. Not sure if that's been a good design decision, though.

13:12 justin_smith: ,(compare (java.util.Date.) (do (Thread/sleep 1) (java.util.Date.)))

13:12 clojurebot: -1

13:13 zanes: pyrtsa: Is there some contrib library I should be reaching for?

13:14 Also, this is a weird question, but is there a convention for naming deref'd variables? e.g. variable-name -> dvariable-name or similar

13:15 pyrtsa: zanes: Don't know of any.

13:16 zanes: I guess just using @ everywhere is shorter in almost all instances.

13:17 pyrtsa: I usually try to avoid dereffing the same IDeref multiple times in the same function, if it's possible some other thread might be changing it.

13:18 justin_smith: really you should be using a transaction (for a ref) or a swap function (for an atom)

13:18 dereffing multiple times in one fn sounds like a code smell

13:18 pyrtsa: Nod.

13:18 justin_smith: also "sounds like a code smell" is metaphor abuse

13:18 pyrtsa: :D

13:19 llasram: Software synesthesia

13:19 justin_smith: lol

13:20 technomancy: why does everyone assume code smell is malodorous

13:20 justin_smith: code perfume

13:20 technomancy: can't code smell fresh and lively?

13:20 justin_smith: decoderant

13:20 llasram: (inc justin_smith)

13:20 lazybot: ⇒ 27

13:20 technomancy: nice

13:21 SegFaultAX: Haha, well done.

13:22 bbloom: justin_smith: decoderant would be a great name for a linter

13:22 "Eliminates those pesky code smells!"

13:22 "Now with bleach!"

13:23 pjstadig: 𝅘𝅥𝅮Your code's not fully clean until it's Zest fully clean!𝅘𝅥𝅮

13:23 amalloy: bbloom: coderant.de is available

13:24 de.coderant is the group-id - now what's the artifact-id?

13:24 pjstadig: speed-stick

13:24 bbloom: fresh-blast

13:24 pjstadig: that's the the submodule that finds perf smells

13:26 technomancy: different versions have code names [de.coderant "0.5.0-ARCTIC-CHILL"] and [de.coderant "1.1.0-ISLAND-BREEZE"]

13:26 justin_smith: haha

13:26 pjstadig: i always end up buying domain names because of #clojure

13:27 this is how i ended up with clabango.org (which I finally let go)

13:27 ~suddenly

13:27 clojurebot: CLABANGO!

13:27 Raynes: #firstworldproblems

13:27 :P

13:41 aphyr: CookedGryphon: #riemann is the best way to get ahold of me BTW.

13:42 CookedGryphon: haven't seen a compilation error before but I believe you, haha. Riemann-java-client defines it internally.

13:42 Any idea how to let the java client implement the interface without copying the class?

13:43 hiredman: http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html ?

13:55 ptcek: Anyone know how to configure jTDS or MSJDBC driver for MSSQL 2005 to use :fetch-size parameter and fetch lazily? I have a working example with Oracle, but cannot find out how to do that with MSSQL...

13:57 It always tries to load the whole dataset in memory in contracst with Oracle that uses fixed amount of memory no matter how large the dataset...

14:00 aphyr: CookedGryphon: https://github.com/aphyr/riemann-java-client/issues/34

14:02 justin_smith: ptcek: clojure.java.jdbc should return a stream of result data, using constant memory space is a question of what you do with that stream

14:03 ptcek: justin_smith: I will post the working code in a sec to make it clear...

14:06 fitzoh: anyone have any experience with clj-webdriver?

14:16 ptcek: justin_smith: Cannot connect to work, so just from memory http://pastebin.com/uewDgdau

14:18 justin_smith: this works well when connecting to Oracle (clojure process will take a few MBs more than when idle no matter how large the dataset) but MSSQL driver will try to load the whole dataset into memory so it blows up

14:23 justin_smith: oh, so this sounds like a bug somewhere in the integration of the mssql driver and clojure.java.jdbc - have you tried breaking it into explicit count and offset queries? that should work as a fallback

14:23 though it is admittedly tedious

14:27 ptcek: justin_smith: I did not and don't want to (I don't need to get the result now so I am not forced) and it bugs me that it works in Oracle

14:28 justin_smith: Sounds like a problem with that mssql backend, yeah. I think your options are not use mssql, fix their driver, or use count and offset queries.

14:29 I'd be interested if you find something better though.

14:29 ptcek: as I am total noob and new to clojure/dbs and all I think I will not :)

14:30 justin_smith: :count and :offset keys, and breaking into multiple queries in a loop, should work OK

14:30 borkdude: So now I get what caribou is about: building crud apps

14:31 justin_smith: borkdude: yeah, that's a big part of it - or at least handling the crud part of setting up a website

14:31 borkdude: justin_smith I'm impressed by the demo video

14:32 justin_smith: thanks, I'll let patchwork know

14:32 ptcek: justin_smith: yeah this will work but if my approach is correct, I would even more like to see IT working. Could it be considered bug?

14:33 justin_smith: bug in what? drivers?

14:33 justin_smith: ptcek: I think it is a bug in the mssql driver

14:33 ptcek: justin_smith: I will try jTDS authors then...

14:34 justin_smith: or maybe it is a technically a missing feature and not a bug... dunno, sorry

14:34 ptcek: they present that it should be working and all the opts are supported

14:34 jonasen: Anyone know of where I can read more about core.async pub/sub system (blog posts, examples etc)? All I found is basically the docstring for `core.async/pub`: https://github.com/clojure/core.async/blob/master/src/main/clojure/cljs/core/async.cljs#L597

14:35 ptcek: justin_smith: after all, do you consider the aproach with, genrally, statefull function to be correct given the use case?

14:35 aphyr: jonasen: the docstrings are helpful: https://github.com/aphyr/core.async/blob/decomplecting/src/main/clojure/clojure/core/async.clj

14:37 dnolen_: jonasen: pub/sub is pretty simple, https://github.com/swannodette/om-sync

14:37 jonasen: pub takes a chan and returns something you can suscribe to, you must supply something that take the value of the channel and returns the topic, sub is simple, you subscribe to pub chan and you say what topic you want to listen in on.

14:38 justin_smith: ptcek: as long as you don't ever run the code in parallel

14:39 ptcek: if you would ever have two concurrent queries, you would want to bind the atom inside a closure, so they wouldn't compete for the same atom

14:39 jonasen: dnolen_: thanks! I think pub/sub is what I want. Great to see om-sync is using it. I'll read through the code

14:39 justin_smith: (wrapping the whole thing in a let statement instead of using def, and probably putting that inside an fn)

14:39 dnolen_: jonasen: it's not so much using it, people who want to use it must follow this pattern.

14:40 jonasen: om-sync works by consuming a feed of all changes to the application state

14:40 justin_smith: good clojure style is to refactor things so that all the caller will care about is the arguments (if any) and the return value

14:40 ptcek: justin_smith: this is what I meant by stateful function, ie closure over atom, right?

14:40 justin_smith: right, once you close over a new atom, it is only locally stateful

14:41 and won't share state with another invocation

14:41 stompyj: Clojure + Redis. It's like the dawn of a new day. That is all. :)

14:41 ptcek: yeah this is what I am planning

14:41 justin_smith: (let [sum (atom 0)] (clojure.java.jdbc/query ... (rest of your code goes here)))

14:41 of course dereffing the atom at the end

14:42 ptcek: justin_smith: thanks for suggestions

14:43 justin_smith: also, if you end up doing queries in a loop with :count and :limit parameters, you can probably make the queries in parallel, adding to the atom as each comes back, instead of waiting for them one at a time

14:44 so you only need deal with latency once, rather than multiplying latency by the query count

14:46 ptcek: justin_smith: so use n atoms for n parallel queries?

14:46 justin_smith: um no

14:46 one atom, but swap as they come back

14:46 for n parallel queries that are meant to derive 1 count

14:48 ptcek: ok, actually I am using some "switches" that I switch while going through the dataset and adding only when some combination of switches is present, ie I process a row at a time and keep the necessary history in the atom

14:49 amalloy: justin_smith: instead of hand-rolling some junk with an atom and spawning the threads yourself, why not use reducers/fold? that's what it's for; you just have to define a Reducer implementation for your database thing

14:49 ptcek: + the accumulator, of course

14:49 justin_smith: ptcek: yeah, amalloy's idea is much better

14:51 ptcek: ok so use fold in place of result-set-fn

14:54 justin_smith: I think it's not quite that simple, you would define a fold that does a query, and reducers would combine the results http://clojure.com/blog/2012/05/08/reducers-a-library-and-model-for-collection-processing.html

14:55 I haven't used reducers / fold myself though, but it sounds like the right solution, maybe amalloy has more specific suggestions

14:56 the basic idea is that each query would construct its own sum, and the reducer would sum each of these as they are ready, I think

14:57 amalloy: sorry, i don't really have time to dive back into the details of how to build custom foldables. i have slides and a script from a presentation i did on it back whenr educers were new, though: https://github.com/amalloy/reducers-presentation

15:00 ptcek: amalloy: thanks for this material I'll go through it

15:14 ericdwhite: Hi I have a questions about using merge to add items to list within a map. I'm looking for feedback on style as I'm new to clojure. What's the best way to post code in IRC? gist?

15:15 llasram: ericdwhite: gists are fine, also https://www.refheap.com/

15:15 ericdwhite: https://gist.github.com/ericdwhite/9079003

15:17 In the example I have a room with a list of people inside, and I want to create a method to allow people to join the room. I'm looking for feed back on the method (join-em)

15:17 amalloy: join-rm could be (update-in room [:people] merge person)

15:18 justin_smith: also, in general, if you know the keys ahead of time, assoc makes more sense than merge

15:18 amalloy: although merge shouldn't work at all here, right? i mean, what i posted is a transformation of your existing code, but you can't merge vectors, only maps

15:18 so really you mean more like (update-in room [:people] conj person), which is pretty normal

15:20 `cbp: I'd do like (defn add-people [room & people] (update-in room [:people] into people))

15:21 amalloy: meh

15:22 whether one person or multiple people makes more sense depends on his context, which we don't know

15:22 i certainly wouldn't use &, though - people being an explicit seq will be more convenient

15:24 ericdwhite: I was adding 1 person at a time, because that was how the UI worked.

15:24 notid: Quick question: is there a splat operator in clojure? I'm wanting to make the vector inline here: (some-func [1 2 3] "hello")

15:24 ericdwhite: so with 'conj' the result is: {:id "room1", :people [{:name "john", :id 1} {:name "sam", :id 2}]}

15:25 And the same for & people with into. Thanks for your help. What I was really missing was update-in!

15:38 dnolen_: notid: apply

15:39 notid: though you can't quite do what you want there.

15:39 (apply some-func (concat [1 2 3] ["hello"])) is about the best you can do.

15:40 notid: unless of course some-fun takes vectors as second arg, then (apply some-fun "hello" [1 2 3])

15:43 ivan: jonathanj: I think I'll go with (mapv (partial reduce +) (apply map list [[1 1] [2 2] [3 5]])) for summing columns; I don't think there's a shorter way to do sum or zip unless you want to define your own

15:56 gfredericks: did java originally have characters or were they stapled on later?

15:57 danneu: Is there another way to sort strings alphabetically (case-insensitive) than to convert to lower-case?

15:58 hiredman: ,(doc sort-by)

15:58 clojurebot: "([keyfn coll] [keyfn comp coll]); Returns a sorted sequence of the items in coll, where the sort order is determined by comparing (keyfn item). If no comparator is supplied, uses compare. comparator must implement java.util.Comparator. If coll is a Java array, it will be modified. To avoid this, sort a copy of the array."

15:58 gfredericks: danneu: String#compareToIgnoreCase

16:00 ,(sort (comparator (fn [^String s1 ^String s2] (neg? (.compareToIgnoreCase s1 s2)))) ["foo" "BAR" "baz"])

16:00 clojurebot: ("BAR" "baz" "foo")

16:00 danneu: gfredericks: brilliant

16:01 hiredman: ,(sort-by #(.toLowerCase %) ["foo" "BAR" "baz"])

16:01 clojurebot: ("BAR" "baz" "foo")

16:09 pjstadig: ,(sort-by (mem-fn toLowerCase) ["foo" "BAR" "baz"])

16:09 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: mem-fn in this context, compiling:(NO_SOURCE_PATH:0:0)>

16:09 pjstadig: ,(sort-by (memfn toLowerCase) ["foo" "BAR" "baz"])

16:09 clojurebot: ("BAR" "baz" "foo")

16:12 danneu: for one use-case, the built-in comparator saves me 2 characters

16:13 borkdude: is there no section on debugging in the clojure cookbook? https://github.com/clojure-cookbook/clojure-cookbook

16:14 hiredman: gfredericks: fns (if I recall correctly) implement whatever the comparing interface is, so you shouldn't need to call comparator or neg?

16:15 llasram: borkdude: Clojure code never has bugs. Once you get code working at the REPL, it generally just works

16:15 borkdude: llasram that is only true if your name is Rich Hickey

16:16 I just discovered this nice tool https://github.com/prismofeverything/schmetterling

16:16 via caribou docs

16:16 danneu: my debug workflow is about as sophisticated as it was at my first vbscriipt job

16:17 borkdude: daniel_karlsson you mean println?

16:17 I mean danneu

16:17 danneu: yes

16:17 borkdude: danneu mine too

16:17 danneu: or clojure.pprint/pprint

16:17 borkdude: danneu and I used swank debug thing

16:17 danneu: when i'm feelin fancy

16:18 borkdude: danneu but I haven't used it in a long while, I don't know if it is even ported to the new nrepl world?

16:19 danneu: i dont know how to make nrepl helpful with stacktraces. right now it just shows the top line of the trace in a 1-inch-high popup which is usually good enough

16:19 the default seemed to print the whole trace in its own buffer that i would have to manually close

16:20 gfredericks: hiredman: I knew there must be an easier way; that's a tricky one to guess though

16:20 pjstadig: that one reflects I think

16:31 borkdude: is anyone around involved in schmetterling?

16:31 yeahyeah I can't use the word anyone here, but now it seems appropriate

16:32 I wanted to ask if it's normal that when I press "continue" the same exception comes up again and again

16:33 justin_smith: borkdude: patchwork is the guy behind schmetterling, I can ask him what is up

16:33 there is a thing where if you do something in the inspector that throws an error, it goes into an error loop iirc

16:34 unless that is fixed

16:34 borkdude: justin_smith yeah I got that, that is documented as well on the page

16:34 justin_smith: oh, ok

16:35 patchwork: borkdude: What is the exception? It all depends on the state of your process

16:36 borkdude: patchwork I opened up a repl with 'lein try schmetterling'

16:36 patchwork: Also, some libraries throw exceptions with the intention of catching them later, but schmetterling will still break on them

16:36 borkdude: and then did this:

16:36 user=> (let [x 10 y 15]

16:36 #_=> (schmetterling.core/debugger))

16:36 patchwork I can inspect x and y

16:36 but when I press continue, I get the same thing over and over, the REPL never returns to the normal state

16:37 patchwork: paste the exception here: https://www.refheap.com/

16:38 I need to document this, but you can add certain exceptions to an exclusion list if certain libs you use pathologically throw them internally

16:38 muhoo: is there some way to make liberator use cheshire instead of clojure.data.json?

16:40 gfredericks: time to write a simple-json-facade-clj

16:41 rasmusto: gfredericks: faceon

16:42 * technomancy shudders

16:42 gfredericks: I'm still trying to solve the problem of making cheshire extensible for libraries

16:42 rasmusto: technomancy: at least there's no ironicjure in it

16:43 borkdude: patchwork https://www.dropbox.com/s/v9fr9vdt4p0uox9/Screenshot%202014-02-18%2022.38.21.png

16:43 patchwork I raised the expection from a repl, calling a function foo with args x y and z

16:43 https://www.refheap.com/41562

16:44 patchwork when I click continue, I get the same screen over and over

16:45 patchwork: borkdude: Hmm…. strange. Must be something about how the exception is interacting with the repl

16:46 it should just finish and continue, but I have never triggered the exception from the repl before, I usually do it from a running app

16:46 hiredman: gfredericks: a module system where every library gets its own copy of cheshire to extend, right?

16:46 patchwork: borkdude: What happens if instead you trigger a different exception, like (/ 1 0)?

16:47 gfredericks: hiredman: man I have no idea how seriously you meant that

16:47 borkdude: patchwork I'll try now again

16:47 bob2: muhoo, how did you make it use either?

16:47 technomancy: parameterized namespacessssss

16:48 bob2: muhoo, I didn't think it did any implicit deserialisation

16:48 hiredman: rewrite cheshire to use some kind of service object, so you instantiate this cheshire object with some parameters and use it

16:48 sdegutis: technomancy: wat

16:48 that would be so cool

16:49 hiredman: gfredericks: I don't know how serious the question is

16:49 gfredericks: (deftype ReadOnlyDereffable [r] clojure.lang.IDeref (deref [_] @r))

16:49 muhoo: technomancy: huh?

16:49 bob2: serialization not deserialization

16:49 danneu: Has anybody ever worked with BBCode with Clojure/Java? I'm looking for a good lib + editor combo

16:49 gfredericks: hiredman: reasonably serious; I have a structured logging lib and would like it to default to str rather than throwing; and maybe a couple other customizations

16:50 bob2: muhoo, ah

16:50 hiredman: (deftype Cheshire ...) (let [c (Cheshire.)] (add-encoder c ...) ...)

16:50 technomancy: sdegutis: apparently OCaml modules do a good job at supporting this

16:50 muhoo: bob2: it uses clojure.data.json to encode application/json types. i could manually just handle types but it defeats one of the purposes of using liberator

16:50 bob2: yeah, i'm less convinced of liberator than I was

16:50 muhoo: it's a Great Beast

16:50 gfredericks: hiredman: the weird part is if I'm going to fork and rewrite or whatever anyhow, I actually solve the problem by using the new version from the logging lib and nowhere else :/

16:50 danneu: Rather, can anyone recommend a good editor that also happens to support BBCode?

16:50 borkdude: patchwork same problem

16:50 gfredericks: fsvo "solve"

16:51 muhoo: it seems way more work than it's worth for some things, but i've got a project that already uses it and don't feel like ripping it all up and starting over ATM

16:51 hyPiRion: gfredericks: (defn read-only-deffable [val] (let [p (promise)] (deliver p val) p)) is not sufficient? Saves you a deftype

16:51 hiredman: gfredericks: stick a copy of cheshire in a classloader where no one else can get at it

16:51 gfredericks: hyPiRion: hey reify would do it too

16:52 bob2: also all the hooks are racey

16:52 borkdude: danneu maybe there is a BBCode mode for emacs? http://www.emacswiki.org/emacs/BbCode#toc1

16:52 gfredericks: hyPiRion: also: (doto (promise) (deliver val))

16:52 bob2: does this url exist at hook time? no? better check in the handler anyway

16:52 hyPiRion: gfredericks: oh nice

16:52 I don't usually deliver promises instantly, but I'll note it down

16:52 danneu: borkdude: oh, i meant for users. like my forum users.

16:52 gfredericks: hyPiRion: useful for any alter-then-return pattern

16:52 rsenior: technomany: do you have any clojure swarming bootstrap scripts for syme?

16:52 borkdude: danneu ah ok ;0)

16:52 gfredericks: (doto (def ...) (alter-var-root ...))

16:53 gtrak: gfredericks: any reason not to use delay there?

16:53 llasram: technomany == a system for cloning technomancy, ensuring the dominance of leiningen over all other build tools

16:53 gfredericks: gtrak: arbitrary refs can have changing values

16:53 rsenior: doh - thanks llasram

16:53 gfredericks: technomancy are the author of the clojure build tool leiningen

16:54 rsenior: technomancy: do you have any clojure swarming bootstrap scripts for syme?

16:54 technomancy: rsenior: there should be one in the repo, but I think there's something wrong with the language detection

16:54 it's just not getting applied somehow

16:55 https://github.com/technomancy/syme/blob/master/resources/languages/Clojure.sh

16:55 https://github.com/technomancy/syme/pull/37

16:55 rsenior: right, I was thinking emacs, starter-kit, clojure-mode etc

16:55 technomancy: oh, personal dotfiles; suer

16:55 sure

16:55 https://github.com/technomancy/.symerc

16:57 borkdude: patchwork I tested now without the repl, causing the exception from a 'lein run', same problem

16:58 patchwork: borkdude: Strange, I'll try to replicate

16:59 borkdude: patchwork this is the code from which the exception is thrown: https://www.refheap.com/41564

16:59 patchwork: It is like it is trying to execute the same function over and over again

16:59 borkdude: patchwork this is my project.clj https://www.refheap.com/41565

17:00 rsenior: technomancy: thanks! Going to give swarming a try this evening at the St Louis Clojure Meetup

17:07 patchwork: borkdude: Ah, if you notice the exception is in a different line and file each time

17:07 I hit continue maybe 15 times and it completed

17:07 gfredericks: (defmacro while-> "Like -> but short-circuits as soon as pred returns falsy for the threaded value." [pred x & forms] ...)

17:07 patchwork: It is just showing every exception getting thrown by the clojure compiler at every level it does that

17:07 I think the main issue is that you trigger the exception when the file is loaded

17:08 (foo 1 2 3) at the root level

17:08 I will try an experiment, just a sec

17:14 technomancy: rsenior: great; good luck

17:14 patchwork: borkdude: Yeah, in general you want to avoid executing things when a file loads. Check this out: https://www.refheap.com/41567

17:15 Instead of (foo 1 2 3) at the outer scope of your file, it is inside the -main function

17:15 gfredericks: oh hey another function with `some` in the name that uses traditional truthiness: some-fn

17:15 patchwork: This protects it from evaluation at load time

17:15 Then in your project.clj just say :main proj.core

17:17 It is still triggered maybe three times, this is the compiler rethrowing the same exception as it percolates up the stack

17:18 technomancy: gfredericks: traditional truthiness is between one true and one false only.

17:20 amalloy: technomancy: this sounds like some weird satire of gay rights

17:20 satire? maybe i mean parody

17:20 borkdude: patchwork I know, this was just for testing

17:21 patchwork testing without a repl that is. normally I don't create calls at top level ;)

17:21 gfredericks: amalloy: anti-gay-rights?

17:22 technomancy: traditional truthiness is int-based

17:22 technomancy: oh snap

17:22 patchwork: borkdude: What I am saying is, that is what makes it seem like the exception is repeating itself, when really it is just sending it through far more calls since it is loading it over and over again

17:22 probably something similar is happening with the repl

17:22 technomancy: don't get all von neumann on me

17:22 borkdude: patchwork ah ok

17:22 technomancy: gfredericks: I follow the teachings of the Church.

17:22 borkdude: patchwork I'll try non-top-level call then

17:22 gfredericks: technomancy: von neumann said it, I believe it, that settles it

17:23 rasmusto: one man and von neumann, please

17:23 technomancy: the Church, who also happens to be A Church.

17:23 hyPiRion: haha

17:23 sdegutis: :/

17:24 hyPiRion: good old Alonzo.

17:24 borkdude: patchwork I now got this. No difference. https://www.refheap.com/41569

17:26 sdegutis: oh thats a nice story, von Neumann died a Catholic :)

17:28 patchwork: borkdude: Keep hitting continue

17:28 its location in the stack changes

17:31 gfredericks: ,(as-> {:foo 12} {:keys [foo bar] :as m} (assoc m :foo 13) (assoc m :bar foo))

17:31 clojurebot: {:keys [13 13], :as {:bar 13, :foo 13}}

17:31 gfredericks: haha

17:31 sdegutis: oh good, we're back on topic

17:31 gfredericks: (inc clojure)

17:31 lazybot: ⇒ 15

17:31 * sdegutis got nervous for a second

17:33 rasmusto: gfredericks: waaah, that's confusing me

17:34 ,(doc as->)

17:34 clojurebot: "([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form."

17:34 borkdude: patchwork that's true. when I keep pressing continue eventually the browser window is 'empty', but what should happen to the call to foo? now my program doesn't respond anymore

17:34 patchwork I think it should just finish now?

17:35 rasmusto: gfredericks: is it supposed to stay 12?

17:35 patchwork: It does finish with an exception in the terminal

17:35 (at least for me)

17:35 ztellman: technomancy: I think you should be a little more open-minded when it comes to churches http://bit.ly/1jP4CEP

17:35 patchwork: Which is correct, since it threw an exception and it is not in a loop

17:36 borkdude: patchwork yes, I would expect that, but not in my terminal :-s

17:37 amalloy: gfredericks: that's pretty silly. as-> could make this work, right, just by letting another gensym at the end? or i suppose by not letting the last version at all

17:38 ie, like https://gist.github.com/amalloy/9081844

17:38 borkdude: patchwork only when I kill the schmetterling instance, my program finishes

17:39 patchwork with the exception thrown

17:41 patchwork: borkdude: Strange, not sure what is up with that

17:41 I usually use it on a web server and trigger the exception on requests

17:41 Then the process continues and you can trigger it again by reloading

17:42 rhg135: quick question, how would i compose a series of channel-returning functions?

17:42 patchwork: Maybe it has something to do with the dt_socket keeping the process alive?

17:42 borkdude: patchwork I don't know. I haven't yet used this in a project, just discovered it.

17:43 bob2: rhg135, ? as in wait on them all?

17:43 hhenkel: (inc oskarkv)

17:43 lazybot: ⇒ 2

17:43 rhg135: bob2, i'm such an idiot lol

17:43 patchwork: borkdude: Well, I haven't officially released it yet, but I use it all the time. I will work on that and see what I can find out. There are a lot of quirks in the java debugging interface I have discovered during this process

17:43 rhg135: knew i was overthinking this

17:44 borkdude: patchwork it's great stuff

17:44 rhg135: just run it all in a go block

17:49 patchwork: borkdude: Thanks! all feedback welcome

17:59 `cbp: heh that as-> stuff

17:59 maybe make a jira ticket?

17:59 technomancy: seangrove: hey, are you still having issues with build speed?

18:00 we rolled out a bunch of changes recently to speed things up; wondering if you've noticed any difference

18:01 sdegutis: oh i saw that on HN

18:02 `cbp: sdegutis: you saw what?

18:07 TravisD: is the seuqence library similar in spirit to the iterator abstraction in the STL for c++?

18:07 like, most containers are iterable, let's use that as a unifying interface?

18:08 bbloom: TravisD: you mean the seq abstraction in clojure?

18:09 TravisD: bbloom: yeah, I guess. The book I'm looking at calls something the "seq library", which I guess is just all the functions for dealing with seqable things

18:09 bbloom: TravisD: there's a tiny bit of commonality, but in reality it is muuch much different than the STL iterator idea

18:09 TravisD: ah okay

18:09 bbloom: TravisD: oh i see you mean on http://clojure.org/sequences

18:10 TravisD: nobody calls it that :-P

18:10 that's just a heading in that documentation page

18:11 TravisD: bbloom: in the book Programming Clojure they talk about the "seq library". But maybe that's just an informal name they are using

18:11 bbloom: TravisD: the major difference between iterators and seqs is that iterators have a much richer network of notions around forwards and backwards, "end" positions, types, etc

18:11 TravisD: ah, right

18:11 bbloom: TravisD: i suspect that's just the author filling content by reading from the clojure home page :-)

18:11 TravisD: seqs have basically two operations of interest: first and rest

18:12 or next, instead of rest, depending on how you look at it

18:12 iterators themselves are mutable, seqs are not

18:12 the fact that they help you traverse a sequential abstraction is basically where the similarities end

18:13 sdegutis: Iterators rock.

18:13 Does Clojure have any?

18:13 AeroNotix: sdegutis: persistent data structures

18:13 immutability

18:13 iterators are at odds with those things

18:13 TravisD: hm, seems like the two concepts are quite related, no? They both are for traversing collections, with the intention of making it possible to write more general algorithms

18:13 the details are obviosuly different

18:13 sdegutis: AeroNotix: It could use atoms.

18:13 amalloy: sdegutis: jillions of them

18:13 &(.iterator [1 2 3])

18:13 lazybot: ⇒ #< clojure.lang.APersistentVector$2@fcf9e1>

18:13 sdegutis: amalloy: as a Clojure-level feature

18:14 bob2: that's not really what atoms are for

18:14 hiredman: seqs are a functional iteration protocol

18:15 sdegutis: Hey now, let's not adopt a "can't do" attitude!

18:15 We can do anything we set our minds to! Let's totally make iterators!

18:15 turbofail: it's not a "can't do" attitude, it's a "shouldn't do" attitude

18:15 hyPiRion: Let's implement goto guys

18:16 yedi_: lol bbloom: i was down with your pseudo troll in the scala thread on HN

18:16 hiredman: http://okmij.org/ftp/continuations/

18:16 bob2: come-from

18:16 hyPiRion: The return of TAGBODY

18:16 sdegutis: hyPiRion: that'd be awesome

18:16 bob2: hyPiRion, (recur)

18:17 turbofail: recur is too limited in its confusion-generation capabilities

18:17 bbloom: yedi_: using the parent response as a template was very trollish, but it was just too fun

18:17 bob2: haha

18:17 turbofail: we need to go further

18:17 bob2: recur to arbitrary points above you in the stack?

18:17 turbofail: random points, preferably

18:17 qbg: It's called throw :p

18:18 hyPiRion: (inc qbg)

18:18 lazybot: ⇒ 2

18:18 sdegutis: But throw only works if you go backwards in execution. I'd like to go forwards.

18:18 I'd like to skip a bunch of steps.

18:19 qbg: Exceptions don't bring you backwards in execution

18:19 Only forward :)

18:19 sdegutis: Backwards up the stack sir.

18:20 bbloom: you guys should totally start where hiredman sent you :-)

18:20 sdegutis: You may totally skip some steps, whatever is between the try high-point and its catch.

18:21 bbloom: oleg's continuations explorations are super insightful, if you have the patience

19:18 whomp: how do i test if a var is an int vs., say, a char?

19:18 right1: (class)

19:18 `cbp: or type

19:19 whomp: so i'd say, (= (class a) Java.lang.Long) ?

19:19 qbg_: ,[(integer? 5) (char? 5)]

19:19 clojurebot: [true false]

19:19 whomp: thx :)

19:19 qbg_: YMMV w.r.t. integer?

19:20 bob2: can you make the caller just provide the right thing?

19:21 akurilin: So let's say I'm bootstrapping some JS for my web application: is there a clojure library that will easily convert clj datastructures into JS syntax so I can inject it into a template?

19:21 It's also possible I'm going totally wrong about this.

19:21 logic_prog: dnolen_ : ping

19:22 `cbp: akurilin: serialize into json?

19:22 akurilin: `cbp: oh derp. Ok cheshire it is then.

19:22 `cbp: :-P

19:22 akurilin: For some reason I totally blanked about that one.

19:23 qbg_: clj->js

19:23 `cbp: qbg_: that's clojurescript

19:23 qbg_: sorry, misread :)

19:52 AmnesiousFunes: The first prerelease of Typed Clojure for Light Table is available here: https://github.com/ndr-qef/light-typedclojure

20:25 marcopolo`: AmnesiousFunes: kudos!

20:26 AmnesiousFunes: Thanks

20:27 Side effects: new LT bug confirmed and 2-3 PRs incoming.

20:39 dsrx: AmnesiousFunes: just curious, why the paredit dep?

20:40 AmnesiousFunes: dsrx: Annotation formatters require some sexp/cursor manipulation

20:40 dsrx: anyone in here using clojurescript to write a chrome extension, spotify application, or anything else that isn't served over http:// (and thus has issues using something like austin or the cljs browser repl)?

20:41 if so I just released something you might be interested in, ping me

20:42 AmnesiousFunes: ah, makes sense

20:50 donmullen: dsrx: interested in using clojurescript for chrome extension development

20:50 technomancy: I wish I could use lisp for extending my browser too

20:50 I don't use chrome though

20:51 sdegutis_: You can!

20:52 All we need to do is invent a way less convoluted version of HTML/CSS/JS, and make it run inside a custom VM, and make it easy to write browsers for, and then write a browser for it!

20:52 Then we'll just add Clojure as a scripting language.

20:53 technomancy: no, first you need to reinvent logic gates. the ones we have now are so clunky.

20:53 sdegutis_: Nonsense.

20:53 technomancy: while we're at it, maybe we could find a better material than silicon for semiconductors

20:53 TimMc: water-based gates are more elegant

20:54 I have ethical objections to silicon doping.

20:54 technomancy: "a less convoluted version of HTML/CSS/JS" -> "Emacs buffers, overlays, and elisp"

20:54 "make it run inside a custom VM" -> check

20:54 "make it easy to write browsers for" -> check

20:55 "write a browser for it" -> check

20:55 ok, that was fun

20:55 sdegutis_: technomancy: how is that last one a check?

20:55 How is it easy to write a custom browser w/ the elisp vm?

20:56 technomancy: the Info reader is a hyperlinked browser

20:56 sdegutis_: Oh, right.

20:56 I was thinking something with pixel-based margins.

20:56 Yes I know, heresy etc.

20:56 technomancy: pixels are so gauché

20:56 if you're going to start from scratch at least use voxels

20:57 there's also http://bzr.savannah.gnu.org/lh/emacs/trunk/annotate/head:/lisp/net/eww.el

21:09 TravisD: Is the list of libraries in a call to (use) is quoted because the symbols it contains may not be defined?

21:10 sdegutis: More like because you don't want to access whatever they may point to.

21:10 ,(def clojure.core 3)

21:10 clojurebot: #'sandbox/clojure.core

21:11 sdegutis: ,(inc clojure.core)

21:11 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.core, compiling:(NO_SOURCE_PATH:0:0)>

21:11 sdegutis: Uhh.

21:11 TravisD: Yeah, I guess you don't want the symbols to be evaluated

21:13 gfredericks: TravisD: notably even after (use ...) finishes those symbols still aren't defined

21:13 ,clojure.core

21:13 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clojure.core, compiling:(NO_SOURCE_PATH:0:0)>

21:13 TravisD: Ah, cool

21:14 an alternative would be to use strings to name the libraries?

21:14 gfredericks: ,(require "clojure.string")

21:14 clojurebot: #<ExceptionInfo clojure.lang.ExceptionInfo: Don't know how to create ISeq from: java.lang.Character {:instance \l}>

21:15 gfredericks: require certainly could have been written that way

21:15 TravisD: oh, I mean, that would have been an alternative way to do it

21:15 gfredericks: namespaces in general are and endless source of n00b confusion

21:15 TravisD: hehe

21:16 I haven't looked at them too closely yet, but some examples in this book were a bit confusing

21:16 it's one of the only place I've seen quoted vectors

21:16 gfredericks: they're not all that complicated, there are just a few things that aren't what you first expect

21:17 quoted vectors are just an alternative to quoting the things inside the vector instead

21:17 e.g. '[foo bar] vs ['foo 'bar]

21:17 TravisD: and you only need to quote it so that the symbols aren't evaluated

21:17 gfredericks: exactly

21:19 TravisD: cool, thanks

21:20 muhoo: how do i rebind a private function inside a ns i don't control?

21:21 bob2: are you sure you need to do that?

21:23 dsrx: donmullen: http://github.com/tomjakubowski/weasel -- provides a websocket transport for the clojurescript repl, as suggested by dnolen in this thread https://groups.google.com/forum/#!topic/clojure/lC8me2Gx_B4

21:27 donmullen: I've not used CLJS for chrome extension development, but I faced a similar problem as the person in that thread connecting a CLJS repl to a spotify application (which is just a web page in an embedded chromium, served over a proprietary sp:// protocol)

21:36 dnolen_: dsrx: donmullen: you all should ping ericnormand when he's around, he's done quite a bit of Chrome Extension ClojureScript dev

21:39 dsrx: dnolen_: good to know, thanks

21:46 echosa: Hey, #clojure. I'm having issues getting a number to always be two decimals places. Not just *display* two decimal places, but actually *be* two decimal places. I've been wroking with (with-precision) and a BigDecimal number, but I just can't quite get it right.

21:47 ,(with-precision 2 (* 100M (/ 3 72)))

21:47 clojurebot: 4.2M

21:47 echosa: ,(with-precision 3 (* 100M (/ 3 72)))

21:47 clojurebot: 4.17M

21:48 echosa: ,(with-precision 3 (* 100M (/ 40 72)))

21:48 clojurebot: 55.6M

21:49 hiredman: decimal places are an artifact of notation, and hence display

21:50 you'll have to be clearer about what you want

21:51 echosa: except with-precision is supposed to round them off, but I'm having problems getting it to always have 2 decimal places. I'm showing percentage, so I can assume that (until I hit 100), I'll only ever have 1 or 2 digits before the decimal point.

21:51 So with 1 digit, I need a precision of 3 (1.23) while with 2 digits, I need a precision of 4 (12.34) it would seem.

21:52 bob2: so you want it to work like money?

21:52 echosa: ,(with-precision 3 (* 100M (/ 1 72)))

21:52 clojurebot: 1.39M

21:52 hiredman: echosa: it certainly sounds like you are concerned with display to me

21:52 in which case you want format

21:52 echosa: bob2: I suppose that's oen way to look at it.

21:53 hiredman: ok, suppose I'm not and treat this as an excersize. Take display out of it. I want the function return value to be the correct value. I can't see whre I'm goign wrong.

21:53 Through everythign I'm sending to clojurebot seems to be working-ish

21:53 I'll check my code for a fifth time

21:54 systemfault: Is the source for clojurebot somewhere?

21:55 hiredman: echosa: in what sense is it wrong?

21:55 systemfault: A IRC bot is usually the first thing I try to write when learning a language :)

21:55 muhoo: systemfault: irclj

21:55 specifically https://github.com/Raynes/irclj

21:56 hiredman: clojurebot is perhaps the definition of a legacy software system

21:56 ~clojurebot is perhaps the definition of a legacy software system

21:56 clojurebot: Alles klar

21:56 systemfault: Thank you

21:56 muhoo: i though clojurebot had a poetic soul

21:56 echosa: hiredman: I'm getting something reproducable. one moment

21:57 systemfault: Is clojurebot bad software or what? :P

21:57 muhoo: systemfault: read the source. it's got... quirks

21:57 systemfault: Now I'm scared of looking at its code because I don't want to learn bad pattern.s

21:58 dsrx: there's also lazybot

21:58 muhoo: systemfault: id suggest looking at irclj, and IIRC lazybot is built on it

21:58 dsrx: I can't speak for the relative quality of either of those projects :D

21:58 systemfault: Ok :)

21:59 muhoo: ok, i asked this, i think. i need to rebind clojure.tools.trace/tracer to a function, globally, that i define (hint: it'll use timbre to log the trace). but i don't reemember how to monkey around with private vars inside someone else's ns

21:59 i'm pretty sure it's possible though.

22:00 * muhoo looks at the source code of dire for clues

22:01 hiredman: ~clojurebot

22:01 clojurebot: clojurebot has a lot of features, most of which are broken

22:01 hiredman: ~botsnack

22:01 clojurebot: thanks; that was delicious. (nom nom nom)

22:01 muhoo: aw, why y'all hatin' on clojurebot.

22:02 it's just different.

22:02 systemfault: clojurebot should be a synonym for awesome :'(

22:02 muhoo: don't listen, clojurebot. you're ok at what you do and we all appreciate you despite your issues.

22:04 hiredman: ~awesome

22:04 clojurebot: your assessment smacks of bias, thus undermining your credibility further. (http://wondermark.com/560/)

22:05 echosa: hiredman: I think it's a logic problem. Lack of sleep. :-/

22:05 systemfault: Oh god... nobody cares about the bot :P It hasn't been touched for 5 months now :P

22:08 hiredman: we have an instance of clojurebot running in our work irc channel, if you ask it about itsself it claims to be powered by neglect

22:09 systemfault: That's what I was saying... the source code of the bot looks neglect'ed

22:09 hiredman: it is mature software

22:09 amalloy: systemfault: what's to change? clojurebot works

22:10 hiredman: clojurebot: amalloy |claims| clojurebot works

22:10 clojurebot: In Ordnung

22:10 amalloy: that's what i get for skimping on the "mostly"

22:10 systemfault: amalloy: Just saying that nobody has committed to it in half a year :P Sorry

22:11 And it's saying that it's a WIP...

22:19 voldyman: AeroNotix: i swtchied from jetty-adapter to http-kit and sqlite to mysql 500 concurrent connections have negligible overhead.

22:24 echosa: it's weird typing "true" instead of "t"

22:25 muhoo: hmm, i'm not seeing any clues in dire. and google is failing me.

22:25 * muhoo goes off to look in the source to leiningen

22:26 muhoo: aha, robert.hooke looks lively

22:28 * muhoo and hones in on alter-var-root, at last. doh.

22:28 systemfault: Perhaps I'm just saying this because I'm a noob... but I love clojurebot's code :/

22:28 muhoo: it's got some funny stuff in it. and some really esoteric interesting stuff IIRC

22:39 delightful! https://www.refheap.com/41829

22:49 dnolen_: pushing out Om 0.5.0-rc1 so people can test against React 0.9.0-rc1

22:54 Tolstoy: dnolen_: Noticed that IWillUnmount isn't on the documentation page. File an issue?

22:54 dnolen_: Tolstoy: better, feel free to add it :)

22:55 noprompt: dnolen_: whoops, sorry i pinged you on twitter. thought you were away.

22:56 dnolen_: wrt using om.core/value

22:56 dnolen_: noprompt: it's hooking a bit into implementation details but I don't forsee changes there in the near future

22:57 noprompt: one thing to be concerned about is that om.core/value will return a "cached" value

22:57 noprompt: (vector? data) doesn't work properly but (vector? (om.core/value data)) works fine

22:57 dnolen_: which may or may not reflect the application state

22:57 noprompt: ah ok

22:57 dnolen_: noprompt: yes because we wrap IIndexed types, so it won't be a vector anymore, just IIndexed

22:58 noprompt: that might change in the future, but I haven't felt a need to more specific yet

22:58 noprompt: dnolen_: so how would you suggest going about building a component based inspector?

22:58 dnolen_: noprompt: I haven't put much thought into it honestly, though I'm pretty interested in that.

22:59 noprompt: kovasb has been doing some interesting work here as well

22:59 noprompt: you want to be able to inspect ClojureScript values right?

22:59 noprompt: dnolen_: awesome.

23:00 dnolen_: right. and i need to known the type before i make a decision about class names, rendering etc.

23:00 dnolen_: noprompt: honestly the best thing would be to really examine how Om works

23:00 noprompt: and then tell me what you think you need that isn't already there

23:00 and we can discuss

23:01 noprompt: dnolen_: sure. that's how i came across om.core/value. i'm starting to dig through the source more.

23:02 dnolen_: we successfully built a decent single page client side app with om/secretary at work.

23:02 dnolen_: noprompt: awesome :)

23:02 noprompt: dnolen_: there's a template we started working on but haven't finished it yet.

23:06 dnolen_: noprompt: kovasb is really working on exactly the same thing - ClojureScript value inspector

23:06 I would love to see this as a generic reusable component

23:06 super useful for everyone.

23:08 noprompt: dnolen_: i've got most of the pprint part working; just wanted to know what would be the safest route to ask vector? map? etc w/ cursors.

23:09 dnolen_: this morning i noticed om.core/read is no longer a part of the API.

23:10 dnolen_: noprompt: yep it's been gone for a while now

23:10 noprompt: no longer needed

23:10 noprompt: you can just deref

23:10 noprompt: to deal w/ vectors you need to wrap in VectorCursor which of course I haven't implemented.

23:11 the hook is -to-cursor

23:11 noprompt: dnolen_: but i'd have to implement all the protocols right?

23:11 dnolen_: VectorCursor would need to support all the obvious ops, and implement the IVector marker protocol

23:11 noprompt: yes you would.

23:12 noprompt: but it's just boilerplate

23:13 noprompt: another way is perhaps to do this via metadata?

23:13 mgaare: is anything going on with ritz? plans to get it up to date with the current state of things in emacs, cider, etc?

23:16 noprompt: dnolen_: doesn't look like meta did it.

23:17 dnolen_: i guess i could take a swing at the protocl implementation.

23:17 dnolen_: it doesn't look to big. just wordy.

23:17 dnolen_: noprompt: oh, right ... you can check type of value to if that's what you were thinking about

23:17 noprompt: implementation detail for you that you can switch later

23:18 noprompt: dnolen_: yeah. basically that's all i'm doing is a cond with (type-fn? (value data))

23:19 dnolen_: noprompt: ok that's fine for now, and you can do something cleaner later I think.

23:19 noprompt: dnolen_: heh, well now i'm looking at the protocol thing. :)

23:29 akurilin: Question: ok so let's say you use Migratus for DDL migrations. What do you use for when you also need to "migrate" the data itself as part of that schema change? For example, say you're splitting a table into two: you'd make the new table, move the data from the old one, and then apply schema changes to the old table, all within one transaction.l

23:30 You can do it in Migratus as long as you can do the move 100% in sql statements, but it'd be cool to be able to plugin some jdbc/korma logic in there too.

23:31 logic_prog: is there a way to define a function that is called every time a namesapce is loaded?

23:31 I wnat my own tool to *sanity-check/lint* every namesapce that is loaded

23:31 akurilin: Right now I essentially do a partial migration, run a task from clojure, then complete the migration.

23:33 noprompt: ,(ns foo (:println "foo"))


23:33 clojurebot: foo\n

23:33 noprompt: logic_prog: ^

23:34 logic_prog: noprompt ... hmm

23:34 noprompt: logic_prog: dunno, if that helps but when you load the file that code will run.

23:34 logic_prog: noprompt: my question was poorly phrased

23:34 noprompt: let me write it up, spam the clojure list, and point you to the clojure list

23:36 noprompt: how did i not know about specify?

23:37 logic_prog: noprompt: https://groups.google.com/forum/#!topic/clojure/wx-naQUqi4o

23:37 noprompt: is specify a clojure function?

23:37 noprompt: I'm not seeing it here: http://clojuredocs.org/search?x=0&y=0&q=specify

23:38 noprompt: looks like specify and specify! are clojurescript fns

23:38 sorry, macros

23:40 logic_prog: honestly, and this could be the wrong idea, but you might need a macro for that.

23:40 logic_prog: noprompt: I agree, I think macros = wrong idea. :-)

23:40 I don't want to do things like :my-require ...

23:40 or hack ns

23:41 noprompt: logic_prog: for instance (defmacro slurp [file] `(clojure.core/slurp ~file)) will work in clojurescript but only at compile-time.

23:41 logic_prog: worse yet, it won't be called every time a clj file is reloaded

23:41 noprompt: whoops drop the ` ~

23:42 logic_prog: that would at least give you the ability to read the file so it would be available in cljs land as a string.

23:44 logic_prog: in this case i'm not sure i would totally agree that macros are the wrong way to go because you may actually need *clojure* to do what you want.

23:49 logic_prog: (inc noprompt) ;; for effort :-)

23:49 lazybot: ⇒ 1

23:51 * dsrx ponders the dynamically bound var *clojure*

23:51 sdegutis: ,*clojure*

23:51 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: *clojure* in this context, compiling:(NO_SOURCE_PATH:0:0)>

23:51 sdegutis: Nope.

23:52 noprompt: guess my points got reset. :/

23:55 sdegutis: $karma noprompt

23:55 lazybot: noprompt has karma 5.

23:56 sdegutis: noprompt: it's just an eager regex

23:56 (inc noprompt) one more paren for good measure)

23:56 lazybot: ⇒ 1

23:56 sdegutis: (inc noprompt) and another)

23:56 lazybot: ⇒ 1

23:56 sdegutis: :)

23:58 noprompt: logic_prog: here's the gist (ns foo.core

23:58 (:refer-clojure :exclude [slurp]))

23:58 (defmacro slurp [file]

23:58 (clojure.core/slurp file))

23:58 ;; In CLJS

23:58 (ns bar.core

23:58 (:require [foo.core :include-macros true :refer [slurp]]))

23:58 ;; This is possible because we can evaluate *Clojure* code at compile time.

23:58 (def project-clj

23:58 (slurp "project.clj"))

23:58 well shit. i meant to give you a link. ;_;

23:58 https://gist.github.com/noprompt/9086232

23:58 i'll post to the ML too for good measure. ;-_

23:59 _eric: does clojure have a string quoting notation like ruby's %{} or scala's """ """?

23:59 (to make it so you don't have to escape a double quote)

23:59 logic_prog: spammer!! :-)

23:59 (inc noprompt)

23:59 lazybot: ⇒ 6

23:59 noprompt: _eric: no

23:59 _eric: bummer

23:59 noprompt: _eric: you've got str though

Logging service provided by n01se.net