#clojure log - Jun 10 2014

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

0:00 PigDude: even more than the stacktraces -,-

0:09 probably people with questions like these use other testing tools eventually

0:17 justin_smith: well, since a standard function can call is, you can construct your test such that you pass args or even an env map describing the values you need to each of those functions

0:28 ddellacosta: I can't use destructuring in deftype/defrecord args, huh

0:28 * ddellacosta pouts

0:34 amalloy: ddellacosta: you mean the fields held by a deftype? indeed you can't. but you can in the args passed to a protocol function or interface method

0:34 ddellacosta: amalloy: yeah, I was talking about the fields. I guess what I've got here is a smell that I'm probably doing something wrong design-wise, though.

0:36 gratimax: ddellacosta: you should probably extract that destructuring logic into another function

0:36 amalloy: yeah, that'd be pretty weird. you wouldn't want to be able to support something like (deftype Foo [[x & y :as z]]) - what fields get stored for real, and what gets computed on the fly? it's antithetical to the performance goals of deftypes

0:37 PigDude: justin_smith: but then your tests fail in one big function?

0:37 justin_smith: (one big test)

0:38 ddellacosta: amalloy, gratimax: what I've got is a lot of configuration values getting passed in, which should probably be defined by the type user by extending the type with another protocol

0:38 ...or something like that. Alternatively, I may just pass in a single opts hash-map for those options that make sense

0:38 amalloy: ddellacosta: or just define a function that builds these records. don't use (Foo. x y z) as your public-facing api, expose something nicer

0:40 gratimax: ddellacosta: I use maps for config and have functiosn that operate on those maps in cases like this

0:40 ddellacosta: amalloy, gratimax: yes, I suppose that's a good strategy--just have a config! function that takes an option map or something, and returns an instance of this thing.

0:40 still, can't help but think this is a bit ugly

0:41 amalloy: why in the world would it be a bang function?

0:41 gratimax: ddellacosta: what does it mutate? why the bang?

0:41 amalloy: (defn build-the-thing [config] (TheThing. (whatever config)))

0:41 ddellacosta: amalloy, gratimax: ...why would it not? It's mutating state by creating an instance of a thing, is it not?

0:41 justin_smith: PigDude: not really, your deftest can pass whatever data to the individual test functions it needs to run, which should be fairly modular. If you need the same setup for multiple deftests, then once again you can use a function that sets up that data for you (since you shouldn't be testing based on side effects in one test in the next test anyway, their order should be unimportant)

0:42 gratimax: ddellacosta: unless you're using a previous thing and changing its state, then no

0:42 amalloy: if allocating objects mutated state, everything in clojure would have a bang

0:42 justin_smith: PigDude: most convenient is likely a function (or maybe a few for parameterization) that returns a map of options

0:42 or you can just def the map if they are going to be the same options

0:42 amalloy: like, conj makes a new list

0:43 PigDude: justin_smith: but you can't have your cake and eat it too, either you have no failure locality, or you have failure locality as you said, and so all you see is line 234 in test-project (your big test function)

0:43 justin_smith: sorry for being obtuse

0:43 justin_smith: is there somesmall example of this?

0:43 ddellacosta: gratimax, amalloy: huh, okay...never thought of it that way. I guess this seemed different for some reason, but that's a good counterpoint.

0:44 gratimax, amalloy: anyways, in the end I'm not sure that the config fn is saving the user much if they still have to pass in a big bunch of options

0:44 gratimax: ddellacosta: just interested.. what's your use case?

0:45 ddellacosta: gratimax: initializing a set of configuration variables for a database + messaging related lib

0:45 gratimax: to be very general

0:46 justin_smith: PigDude: https://github.com/caribou/caribou-core/blob/master/test/caribou/test/model.clj each defn tests a different kind of thing, then they are called in deftests that parameterize (in this case across db backends since they are not fully compatible in the sql they support) - when I get an error in the tests it tells me which backend was being tested, and which function in that test was being run

0:46 PigDude: pardon some of the weird naming please, a coworker was stoned when writing some of those tests

0:46 gratimax: ddellacosta: you could possibly do stuff like korma hand have 'defdb' or something that mutates an internal variable and have operations on that

0:47 ddellacosta: gratimax: trying to avoid doing anything like Korma actually...haha. But more to the point, the database config is just a small part of it.

0:48 gratimax: you do (defdb {:db "korma"

0:48 :user "db"

0:48 :password "dbpass"})) and then every subequent operation modifies that

0:48 oh, ok

0:48 PigDude: justin_smith: standard operationg procedure, of course. the trouble is running htis test so i can see what happens when it fails ... i don't hvae these servers around, etc.

0:48 justin_smith: i see the technique, looks reasonable

0:48 ddellacosta: gratimax: there is database config, then past that ways for subscribing to messages, and flags for related behavior (filtering and whatnot). I just have to find the right way to organize it all.

0:49 PigDude: justin_smith: but i fear when the test fails you are seeing failure: postgres-tests, not failure: collection-map-test

0:49 justin_smith: PigDude: that's what test/testing is for

0:49 I get both messages

0:49 I promise

0:49 those tests break a lot, so I have to make sure they give me reasonable output :)

0:49 gratimax: ddellacosta: if all you're doing is initializing then reading from config, I would keep the config to simple maps with accessor functions

0:50 PigDude: i wish i could run them but i'm not ready to configure mysql/postgres on localhost to run this :\ do you have an example of failure output?

0:50 mdeboard: Are vars considered harmful?

0:50 PigDude: fine if not, this is a nice example

0:50 mdeboard: I thought I read something saying ~that recently

0:50 justin_smith: PigDude: well you could run h2, but that would require the bootstrap stage

0:50 one sec, I'll make one break

0:51 PigDude: justin_smith: clojure testing seems very "seat-of-your-pants"

0:51 gratimax: so your api would be something like 1. (defthing mything {:config "x" :other-config "y"}) 2. (subscribe! mything :my-message ...) 3. (filter mything :my-message ...)

0:51 mdeboard: dynamic vars, I guess.

0:51 PigDude: justin_smith: with projects inventing their own schemes

0:51 justin_smith: as does this one

0:51 gratimax: mdeboard: depends on use case, like everything

0:51 ddellacosta: gratimax: yeah, the basic thing that I'm wrestling with is that I have this central...thing that gets passed around--it has to know both about database stuff as well as messaging stuff. And I'm having trouble keeping it clean while still allowing the user to configure it simply. So I'm still searching for the right design principle here...we'll see. In any case, thanks for the help, also thanks to amalloy.

0:51 PigDude: justin_smith: (and mine)

0:52 mdeboard: Oh, I misunderstood the thing.

0:52 justin_smith: PigDude: it's just higher order functions being used to permute over some options, this is a pretty standard thing, and given we have pervasive statelessness and immutability, we don't actually need a lot of the other unit testing conventions

0:53 gratimax: ddellacosta: is the user going to create multiple things? if yes I would do like korma, if no, I would pass it around

0:53 ddellacosta: final option is a macro like (withthing mything (subscribe! :my-message) (filter ...) ...)

0:53 justin_smith: (until we have stateful / mutating code, then yeah maybe you should check out junit or midge or whatever)

0:53 ddellacosta: gratimax: the user needs to be able to set up a message queue, subscribe to messages, and then update a database which triggers messages getting sent out. Definitely trying to avoid a config macro...something we've considered though.

0:55 gratimax: ddellacosta: I see. I probably don't know enough about the project to give you any more useful advice. good luck anyway

0:57 ddellacosta: gratimax: yeah, I probably have to go into more detail before I can solicit useful feedback...but thanks, I appreciate getting your thoughts! It's helpful nonetheless.

0:57 PigDude: justin_smith: i agree about the strengths of immutability and fp for testing, i find tests very easy and reliable to write in erlang, but i am waiting for (or might work on :)) something in clojure like eunit+ct

0:57 justin_smith: i think it's nice to have some conventions even in a powerful language

0:58 mdeboard: here's what I was thinking of http://stuartsierra.com/2013/03/29/perils-of-dynamic-scope

1:00 PigDude: justin_smith: btw this caribou library is neat

1:00 justin_smith: PigDude: it's pretty huge

1:00 PigDude: hehe

1:00 justin_smith: lein new caribou gets you a MRM (map relational model), an interactive web based cms for lay-users, a default schema bootstrapped...

1:01 also the cms is totally own-dogfood built in the lib itself

1:01 it's too big and too bloated and too frameworky, but it helped me get a lot of work done and was definitely a fun learning experience

1:01 PigDude: util/dbize is useful for something i am doing

1:02 this technique

1:02 justin_smith: and also, despite the massive ram usage, it performs very well

1:02 even has a caching image resizer with s3 integration built in, full kitchen sink

1:02 PigDude: if you care about ram you aren';t using clojure

1:02 justin_smith: heh

1:03 OK I fixed the logging level so the test output wasn't a huge spew of noise, now to make a test fail and share the output

1:03 PigDude: ty so much

1:04 justin_smith: np, this matters to me, because if I am wrong and there is a better way to do this, then you'll make something better, and we all win

1:05 so there are some stray printlns that I totally need to delete, but I think the location and context of what failed is very clear here https://www.refheap.com/86426

1:06 see how I get a line number, but also the test name and the testing statement- it is unambiguous where things were when it failed

1:10 as well as the file name, of course

1:13 PigDude: justin_smith: not too bad

1:14 justin_smith: so the (testing strings get you there

1:14 justin_smith: i like it!

1:14 skinkitten: thanks justin_smith lots of help earlier today

1:14 justin_smith: skinkitten: np

1:14 skinkitten: going to learn a lot from you

1:14 justin_smith: PigDude: also, is takes an optional string argument, if you want to provide even more context

1:14 skinkitten: with any luck

1:15 PigDude: yea i always use that

1:15 andyf: and the string can be dynamically built at test run time with str, format, etc.

1:15 PigDude: is this the official clojure.test docs? http://richhickey.github.io/clojure/clojure.test-api.html

1:15 it's confusing how the docs are everywhere

1:15 andyf: yes

1:15 seancorfield: the richhickey repo is old

1:15 andyf: oh, wait, no, that is the old one as sean said

1:16 PigDude: yea that was my fear, that these richhickey github io pages are all out of date

1:16 seancorfield: here http://clojure.github.io/clojure/clojure.test-api.html

1:16 PigDude: thanks, i'll go there

1:16 andyf: That said, the up to date official docs aren't necessarily more explanatory than the old out of date one :)

1:16 PigDude: this helps a lot, i was getting pretty frustrated and making some ugly testing schemes

1:17 justin_smith: I put many hours into those caribou.model tests, I wonder how many useful clojure.test features or idioms are missing from there

1:19 skinkitten: :)

1:21 seancorfield: We started out using clojure.test at World Singles but now we only use it for our WebDriver stuff since it feels very imperative - do stuff, assert something observable, do more stuff, assert something observable...

1:21 We switched to Expectations about 18 months ago

1:21 mdeboard: haha

1:22 reminds me of that SNL skit from years ago, "Lowered Expectations"

1:22 https://www.youtube.com/watch?v=6xLsRI7-hBs

1:22 s/SNL/MadTV/

1:24 justin_smith: seancorfield: interesting - I found my tests were mostly about asserting some property of a returned data structure (other than fixtures, but the point is that those abstract the procedural setup from the functional values)

1:26 skinkitten: hi seancorfield :)

1:26 seancorfield: Expectations makes it easy to test a bunch of things about a returned value, all at once

1:26 skinkitten: I remember you from programming language DEC 2013

1:26 seancorfield: Hiya skinkitten - enjoying Clojure now?

1:27 skinkitten: great course, learned a lot from you ^^ I hope you're doing great . yes I am, it is a nice language, reminds me of racket

1:29 seancorfield: skinkitten yeah, life is good... spent the day working with Mark Engelberg's Instaparse to create a way to specify our search rules in "English" :)

1:30 skinkitten what have you been working on since PL?

1:36 wei: what’s a good way to create a lookup map from a list? e.g. lookup by id ({:id 1 :data 123}, {:id 2 :data 456}) => {1 {:id 1 :data 123}, 2 {:id 2 :data 456}}

1:37 andyf: wei: (group-by :id lst) is close to what you ask for

1:38 mdeboard: ooh

1:38 andyf: except that each map value is a vector of values with the same value of the function.

1:38 wow, I didn't edit that sentence before sending it

1:38 mdeboard: haha

1:39 I invented my own way of doing that... https://github.com/mattdeboard/ticket-to-ride/blob/master/src/ttr/board.clj#L262

1:39 I needed an index based on the values of multiple keys

1:40 i'm sure there's a function out ther ethat does exactly what i need already, does group-by take a func?

1:40 sho nuff

1:40 I'm even using it here https://github.com/mattdeboard/ticket-to-ride/blob/master/src/ttr/board.clj#L322

1:40 oh well, for tomorrow.

1:41 wei: thanks. basically just need a function for updating an element in a list, would be nice if it’s constant time

1:42 ,(into {} (for [[k v] (group-by :id '({:id 1 :data 123}, {:id 2 :data 456}))] [k (first v)]) )

1:42 clojurebot: {1 {:id 1, :data 123}, 2 {:id 2, :data 456}}

1:42 wei: kinda verbose though

1:43 PigDude: seancorfield: cool, i'll look at expectations

1:44 andyf: wei: There is a function often called map-vals that many people have defined that does what everything except the group-by call in your example does.

1:44 skinkitten: seancorfield, amazing! I've been completing coursera courses! I can't get enough of them, upcoming are algorithms and a principles of computing by rice. programming in a lot of languages is fun, these past days I've been programming in ruby,python,racket,clojure :D

1:44 andyf: well, almost everything: (map-vals (group-by :id lst) first)

1:45 or probably actually the other way around on args: (map-vals first (group-by :id lst))

1:45 wei: right. map-vals should come with clojure :)

1:46 andyf: (defn map-vals [f m] (into {} (for [[k v] m] [k (f v)]))

1:46 often redefined, and yes, it wouldn't be bad if it were in core

1:47 https://github.com/jonase/eastwood/blob/master/src/eastwood/util.clj#L9-L23

1:47 amalloy: andyf: https://github.com/flatland/useful/blob/develop/src/flatland/useful/seq.clj#L422 is a more general group-by that allows you to do those steps all at once, without the intermediate list of things you don't care about

1:48 seancorfield: skinkitten cool, i've done a lot of languages over the years, but i like working mostly in clojure/script nowadays :)

1:48 wei: these are quite useful functions (as the name claims)

1:49 amalloy: ^

1:49 andyf: amalloy: amalloy/useful has issues and pull requests, but flatland/useful does not. Should interested parties file issues against flatland/useful?

1:49 mdeboard: holy crap

1:49 awesome.

1:50 amalloy: andyf: i don't know, really. flatland/useful used to be the official home, but in the geni layoffs i took it

1:50 seancorfield: ,(into {} (map (juxt :id identity) '({:id 1 :data 123} {;id 2 :data 456})))

1:50 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

1:50 amalloy: i'm still used to linking to flatland, and don't really think of it as mine; but we split up the flatland repos so that our personal github pages don't look so lonely

1:50 seancorfield: oops

1:51 ,(into {} (map (juxt :id identity) '({:id 1 :data 123} {:id 2 :data 456})))

1:51 clojurebot: {1 {:id 1, :data 123}, 2 {:id 2, :data 456}}

1:51 wei: amalloy: groupings does not seem to compile in clojurescript: if-let requires exactly 2 forms in binding vector

1:51 seangrove: wei: It's about time I left the country, thinking about Korea - you still out that way?

1:51 wei: there’s no if-let in there though, weird

1:51 andyf: wei: if-let is in core

1:52 wei: sorry, wasn't following your meaning carefully enough.

1:53 amalloy: huh, should compile fine. dunno what's wrong

1:53 wei: seangrove: yup, in Beijing now. we should meet up!

1:58 skinkitten: seanaway, nice :)

3:16 ddellacosta: seangrove: stopping in Japan?

3:16 danielcompton: When upgrading leiningen (or most other CLI apps), why does it show "Do you want to continue [Y/n]" with a capital Y and lowercase N?

3:17 ddellacosta: danielcompton: I assume that indicates the default

3:17 danielcompton: ddellacosta: that makes complete sense

5:55 silasdavis: I need something like a sorted-map, but with the ability to lookup the neighbours of a particular key

5:56 so for example if the map had

5:56 {:aa 1 :ab 3 :cd 4}

5:56 I cna find out that the left neighbour of :ac would be :ab and the right :cd

5:57 It would be fine if I had to first :ac, and thenn somehow get the previous

5:58 Glenjamin: silasdavis: have a look at clojure.data.avl

5:58 i think that does what you describe

5:59 silasdavis: ah perfect

5:59 yes I think it does

5:59 thanks

6:07 is there any performance difference between using destructuring, [head & tail], to get the first/rest of a seq (actually a vector in this case) vs using the functions?

6:12 clgv: silasdavis: might be (depending on the concrete access). you are on the safe sight by using the API function of data.avl

6:13 john2x: is vector a sequence?

6:14 clgv: john2x: what sequence property are you interested in?

6:16 &(->> [] class ancestors sort)

6:16 john2x: clgv: I'm just confused when tutorials/books/docs talk about functions working on sequences.. e.g. whether I should explicitly (seq ..) a vector when a function expects a sequence, etc..

6:17 clgv: john2x: functions working on sequences do call "seq" themselves usually

6:17 john2x: seq+next in recursion or lazyseq tail is a common pattern

6:18 john2x: oh ok.. and `seq` works on vectors.. so sequences mean anything that can be seq'd?

6:18 clgv: john2x: in summary those functions work on vectors but the reult is not a vector anymore

6:19 only exception are mapv (for one sequential datstructure) and filterv

6:19 ,(seq [4 7 9])

6:20 clojurebot: (4 7 9)

6:21 clgv: john2x: yes in that context sequences and things you can get sequences from are meant

6:22 john2x: clgv: thanks. makes a lot more sense now..

7:15 clgv: I still wonder why this happens: "ClassCastException [trace missing]" - after reevaluation of the namespace I get no exception traces anymore :(

7:36 danielcompton: As a Clojure project grows in age, probability that it will write its own version of dissoc-in approaches 1 http://crossclj.info/search?q=dissoc-in

7:38 noidi: heh

7:42 clgv: danielcompton: well isnt there a jira ticket for dissoc-in?

7:43 danielcompton: http://dev.clojure.org/jira/browse/CLJ-1063

7:43 Affects 1.4

7:43 :)

7:43 clgv: ha right, thats the one I created ;)

7:51 mduerksen: didn't know about crossclj - how cool is that! :)

7:52 clgv: hmm does crossclj index clojars? since there are definitely some functions on github that I do not find with it

7:52 phillord: Is any one else getting crashes from lein help release (for the new version) or is it just me?

7:52 clgv: phillord: was there an update?

7:53 phillord: 2.4.0

7:53 which includes a release task:-)

7:53 clgv: lein 2.3.4: lein help release => Task: 'release' not found

7:54 phillord: yes

7:54 it's 2.4.0

7:58 clgv: no I mean thats the result with 2.3.4 ;)

7:59 phillord: yes, I would have guessed that would be the result

8:00 as the release task is new in 2.4.0

8:00 CookedGryphon: phillord: yeah, i got a stack overflow for lein help release

8:00 phillord: it takes 5 minutes to overflow for me, which is the strange thing

8:06 engblom: Is lein still used? It seem to pull down an old version of Clojure

8:07 kzar: engblom: Lein is still used, clojure version generally depends on project.clj. Also have you tried `lein upgrade`?

8:12 engblom: kzar: It must have been updated very recently. I also did 'lein upgrade' last week and then it was still using 1.5. Now it is using 1.6

8:13 kzar: Cool OK

8:17 engblom: I have JDK installed myself, but if I want to deploy a clojure project somewhere, is JRE enough?

8:18 How is the compilation happening? Is it outputting java-code which then javac compiles or is clojure directly outputting java bytecode for jre?

8:18 Bronsa: engblom: the compiler emits jvm bytecode directly

8:19 engblom: Bronsa: Thanks!

8:28 deathknight: Hey guys, it just occurred to me that collaborating on an open source project might not be unlike being in a corporation in Eve-Online or a clan in a game. I'm an amateur and think being in a collaborative environment would be advantageous to my learning. What is a project that one recommends that I contributing to?

8:28 mdrogalis: deathknight: Leiningen, perhaps.

8:29 deathknight: sweet, that has a pretty active community

8:35 sdegutis: Is lein ring uberjar still the recommended way to compile simple ring-baed Clojure web apps?

8:37 hyPiRion: deathknight: If you have any questions re: leiningen problems, feel free to ask over at #leiningen

8:38 deathknight: In addition, xeqi -- which knows a fair bit of lein stuff, wanted to pair with people: http://nelsonmorris.net/2014/04/07/saturday-remote-pairing.html

8:38 deathknight: awesome!

8:38 This helps so much, hyPiRion

8:38 thank you

8:38 hyPiRion: no problem, hope it helps

8:39 deathknight: It does, tremendously

8:39 hyPiRion: I'll try to be more active over there and help people after this week is over, too. (Currently in my last week of my master's thesis)

8:39 mdrogalis: hyPiRion: Your tweets scare me.

8:40 hyPiRion: mdrogalis: I'm afraid I'm going crazy

8:40 mdrogalis: You can join Donny K.

8:40 I think he'd punch me if I called him that.

8:40 sdegutis: Is it natural that the bigger a project gets, the less control I want to give to third-party libraries over how it's launched and executed?

8:40 (i.e. lein ring)

8:49 catern: sdegutis: why don't you want lein ring?

8:50 sdegutis: It's not that I don't want it.. it's that I don't know what it's doing, and that means I have less control over my project.

8:50 Also, I see that when I run lein ring uberjar, it adds a :main task to my project, but Lein complains that there's no :aot for it. The solution for this would be more obvious if I added :main by myelf.

9:30 mdedetrich: hey I am getting familiar with clojure + light table, and I was wondering if there is a list of default keymaps for paredit, or is it something you have to manually configure (and if so, is there an idea config I can get from somewhere?)

9:31 Glenjamin: mdedetrich: LT inherits a bunch of keybinds from codemirror

9:31 mdedetrich: Glenjamin: can you provide me with a link?

9:32 Glenjamin: everything LT-specific is the in the "Default/User Keymaps" page

9:32 mdedetrich: Glenjamin: ah brilliant, thank you!

9:33 Glenjamin: this might help

9:33 https://bitbucket.org/glenjamin/dotfiles/src/master/LightTable/settings/user.keymap?at=master

9:33 those are my keybind overrides

9:34 mdedetrich: Glenjamin: yeah there doesn't seem to be anything spefic to paredit in the default section

9:36 but thanks for the help, looks like I got some exploring to do

9:54 silasdavis: is using a keyword as a function to access record fields going to be any slower than using the java interop directly?

9:54 i.e.

9:54 (.children node) vs (:children node) for some record node

9:55 tesmar: I am addicted to 4clojure.com

9:55 silasdavis: and which, if either, is prefered

9:55 tesmar: it’s awesome and a great challenge

9:58 pjstadig: silasdavis: i would suspect that (.children node) would be faster, but as always with speculation it should be profiled

9:59 silasdavis: there are other considerations like that using (.children node) won't allow you to process non-record maps, so it creats more brittle code

9:59 *creates

10:00 silasdavis: yeah I'd prefer symbol access if the difference is anything other than neglible

10:01 does anyone know how to clear all assignments in lighttable? I keep restarting it to get a clean repl

10:01 pjstadig: clojure does some work to make keyword callsites fast, so i'm not certain that it *would* be non-neglible

10:17 honza: what's the standard way of installing java on osx these days? i seem to be stuck on java 6

10:28 justin_smith: honza: oracle or openjdk should have installers for download that just work™

10:35 stuartsierra: silasdavis: Keyword access is always preferred.

10:36 Unless you're using the record in a hot loop, there should be no visible difference.

10:42 canweriotnow: I’m working on implementing an OAuth2 provider in a ring/compojure app. I’ve been playing with https://github.com/pelle/clauth but I was wondering if anyone had found/created any better solutions for this?

10:52 philandstuff: canweriotnow: I'm interested in this too, particularly around building OpenID Connect providers and consumers

10:53 it's probably worth investigating java libraries that you could call from clojure

10:57 gfredericks: why does cider-nrepl use snapshots? do emacs people hate concrete versions?

10:58 gtrak: there will be a stable release in a couple weeks.

10:58 cbp: its pretty much like auto update man

10:58 every 24 hours

10:59 gtrak: I do like that aspect of it, when we're not breaking people (sorry) :-)

10:59 it's also been discussed to have a separate dev branch

11:01 gfredericks: I prefer to only update my dev tooling when I'm in the mood to do so

11:02 emacs' package manager thing seems to make this difficult too

11:02 gtrak: gfredericks: yea, that's hell. I'm going to rework mine with el-get when I get a chance.

11:02 but I've been running cider from a git checkout.

11:02 since I hack on it.

11:16 tvanhens: Is using lein run an acceptable way to run an app in production or is it preferred to build to uberjar?

11:17 llasram: 1000x the latter

11:17 nixn: tvanhens: it depends on how the underlying webserver runs (security-wise)

11:17 hyPiRion: Unless you have good reason to use `lein run` over uberjaring, use uberjar

11:18 tvanhens: gotcha thanks.

11:18 Glenjamin: there's a gotcha with uberjars

11:18 in that any jvm-opts you'll need to include in your "java -jar" command

11:18 * llasram blinks

11:19 tvanhens: as in anything we have defined in the project.clj jvm-opts we'll need to run manually with java -jar?

11:19 gfredericks: yeah; and it reduces your ability to depend on other lein features, like aliases

11:20 tvanhens: what about command line arguments, is there a way to pass those in?

11:21 hyPiRion: tvanhens: `java [ options ] -jar file.jar [ arguments ]`

11:21 gfredericks: yeah, java -jar supports that

11:22 while you're at it, you can also avoid AOT via `java [ options ] -cp file.jar clojure.main -m my.main.namespace [ arguments ]`

11:22 tvanhens: gfredericks whats the upside of that?

11:23 technomancy: it's easy to mess up AOT

11:23 hyPiRion: avoiding AOT bugs

11:24 technomancy: however, avoiding AOT also adds to your startup time

11:25 gfredericks: leiningen does not have a changelog?

11:25 technomancy: gfredericks: it's pronounced NEWS.md

11:25 kzar: Trying to get started with stasis. I'm doing (stasis.core/slurp-resources "resources/public/" #".*") at the repl to see how things work. It's returning an empty array-map though despite there being a file in resources/public/index.html

11:25 hyPiRion: when it comes to AOT, you're sort of between Scylla and Charybdis.

11:25 gfredericks: technomancy: oh that is an interesting pronunciation; thamks

11:26 tvanhens: Thanks guys that was a ton of help :) Are there any resources that are good for reading up about AOT and uberjars in general?

11:26 technomancy: AOT is fine as long as it never happens in a development context

11:26 so if you have a build server, you should be safe

11:26 kzar: (I'm trying to migrate my site from jekyll to something clojurey, don't have to use stasis)

11:26 gfredericks: oh hey I am mentioned in the news

11:26 hyPiRion: gfredericks: in the changelog*

11:26 technomancy: gfredericks: front page

11:26 extra, extra, read all about it

11:26 hyPiRion: we just spell it funny

11:27 gfredericks: our CI started failing when it silently switched to using 2.4.0 and I'm trying to figure out why

11:27 hyPiRion: Oh, that's a lot of new names on the list

11:30 bacon1989: Does anyone know where I could find an example of clojure running in an android project?

11:30 technomancy: hyPiRion: that's the best part of the new release =D

11:30 arrdem: hyPiRion: 30+ https://groups.google.com/forum/#!topic/clojure-dev/l1hF94fFNN4

11:30 bacon1989: I can't seem to get it working without getting null pointer exceptions

11:31 * arrdem had the wrong list

11:31 bacon1989: here's an example of what i'm trying to do http://pastebin.com/4zsXjmw5

11:31 Frozenlock: bacon1989: Would the clojuredroid tutorial be enough, or do you want a production application?

11:32 bacon1989: Frozenlock: I want to include the runtime in an existing android application, I can't seem to find documentation on that

11:32 hyPiRion: arrdem: I was thinking about Leiningen, in the changelog

11:32 Although that is really neat too

11:32 bacon1989: there doens't appear to be an example of it anywhere

11:33 Frozenlock: bacon1989: https://groups.google.com/forum/#!forum/clojure-android (That's the limit of my knowledge) :-p

11:34 bacon1989: Frozenlock: that's helpful, thank you

11:34 I'm really trying to figure out if my problem is with dalvik, or if it's with my function calls in the example I gave you

11:34 Frozenlock: (slurp "some-url") gives me a connection error. Is there a way to specify which interface should be used?

11:34 bacon1989: I kind of followed this article http://stackoverflow.com/questions/2181774/calling-clojure-from-java

11:35 Frozenlock: Network interface

11:35 clgv: was there leiningen 2.4.0 annoucement on the ML? seems I missed that

11:38 justin_smith: Frozenlock: you may want to check out java.net.URL and its api

11:39 Frozenlock: justin_smith: Will do, thanks

11:39 justin_smith: for example it has a version of the openConnection() method that takes a proxy argument

11:39 ~javadoc java.net.URL

11:39 clojurebot: I don't understand.

11:39 justin_smith: (wondering if that works ... nope)

11:39 Frozenlock: I reading now http://docs.oracle.com/javase/7/docs/api/java/net/URL.html

11:40 *I'm

11:40 That's weird.. I was expecting the OS to chose the interface with the web access for this :-/

11:40 choose

11:40 * Frozenlock needs another coffee

11:41 justin_smith: what did your arg to slurp look like? I assume it include protocol etc.?

11:42 Frozenlock: (slurp "http://google.ca") => java.io.IOException: Server returned HTTP response code: 504 for URL: http://google.ca

11:43 bacon1989: I guess my basic question is, how do I read data into the clojure runtime?

11:43 justin_smith: bacon1989: what kind of data? for clojure edn literals, clojure.edn/read

11:43 gtrak: bacon1989: what kind of data?

11:43 justin_smith: lol

11:44 bacon1989: sorry, i'll be more detailed

11:44 systemfault: Frozenlock: 504??! o_O

11:44 gtrak: big data? little data? orange data?

11:44 nixn: it's always hot data

11:44 canweriotnow: philandstuff: that’s a good idea… I’ll have to take a look. thanks

11:44 justin_smith: gtrak: dada data

11:44 cbp: ~big data

11:45 clojurebot: I don't understand.

11:45 justin_smith: ~bigdata

11:45 clojurebot: Excuse me?

11:45 cbp: dammit clojurebot get with the times

11:45 gtrak: nice cooled glass of data.

11:45 justin_smith: :P

11:45 ~cloud

11:45 clojurebot: excusez-moi

11:45 justin_smith: ~botsmack

11:45 clojurebot: clojurebot evades successfully!

11:45 Frozenlock: systemfault: I know... not everyday you see a 504 :-p

11:46 systemfault: Frozenlock: From Google, indeed.

11:46 bacon1989: I'm in java, and I want to load a string into the clojure runtime, and then call it. There appears to be a function clojure.lang.RT.loadResourceScript(filepath), but I want to just load a 'string' into the clojure runtime

11:46 gtrak: bacon1989: eval+read-string

11:47 bacon1989: my code looks like this http://pastebin.com/TheJsqCE

11:47 gtrak: i'm not making a repl just yet

11:47 gfredericks: so I'm using leiningen 2.3.4

11:48 which depends on pomegranate 0.2.0

11:48 yet it downloads pomegranate 0.3.0

11:48 (and presumably uses that)

11:48 gtrak: bacon1989: well, what do you mean call it? sounds like that's what you want from the pastebin

11:48 gfredericks: how can I figure out why? If a plugin depends on 0.3.0, can that override leiningen's own dependency?

11:48 bacon1989: gtrak: on line 23, that line needs to be loaded into the runtime

11:49 there's a function for loading a 'file', but no function for loading a 'string' that i'm aware of

11:49 stuartsierra: bacon1989: You would need Clojure.var("clojure.core", "read-string") and Clojure.var("clojure.core", "eval")

11:49 bacon1989: any ideas?

11:49 stuartsierra: ahh ok

11:50 stuartsierra: bacon1989: But it looks like you're working on Android, and I doubt that Clojure's `eval` will work at all on Android.

11:51 bacon1989: stuartsierra: are you sure? i've heard of people being pretty successful getting a clojure-repl working

11:51 stuartsierra: Although, now that I think of it, someone demonstrated a Clojure REPL on Android, but it was very slow.

11:51 bacon1989: ya

11:51 i saw that

11:51 i'm ok with slow startup times

11:51 gtrak: bacon1989: there's no faster path to load code than eval.

11:52 aside from AOT

11:52 gfredericks: technomancy: if I add a {:mirrors {"central" {...}}} to my user profile, should I expect pomegranate to blow up with the error msg "Multiple mirrors configured to match repository"?

11:53 technomancy: gfredericks: hrm; I've never used mirrors, but I think the answer is no

11:53 gfredericks: is this new in 2.4.0?

11:53 gfredericks: kthx; staring at the pomegranate source now

11:53 technomancy: well I think it applies to uses of pomegranate 0.3.0, which is supposedly new in 2.4.0

11:53 I'm getting 0.3.0 using leiningen 2.3.4 but haven't figured out why yet

11:54 this pomegranate code might be buggy

11:59 technomancy: easiest way for me to run leiningen with an alternate version of pomegranate? is there a checkouts for the plugin classpath?

12:00 mdeboard: ,(group-by :id [{:id 1 :name "foo" :banana "potato"} {:id 2 :name "foo" :banana "fistula"}])

12:00 clojurebot: {1 [{:name "foo", :id 1, :banana "potato"}], 2 [{:name "foo", :id 2, :banana "fistula"}]}

12:00 mdeboard: Right, so is there a group-by that will group by compound keys

12:00 gfredericks: like two keys at once?

12:00 mdeboard: ,(group-by [:id :banana] [{:id 1 :name "foo" :banana "potato"} {:id 2 :name "foo" :banana "fistula"}])

12:00 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Key must be integer>

12:00 mdeboard: right

12:00 gfredericks: mdeboard: use juxt

12:00 sdegutis: How do you all usually compile your web app and upload it?

12:01 mdeboard: I wrote one last night but I assume there's an easier way

12:01 sdegutis: I have an alias called "compile-all" that runs "cljsbuild once", "garden once", "ring uberjar", and then I push the resulting .jar file up to the server.

12:01 bacon1989: alright, so this is what i've got so far, I seem to be getting closer. Error on line 25 http://pastebin.com/MYjs5gFF

12:02 java.lang.UnsupportedOperationException

12:02 any ideas?

12:02 sdegutis: But it seems like this isn't what Leiningen :aliases were meant for... is there some other more canonical way?

12:02 nullptr`: TIL about garden

12:02 (inc sdegutis)

12:02 sdegutis: aww the one time, and lazybot isnt here :(

12:02 hyPiRion: Raynes: ^

12:02 you had one job.

12:02 sdegutis: it's okay, let's just remember that I have 1

12:03 bacon1989: is it possible I need to generate the string in clojure using 'def'?

12:03 * clgv remembers ambrosebs wanting a clojure update to 1.5.1 on lazybot ;)

12:03 clgv: might have been famous last words? :P

12:04 ambrosebs: clgv: made my own fork, works great.

12:05 clgv: ambrosebs: did lazybot get jealous of your fork and just quit? :P

12:05 ambrosebs: I miss lazybot too :(

12:05 justin_smith: bacon1989: the string does not need to be bound to a var, getting it read and evaled will suffice

12:06 bacon1989: clojure uses java datatypes

12:06 devn: what do people use for automatically rerunning specific clojure.test tests?

12:06 justin_smith: ,(class "hello")

12:06 clojurebot: java.lang.String

12:06 devn: (aka a watcher so I can edit a test, save, and have it rerun)

12:06 bacon1989: justin_smith: but in my example, it's throwing an error

12:06 devn: like midje's `lein midje :autotest`

12:07 mdeboard: gfredericks: Here's how I wrote it (though I have that inner anon func broken out into a separate one) https://gist.github.com/mattdeboard/9e60a7dd4d101fa368dc

12:07 how would that be different with juxt

12:07 technomancy: devn: after-save-hooks

12:07 justin_smith: bacon1989: you are calling foo with one string

12:07 you should be calling it with two strings

12:08 because it takes two string args

12:08 (line 37)

12:08 bacon1989: justin_smith: ah yes, I changed it

12:08 it's failing before that though

12:09 i can't get the eval.invoke(... to work correctly

12:09 it expects a 'form'

12:09 justin_smith: bacon1989: the string you pass to read_string has two forms

12:10 bacon1989: the error is along the lines of java.lang.UnsupportedOperationException: can't load this type of class file, compiling:(NO_SOURCE_PATH:0:0)

12:10 justin_smith: ,(read-string "(ns user) (defn foo)")

12:10 clojurebot: (ns user)

12:10 justin_smith: notice it only gets the first form

12:11 you need to split that into one string per form

12:11 bacon1989: ok, i'll give it a shot

12:11 justin_smith: (this is probably not addressing your problem at hand, it is another error in your code)

12:13 another nitpick - that map.invoke should not actually do anything, because you are not using the return value and map is lazy

12:15 bacon1989: justin_smith: they're tests, but yeah

12:16 i read something stating that what I want to do is impossible with dalvik

12:16 justin_smith: OK

12:16 maybe try this with the jvm first

12:16 for sanity's sake?

12:16 then if you have a working java version, then see how dalvik handles it?

12:20 Glenjamin: to people tend to use tools.trace, or is there a better way of introspecting 3rd-party code when debugging?

12:27 arrdem: if you're feeling brave you could try single stepping with eclj...

12:27 but tracer or tools.trace seems to be the current goto

12:28 Glenjamin: cheers, is there any tooling for jumping to source quickly as well?

12:28 bbloom: arrdem: there's no way to single-step with eclj :-(

12:28 arrdem: bbloom: T_T

12:28 Glenjamin: i tried lein ubersource, but it appears that LT doesnt index target/ - will probably have to poke around the settings

12:28 bbloom: arrdem: eventually the meta-circular interpreter will be able to do that

12:28 arrdem: by treating "eval" as an effect you can intercept

12:29 arrdem: bbloom: hum... really I just want to see a single cycle interpreter built using TANAL's ASTs.

12:30 'cause then we can build a real GDB like debugger.

12:32 bbloom: arrdem: if you want to attach to & debug running jvm programs, you need a very different approach than eclj or whatever you could do with an analyzer's ast

12:32 you need to have origin information on the bytecode

12:32 Glenjamin: arrdem: when you said tracer, were you referring to clojure.contrib, or something else?

12:32 bbloom: arrdem: similar to source maps for js

12:33 arrdem: debugging with an interpreter is a very different approach

12:33 arrdem: bbloom: for debugging JVM interop sure.

12:33 s/JVM/$HOST/g

12:35 visof: hello

12:36 AWizzArd: Hi visof.

12:37 mdeboard: hi

12:37 visof

12:37 we have awaited your return, as the prophecy foretold

12:37 arrdem: heh

12:38 alejandro: hey there, does anyone have a good way of setting environment variables via clojure?

12:39 visof: if i have a string with this format "<x> <y> \"Hello\"\n<xx> <yy> \"hello\nworld.\"\n<a> <b> <z>\n" , how can i get triples [["<x>" "<y>" \"Hello\"], ["<xx>" "<yy>" \"hello\nworld.\"], ["<a>" "<b>" "<z>"]] ?

12:40 technomancy: alejandro: you can't set env vars on the jvm

12:40 visof: even if the string big but in this format

12:40 justin_smith: alejandro: there are hacks, via interop, but it simply isn't an operation that is portable to all jvm hosing operating systems

12:40 gtrak: alejandro: what do you mean setting? for processes that are started via the JVM?

12:40 justin_smith: alejandro: this is why people use System/setProperty and System/getProperty

12:41 alejandro: gtrak: just for the clojure process itself. it's really for unit testing more than anything else

12:41 justin_smith: this is withing your own process that is, you can trivially set env for a child though

12:41 gfredericks: mdeboard: you would just say (group-by (apply juxt ks) m)

12:41 alejandro: justin_smith: cool, I'll look at those and see if I can use them for what I need

12:41 justin_smith: then use System properties instead of environment

12:41 gfredericks: mdeboard: or in your earlier example, (group-by (juxt :id :banana) [...])

12:41 gtrak: alejandro: use environ to grab system properties conveniently.

12:41 mdeboard: gfredericks: Well cool

12:41 gfredericks: mdeboard: note that group-by takes an arbitrary function, not a key

12:43 Glenjamin: visof: a couple of clojure.string/split calls should do it

12:43 visof: Glenjamin: there is a newlines inside strings

12:43 \"hello\nworld.\"

12:44 bacon1989: I wonder if I can grab the clojure file generated from lein-droid, and use it normally like clojure.jar for the JVM

12:44 mdeboard: gfredericks: Although that doesn't quite fit my use case w/o writing more code, but that is useful info

12:44 alejandro: gtrak: justin_smith: so is it better to do config options via system properties for JVM apps?

12:44 e.g. port settings or database urls?

12:45 justin_smith: alejandro: if you want to change them from within the same process, yes

12:45 Glenjamin: visof: i see, you probably want to take a CSV parsing library and tell it that spaces are commas

12:45 gfredericks: mdeboard: it does what you were asking about though, right?

12:45 mdeboard: Though that's really close. I essentially want an inverted index for a collection of hash maps, and your example gets that.

12:46 Glenjamin: alejandro: you can read environment variables for those cases, why do you need to set them?

12:46 justin_smith: alejandro: though a common idiom for that stuff is to use a "config map" in clojure, which is a map (or atom around a map) in a var that is accessed by or passed to various code

12:46 mdeboard: There's just a couple more transformations I'd need to apply (e.g. (for [[k v] ...] (set k) (vals v)))

12:46 Glenjamin: PORT=1234 lein run

12:46 etc

12:46 justin_smith: Glenjamin: he mentioned testing

12:46 alejandro: Glenjamin: yeah, mostly just to be able to test those settings

12:47 Glenjamin: ah, so you can always alter-var-root #'environ/env

12:47 justin_smith: alejandro: another thing is if you make an abstraction around the config grabber, you can make it return an arbitrary value for tests

12:47 gfredericks: mdeboard: prismatic/plumbing has some useful map creation fns

12:47 Glenjamin: or as justin_smith said, wrap access to env via a var you're happy to modify - or pass the env into you app, and pass it differently for tests

12:48 stuartsierra: k

12:48 hyPiRion: Glenjamin: You mean with-redefs I presume?

12:48 alter-var-root changes it permanently.

12:48 Glenjamin: depends on scope i guess, i have an alter-var-root at the top of my scratch repl for when i forget to set up env vars

12:48 mdeboard: gfredericks: I think for now I'm ok with my group-by-many, does what I need and is concise-enough for me to not be ashamed of it haha https://gist.github.com/mattdeboard/9e60a7dd4d101fa368dc

12:48 hyPiRion: Glenjamin: right, I was thinking about for tests

12:49 Glenjamin: depends if its tests in a subset of repl, or tests in their own process i suppose

12:49 but yeah, with-redefs makes more sense

12:50 deathknight: Similar to Nelson Morris, are there any other programmers publicly looking to periodically pair with others? (src: http://nelsonmorris.net/2014/04/07/saturday-remote-pairing.html)

12:51 arrdem: deathknight: 404'd

12:51 justin_smith: deathknight: some local clojerks pdx folks have been doing something similar I think

12:51 bacon1989: one thing I really can't figure out, why don't people include a binary of their work?

12:51 I found this: https://github.com/clojure-android/clojure

12:51 justin_smith: arrdem: in erc I had to take off the ) manually

12:51 bacon1989: which should work with dalvik, but there's no included .jar file?

12:51 deathknight: :)

12:51 arrdem: justin_smith: herp a derp. good catch.

12:51 bacon1989: is there some sortof benefit to compiling something like this

12:52 gfredericks: mdeboard: oh yeah, your function is different in a couple ways

12:52 bacon1989: it's going to be a running in a runtime that isn't going to change

12:52 justin_smith: bacon1989: mvn -q package inside that repo should do the trick

12:52 I think

12:52 gfredericks: mdeboard: if you care about perf you probably want to change that to an (into {} ...)

12:52 instead of merge

12:53 mdeboard: gfredericks: Why's that?

12:53 idk the perf profile of assorted techniques

12:53 arrdem: mdeboard: into leverages transients where merge doesn't.

12:53 justin_smith: mdeboard: into uses transients, merge does not

12:53 mdeboard: Does it have something to do with transients?

12:53 arrdem: lololol

12:53 Glenjamin: i think its transients

12:53 justin_smith: and as we all know, hobos work hard

12:54 mdeboard: I asked last night about transients, not clear what that means exactly

12:54 arrdem: ༼ つ ◕_◕ ༽つ GIVE TRANSIENTS ༼ つ ◕_◕ ༽つ

12:54 mdeboard: It was like `set` vs. `set!`

12:54 arrdem: /s

12:54 mdeboard: transients are explicitly single threaded mutable datastructures that can be finalized to normal immutable collections

12:55 hyPiRion: Transients are the best

12:55 mdeboard: arrdem: "Finalized"?

12:55 justin_smith: mdeboard: transients are for usage in place in a local context where there can be no threading issues, and they are modified instead of copied

12:55 mdeboard: I'm reading clojure.org/transients atm

12:55 Ah I see

12:55 justin_smith: ok, that will explain it better than we do

12:55 hyPiRion: mdeboard: any "update" operation on a transient invalidates the transient and returns a new one.

12:56 well, it should, at least.

12:56 arrdem: hyPiRion: whaaa I thought the whole point was update in place, which defeats that.

12:56 s/defeats/conflicts with/g

12:56 mdeboard: So, it's killing transients

12:56 bacon1989: brb

12:56 gfredericks: hyPiRion: that sounds pretty wrong

12:57 justin_smith: arrdem: technically transients are "allowed" to update in place

12:57 gfredericks: almost all updates on a transient return the same object

12:57 just not guaranteed to

12:57 justin_smith: but they are not bound to

12:57 you must use the return value of all transient ops

12:57 arrdem: hum...

12:57 hyPiRion: gfredericks: I don't mean the implementation detail, rather

12:57 arrdem: this seems like a poor choice of update semantics..

12:57 gfredericks: clojurebot: transients update operations |return| the same object except in this one case

12:57 clojurebot: c'est bon!

12:58 arrdem: that doesn't even work... you can't express the "invalidation" of an object on the JVM. I can still totally hold a pointer to the "old" value and you can't force me to give it up

12:59 you can write your API such that the old value is subsequently useless/self-banning... but why...

12:59 it's not like you can (memset &obj 0)

13:00 hyPiRion: arrdem: Sure, you cannot express the invalidation on the JVM, but it's there semantically (not technically, because you can usually bash in place)

13:01 * arrdem thinks this is silly and goes back to Compiler.java

13:01 hyPiRion: the general idea is that any update operation on a transient "invalidates" it and that the return value must be used in its place if you want to continue to do update it

13:02 mdeboard: I changed (apply merge to (into {}

13:02 No transients were killed

13:02 arrdem: I guess the point of this is that it forces the update semantics of transients to mesh with those of normal datastructures so you don't have silly people like me trying to abuse in-place update behavior to build fully mutable datastructures and to in-place updates on them.

13:03 your code has to be functional in structure, it just _happens_ that the implementation details provide update in place.

13:03 hyPiRion: right

13:03 mdeboard: so I assume into is a macro that calls persistent!

13:03 justin_smith: arrdem: more likely, its the fact that persistant needs to be a single bit flip operation

13:03 gfredericks: they don't all the time though; people come in with bugs because they bash transients

13:03 mdeboard: ,(docs into)

13:03 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: docs in this context, compiling:(NO_SOURCE_PATH:0:0)>

13:03 mdeboard: whatever idiot

13:03 hyPiRion: gfredericks: yeah

13:03 arrdem: justin_smith: well there's that too.

13:03 justin_smith: arrdem: and because of this you have to keep the persistent semantics, including the ability to return a new object sometimes

13:03 gfredericks: ,(let [t (transient {})] (dotimes [n 40] (conj! t n n)) (persistent! t))

13:04 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/conj!>

13:04 gfredericks: ,(let [t (transient {})] (dotimes [n 40] (assoc! t n n)) (persistent! t))

13:04 clojurebot: {0 0, 1 1, 2 2, 3 3, 4 4, ...}

13:04 * gfredericks shakes fist at clojurebot

13:04 mdeboard: lol

13:04 hyPiRion: gfredericks: return its length

13:04 gfredericks: ,(let [t (transient {})] (dotimes [n 40] (assoc! t n n)) (keys (persistent! t)))

13:04 clojurebot: (0 1 2 3 4 ...)

13:04 mdeboard: all this sturm und drang for a Ticket To Ride simulator

13:04 justin_smith: or reduce + on it

13:04 gfredericks: ,(let [t (transient {})] (dotimes [n 40] (assoc! t n n)) (reduce +(keys (persistent! t))))

13:04 clojurebot: 28

13:05 gfredericks: the lesson is that some of the keys turned negative

13:05 arrdem: wat

13:05 cbp: does leiningen let you inject code in files?

13:05 justin_smith: lol

13:06 cbp that sounds like a terrible idea

13:06 but I am sure you could do it with some system calls in an :injection key in proejct.clj

13:06 but don't please?

13:06 cbp: justin_smith: i know but.. clojurescript

13:06 mdeboard: ¸ . ø ¤ º ° º ¤ ø . ¸ justclojurethings ø ¤ º ° º ¤ ø . ¸

13:06 justin_smith: maybe what you really want is a preprocessor plugin, and to use its output?

13:07 technomancy: cbp: not into files, but into any given eval-in-project call

13:07 arrdem: justin_smith: :injections come on get it right /s

13:07 cbp: okies

13:07 eraserhd: What is the recommended way to make a custom exception? :gen-class or proxy?

13:08 technomancy: custom exceptions are =(

13:08 eraserhd: I'm going to suspect :gen-class, but that's kind of icky.

13:08 technomancy: definitely icky

13:08 use ex-info instead

13:08 eraserhd: Aha.

13:08 That sounds like what I'm trying to do anyway.

13:09 justin_smith: arrdem: sorry, an :injections key just parsed wrong mentally, but you're right

13:09 eraserhd: probably ex-info, or maybe reify

13:09 gfredericks: how can I debug where the deps on my leiningen vm are coming from?

13:09 like `lein deps :tree` for plugins&stuff

13:10 justin_smith: gfredericks: there is a mvn command for plugin dep tree

13:10 dunno about lein though

13:10 technomancy: gfredericks: right now you have to just move :plugins to :dependencies

13:11 root: hi, how do i perm change value in list ?

13:11 justin_smith: technomancy: that's too bad

13:11 root: make a different list, or use a java.util.ArrayList and maybe you shouldn't be using clojure

13:11 eraserhd: technomancy, justin_smith: Exactly what I'm looking for, thanks.

13:11 technomancy: justin_smith: nah, it's a golden opportunity for a new contributor to step up

13:12 gfredericks: technomancy: kthx

13:12 justin_smith: heh

13:12 umpa: justin_smith good point

13:15 if I name new list by same name as old one, what happens to the old list ?

13:15 justin_smith: umpa: if it is not bound in some other scope, it can be garbage collected

13:16 * clgv assumes both lists have a party together :D

13:17 justin_smith: umpa: if you have some ns level var that needs to be updated, it should be wrapped in an atom or ref, rather than just calling def again

13:17 umpa: how ?

13:17 justin_smith: ,(def l (atom ()))

13:17 clojurebot: #'sandbox/l

13:17 alndvsza: Can anyone help me with a problem I am having with Korma?

13:17 clgv: thats the right moment to suggest one of the books or online tutorials ;)

13:17 cbp: ~anyone

13:17 clojurebot: anyone is anybody

13:17 justin_smith: ,(swap! l conj 1)

13:17 clojurebot: (1)

13:17 cbp: ~botsmack

13:17 clojurebot: clojurebot evades successfully!

13:18 clgv: ~anybody

13:18 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

13:18 justin_smith: clgv: good point about the books / tutorials

13:18 clgv: cbp: listen to the bot ;)

13:18 alndvsza: lol

13:19 i create a new app with using luminus, when i try do a select on a mysql table called user, i get the following error: check the manual that corresponds to your MySQL server version for the right syntax to use near '.* FROM "users" WHERE ("users"."id" = 1) LIMIT 1

13:19 its like the SELECt is being left off the front?

13:20 justin_smith: alndvsza: can you make a paste of the relevant part of your code?

13:22 umpa: (def 1 (atom ())) did not work for some reason

13:22 (def 1 (atom ()))

13:23 AWizzArd: umpa: that would be in Java something like: 1 = new java.util.HashMap();

13:23 alndvsza: justin_smith: https://gist.github.com/anonymous/f9a12fb49bd8585c4738

13:23 AWizzArd: umpa: you can’t change the value of 1.

13:23 clgv: umpa: there are pretty good introductory books and online resources about clojure that would save you a lot of pain (judging from that question)

13:23 justin_smith: AWizzArd: more like ArrayList :)

13:23 alndvsza: its the defualt code from the luminus template

13:23 justin_smith: sorry, I picked a bad name for it when I used l in my example, my bad

13:24 but still l != 1

13:25 clgv: justin_smith: that's a fun choice for a variable name in a written exam choosing the "appropriate" font. you only need to use it in some numerical comparisons :D

13:25 justin_smith: heh

13:26 alndvsza: (sql-only (select users (limit 1))) returns "SELECT \"users\".* FROM \"users\" LIMIT 1", wtf

13:26 justin_smith: weird

13:28 alndvsza: if i run that line without sql-only i get the error.... use near '.* FROM "users" LIMIT 1' at line 1

13:28 *hits head on table*

13:29 umpa: how do I update value in a hash-map ?

13:29 justin_smith: umpa: I think you should find a good tutorial on immutability and data structures in clojure

13:30 umpa: justin_smith I tried going clojure Koans but still have trouble grassping some of the concepts

13:31 justin_smith: clojure can be great, but it requires a different approach to programming, where instead of mutating some variable, you pass values to functions that return another value as a result

13:31 cbp: umpa: maybe try this http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome

13:31 johnwalker: send-off uses a fixed-size threadpool

13:31 how are the actions being sent to the threadpool allocated?

13:32 justin_smith: cbp: nice link, bookmarking for future reference, thanks

13:32 johnwalker: is it first come first serve?

13:33 for example, if i have multiple agents

13:33 alndvsza: anyone using Clojure with mysql that can give me an alternative to korma?

13:33 mdeboard: alndvsza: jdbc direct?

13:33 johnwalker: actually nevermind, i get how it works

13:33 justin_smith: alndvsza: if you have some sql knowledge, clojure.java.jdbc is fine

13:33 johnwalker: there's one global threadpool but each agent has its own queue

13:33 justin_smith: johnwalker: exactly

13:33 johnwalker: that makes sense, sorry. rubber-ducking

13:33 alndvsza: ah, alright

13:34 johnwalker: thanks justin_smith

13:34 thats a pretty solid way to do it

13:34 hyPiRion: alndvsza: I like yesql, you could check that out

13:34 alndvsza: i will indeed

13:34 justin_smith: johnwalker: http://clojuredocs.org/clojure_core/clojure.core/agent the docs here are for an old version but not out of date

13:35 also you can get a lot from the links here, if you haven't seen it http://clojure.org/cheatsheet

13:37 johnwalker: ahh, i did see those

13:37 clojuredocs is the w3schools of clojure these days

13:37 canweriotnow: lol

13:37 justin_smith: now now, it's not that bad

13:38 umpa: nice thanks for the links guys

13:38 johnwalker: it's not that bad, but there are a striking similarities

13:39 alndvsza: hah, this is quite a novel approach, SQL in sql files!

13:39 johnwalker: clojuredocs is the first hit on google and whenever i click it by accident i bounce

13:39 justin_smith: johnwalker: there is always clojure.repl/source

13:40 johnwalker: why don't i use that more often

13:40 that told me accidentally what i needed to know lol

13:40 er

13:40 exactly*

13:41 i wish that worked with java classes too

13:41 technomancy: or M-. if you're in cider

13:41 justin_smith: you hotshots and your unstable almost-working editor integrated tooling

13:41 johnwalker: M-. throws an error ._.

13:42 wrong type argument sequencep

13:42 technomancy: well, assuming a stable version of cider =(

13:42 johnwalker: oh, it DOES work

13:42 it jumps to source

13:42 justin_smith: johnwalker: all the problems that are not caused by having too old a version of cider, are caused by having too new a version of cider

13:42 ther is no stable version

13:42 johnwalker: it just throws an error if there isn't a string at point

13:43 gtrak: johnwalker: M-. will work with java in recent ciders, but you need the source artifacts in your dependencies.

13:43 technomancy: justin_smith: 0.5.0 has treated me well

13:44 sdegutis: does anyone else pronounce "fn" as "effin"?

13:44 technomancy: which is coincidentally the version on marmalade

13:44 sdegutis: or is it just no one?

13:44 gtrak: sdegutis: yes

13:44 defn and fn rhyme

13:44 justin_smith: technomancy: cool, I will maybe check it out sometime - I am subscribed to their github issues and have a timer set to check out the latest stable whenever the "everything broke" messages stop coming

13:44 johnwalker: gtrak: i will have to look into that because that sounds extremely good

13:45 gtrak: johnwalker: it's quite magic

13:45 we'll have a stable release soon!

13:45 justin_smith: gtrak: and I know you've been pushing for that, and I am grateful

13:45 gtrak: on the order of weeks.

13:45 technomancy: justin_smith: it's really unfortunate that the docs recommend melpa =(

13:45 cbp: :-(

13:45 gtrak: justin_smith: yea, gotta break a few eggs.

13:46 cbp: bbastov has a thing for melpa. His prelude thing defaults to it

13:46 technomancy: cbp: he also has a pretty severe disregard for stability

13:46 the two seem to go hand-in-hand

13:46 arrdem: technomancy: "pretty severe" would seem to be an understatement.

13:47 technomancy: arrdem: I keep telling myself "at least there is a maintainer now"

13:47 gtrak: yea.. he assumes everyone using cider is like him.

13:47 riding git emacs and melpa for everything :-)

13:48 and caring about emacs

13:48 johnwalker: to be fair, bbatsov is a boss

13:48 gtrak: I've found him very pleasant, actually, I just have to keep on top of stability or there would be even less than there is.

13:49 hiredman: in what sense?

13:49 gtrak: like, they added an ASM dep which broke cider-nrepl a while back, for the java navigation.

13:49 since large java projects contain something that contains ASM

13:50 now it uses the java compiler API anyway.

13:52 gfredericks: any luck on tools.nrepl since we last talked?

13:52 I'll probably hit it this week.

13:52 nullptr: t

13:52 gfredericks: gtrak: nopes

13:56 lemonodor: technomancy: the new version of lein looks great. i was excited to try “lein release” but i’ve tried it on 2 different packages of mine, on os x and linux, with a clean ~/.lein/profiles.clj, and in each case it dies with a StackOverflowError: https://www.refheap.com/86444

13:56 any idea what i might be doing wrong?

13:58 technomancy: lemonodor: yeah, this is a bug that only manifests from the uberjar of the 2.4.0 release: https://github.com/technomancy/leiningen/issues/1554

13:58 will push out a 2.4.1 release soon; in the mean time you can run from a checkout of lein

13:59 gfredericks: having some trouble haxing lein

13:59 I wanted to change the pomegranate dependency and run lein that way

13:59 lemonodor: technomancy: perfect, thanks

13:59 gfredericks: so I'm using the /bin/lein in the leiningen project to launch it

13:59 but am not seeing the changed dep

13:59 also if I tweak the version string in /project.clj, `lein --version` doesn't change

14:02 technomancy: gfredericks: try running `lein install` from the leiningen-core dir

14:03 gfredericks: ROGER

14:06 I think I have offended leiningen

14:07 arrdem: the gods frown

14:07 mdeboard: heyyyyyyyyyy satan!

14:07 (south park)

14:07 ,(south park)

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

14:07 gfredericks: you know what I bet I can accomplish this by just sneaking an alternate jar of the same version of pomegranate into ~/.m2

14:08 what could possibly go wrong

14:08 technomancy: checksums

14:09 arrdem: (inc technomancy)

14:09 gfredericks: urm

14:09 lazybot: ⇒ 112

14:09 gfredericks: will they necessarily go wrong?

14:09 arrdem: good lord

14:09 gfredericks: I just need some way to debug my damn build tool

14:09 arrdem: Raynes: did you patch karma to be shared?

14:09 $karma arrdem]

14:09 lazybot: arrdem] has karma 0.

14:09 mdeboard: $karma arrdem

14:09 lazybot: arrdem has karma 29.

14:09 arrdem: that would be a yes

14:09 mdeboard: $karma mdeboard

14:09 lazybot: mdeboard has karma 6.

14:09 mdeboard: :(

14:09 Raynes: arrdem: That's not a bug, it's a feature.

14:10 Karma was always meant to be per-channel.

14:10 arrdem: Raynes: I didn't say it was a bug, it was just unexpected behavior.

14:10 Raynes: We're talking about shared karma between channels?

14:10 cbp: $karma cbp

14:10 lazybot: cbp has karma 8.

14:10 arrdem: oh. herp derp. I'm thinking I'm in -offtopic

14:10 * arrdem can't read his modeline

14:10 cbp: take that mdeboard !!!

14:10 gfredericks: arrdem: quick quick say something about clojure

14:10 mdeboard: (dec cbp)

14:10 lazybot: ⇒ 7

14:10 mdeboard: (dec cbp)

14:10 lazybot: ⇒ 6

14:11 mdeboard: $karma cbp

14:11 lazybot: cbp has karma 6.

14:11 arrdem: gfredericks: nope sorry I _am_ offtopic

14:11 cbp: wat

14:11 mdeboard: (+ 2 cbp)

14:11 (inc cbp)

14:11 lazybot: ⇒ 7

14:11 cbp: who will stand for this injustice!

14:11 mdeboard: (inc cbp)

14:11 lazybot: Do I smell abuse? Wait a while before modifying that person's karma again.

14:11 mdeboard: lol, sorry.

14:13 (inc cbp)

14:13 lazybot: Do I smell abuse? Wait a while before modifying that person's karma again.

14:13 mdeboard: fine.

14:13 Raynes: Lazybot don't mess around

14:13 * Raynes nods vigorously

14:14 arrdem: strictest lazy bot ever

14:14 gfredericks: does leiningen not get its own dependencies from ~/.m2?

14:15 technomancy: gfredericks: bootstrapping lein is tricky. it has to cache its classpath in order to be self-hosting.

14:15 see the .lein-classpath file in the checkout

14:15 gfredericks: I'm using a regular install now

14:15 does it use an uberjar?

14:15 technomancy: yeah

14:15 gfredericks: consarnit

14:15 there goes that tactic

14:16 is there a way I can sneak a user.clj onto the classpath?

14:16 technomancy: you need a checkout for that

14:16 the uberjar is on the bootclasspath

14:17 for speeeeeeed reasons

14:17 gfredericks: wait can't I add to the classpath by messing with my lein script?

14:18 technomancy: you can, but the bootclasspath always wins over regular classpaths

14:18 gfredericks: does leiningen supply a user.clj though?

14:18 can't I still sneak in a monkeypatch before leiningen's clojure code actually runs?

14:20 haha it worked

14:20 arrdem: (inc crowbars)

14:20 lazybot: ⇒ 1

14:20 gfredericks: no monkeys are safe from my patches now

14:21 problem solved

14:21 technomancy: thanks

14:21 (inc technomancy)

14:21 lazybot: ⇒ 113

14:22 dgleeson: hello all. I'm wrote a middleware that does authorization. It requires that my war be installed in the main application, because it handles putting a Shiro subject on the session. This is causing a bunch of my unit tests to fail. I've been trying to figure out a way to only load that middleware when I'm in the tests that test it, and disable the middleware when I'm not testing the middleware. If I just try to define the (handler/app routes) again compoj

14:35 devn: ,(* 3. 2.)

14:35 clojurebot: 6.0

14:35 devn: wat

14:37 johnwalker: dev you reminded me of cedric greevey's trick

14:37 ,(def .3 0.4)

14:37 clojurebot: #'sandbox/.3

14:37 johnwalker: ,(+ .3 0.4)

14:37 clojurebot: 0.8

14:38 gfredericks: leiningen in duplicating the mirrors list before passing it to pomegranate

14:40 justin_smith: dgleeson: make a middleware wrapper that passes the handler unchanged under one env, and does the proper action in the other

14:40 dgleeson: then of course give it its own independent unit test (middleware are just data transforms, so this is trivial)

14:41 (fn [handler] (fn [request] (if should-wrap? (f (handler request)) (handler request))))

14:44 dgleeson: justin_smith: I'll give it a go. Thanks!!

14:46 gfredericks: woooh it is meta-merge

14:46 there's a lein that merges the project map with a modified version of itself

14:47 justin_smith: itself meaning lein?

14:47 (if only)

14:47 gfredericks: lein does (meta-merge project (assoc project ...))

14:47 this should be okay for mirrors because it's a map

14:47 and (merge m m) should give you m

14:47 but somebody has transformed the map into a seq of kvpairs

14:47 so it turns into duplicates that offends pomegranate

14:47 so my question is

14:48 which is the real problem? leiningen merging a project with itself, or the mirrors entry getting de-mapped?

14:49 justin_smith: it sounds to me like the mirrors entry being de-mapped is a bug

14:50 gfredericks: it seems weird to me to expect that merging a project with itself will never cause problems

14:51 unless projects are assumed to belong to a semilattice amirite distributed systems hipsters haha wooo

14:52 maybe I'll try to figure out which one of these actually changed in the new release

14:53 the self-merge: https://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/project.clj#L631-633

14:54 looks like the self-merge is new in 2.4.0

14:55 and I bet the same effect could be gotten by merging with a single-entry-map instead of associng onto the project and merging that back into the project

15:01 justin_smith: gfredericks: sounds like you have enough info to write a failing unit test that demonstrates the issue

15:02 amalloy: gfredericks: mirrors gets turned into a seq of kv pairs for the same reason that dependencies and repos do: so that you can specify precedence

15:02 the canonical format is a seq of pairs; that project.clj accepts a map is just for user convenience in the most ocmmon case where you don't care about order

15:02 gfredericks: amalloy: good to know

15:02 amalloy: or, anyway, i know that's true of deps and repos, and assume from your conversation that it applies to mirrors to

15:02 o

15:03 gfredericks: my guess is that this self merge is not necessary

15:03 technomancy: gfredericks: oh man, that is weird

15:04 gfredericks: technomancy: https://github.com/technomancy/leiningen/commit/f5305ab47b0953969b2b6a6822888e25fa8517c9

15:05 technomancy: we need to meta-merge because :repositories or :plugin-repositories could have :replace or :displace

15:05 but we don't want to do it to the whole map

15:05 gfredericks: right

15:05 so the second arg to meta-marge could be a singleton map?

15:05 via select-keys I guess?

15:06 technomancy: (update-in project [:repositories] meta-merge (:plugin-repositories project)) would be my instinct

15:06 gfredericks: technomancy: what's the best angle for regression-testing this?

15:07 maybe a high-level "I can run something on a project with a mirror"?

15:07 amalloy: technomancy: i think (meta-merge project {:repositories (:plugin-repositories project)}) is probably slightly better?

15:07 i guess it's about the same, never mind

15:09 gfredericks: technomancy: any chance this would fit with the 2.4.1 you mentioned earlier?

15:09 technomancy: gfredericks: definitely going into 2.4.1

15:09 thanks for catching this

15:09 gfredericks: w0000h

15:09 bbloom: i'm having a hard time loading a google closure lib w/ cljs... i've followed dnolen_'s instructions here: http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html but the library does not seem to get included in the output

15:10 technomancy: :mirrors would make a good regression test as would attempting to use a plugin that's in :plugin-repositories and not in ~/.m2

15:10 dnolen_: bbloom: got a gist of your ns form?

15:11 amalloy: technomancy: interestingly, because of the bizarre way that some-fn handles multiple arguments, https://github.com/technomancy/leiningen/blob/d8634b22/leiningen-core/src/leiningen/core/project.clj#L120 is equivalent to ((some-fn nil? displace? replace?) left right)

15:11 bbloom: dnolen_: it's this library: https://raw.githubusercontent.com/google/tracing-framework/master/shims/wtf-trace-closure.js and i'm simply doing (:require [WTF])

15:11 cbp: ,(a/b/c)

15:11 clojurebot: #<CompilerException java.lang.RuntimeException: No such namespace: a, compiling:(NO_SOURCE_PATH:0:0)>

15:11 technomancy: metamerge! http://www.deviantart.com/art/MEGAMERGE-Celled-199279278

15:11 bbloom: dnolen_: manually invokign js-dependencies shows it finds the file

15:12 aaahhh 404 in the network tab

15:12 it's not copying it to the output, it's trying to use it from the resources directory

15:13 spei: Does anyone know if reducers/fold can parallelize over reducers/take?

15:14 dnolen_: bbloom: (:require ...) likely won't work w/o deps.js

15:14 technomancy: gfredericks: can you test master?

15:14 gfredericks: ummm

15:14 let's see :)

15:14 bbloom: dnolen_: my browser is loading deps.js

15:14 stuartsierra: spei: reducer parallelism depends on the *source*, not what operations you do.

15:14 dnolen_: bbloom: the dep.js for wtf-trace-closure.js?

15:14 each library needs to provide it

15:15 bbloom: even so, I'm not sure how good this stuff is since it's not something I've ever used

15:15 it may need more work

15:16 bbloom: dnolen_: does the filename need to match the provide statement?

15:16 ie do i need to rename to WTF.js ?

15:16 dnolen_: bbloom: you may - that might have been part of cemerick's patch

15:17 bbloom: dnolen_: this is pretty hairy

15:17 dnolen_: speaking of which it might be worth relaxing it if the library location can be determined from deps.js

15:17 cemerick: deps.js is only used for the goog stdlib stuff

15:17 dnolen_: bbloom: well you have two resolutions mechanisms - google's laissez faire deps.js and the classpath

15:18 bbloom: dnolen_: ideally, i'd just like to stick a .js file in a particular place and have require just work

15:18 is there a reason that can't happen?

15:18 cemerick: bbloom: yes, the name in :require has to match the goog.provide in the file, and the classpath location of the file

15:18 spei: here is an example where using reducers/take slows down a computation https://gist.github.com/ship561/8c8b1fa60a4937bbce8a

15:18 dnolen_: bbloom: not really interested in allowing people put stuff in random locations

15:19 bbloom: open to novel ideas on how to resolve libraries with non classpath layouts

15:19 well google closure libraries

15:19 not ClojureScript ones

15:20 bbloom: dnolen_: the way i hoped it worked (maybe it does work this way? kinda) is that i'd specify a search path of closure lib roots

15:20 gfredericks: technomancy: looks goooood

15:20 dnolen_: bbloom: its needs to work for libs in JARs too

15:20 amalloy: have you tried looking at the source of r/take, spei?

15:20 bbloom: dnolen_: sure, that's jsut a search path with a ".jar:" in the filename :-)

15:21 dnolen_: bbloom: not really excited about that

15:21 bbloom: anyways this is a project

15:21 technomancy: gfredericks: thanks

15:21 bbloom: dnolen_: sure. don't care about solving the general problem right now... want to solve my particular issue

15:22 dnolen_: bbloom: if you just want to solve your problem ... layout wtf into classpath conventions

15:22 bbloom: dnolen_: but i also need to serve the file so the browser can get it outside of advanced builds

15:22 stuartsierra: spei: Not sure, but `reducers/take` uses an Atom to keep track of how many values have been consumed, which may slow down the overall process.

15:22 bbloom: i have a /public/js directory, i guess ineed to add that to the class path?

15:22 dnolen_: bbloom: however that won't work if the lib does the multiple provide thing which is sadly allowed by Closure

15:22 bbloom: dnolen_: it provides many things, bbut they are all within 'WTF'

15:23 dnolen_: bbloom: why wouldn't you just have it be a part of your build?

15:23 it's a 3rd party lib

15:23 spei: amalloy: I have tried looking at the source. I'm not that great with clojure but as far as I can tell, reducers/take returns a reducible which should allow r/fold to work in parallel

15:23 dnolen_: pack into a JAR where the files respect classpath conventions

15:23 done

15:23 bbloom: dnolen_: what does "part of your build" mean?

15:23 dnolen_: bbloom: produce a JAR of the lib

15:23 bbloom: dnolen_: i can't get it to work without that added complexity... one step at a time

15:23 the compiler can find it if i put it in /resources/WTF.js

15:23 spei: though this example is simple, once I use r/take, r/fold only uses 1 thread

15:24 dnolen_: bbloom: anything else is going to be more complicated

15:24 bbloom: but the browser can't b/c i'm serving static js from /public/js/

15:24 dnolen_: bbloom: I'm telling you the simplest thing

15:24 make it a part of your build

15:24 bbloom: dnolen_: how will that file get served to the browser then?

15:24 amalloy: spei: reducibles and foldables are separate things, and fold is a stronger requirement

15:25 dnolen_: bbloom: like all your other CLJS files

15:25 bbloom: dnolen_: i'm serving them w/ a wrap-file handler from target/public

15:25 amalloy: in particular, most foldables must know exactly how large they are in order to divide and conquer efficiently. how can (take 5000 xs) be split up? how many items does it have?

15:25 bbloom: dnolen_: i don't want to serve all java resourdces

15:25 spei: oh. perhaps that is where I misunderstood on reducers work.

15:26 dnolen_: bbloom: if the 3rd party lib is a part of your build everything magically works

15:26 gfredericks: technomancy: here's the other half of our issue: https://github.com/groupon/DotCi/issues/14

15:26 stuartsierra: amalloy: (Thanks for taking on that answer.)

15:26 dnolen_: there is not difference between JS libs and CLJS libs

15:26 bbloom: dnolen_: i don't understand what it means to be "part of my build"

15:26 dnolen_: bbloom: if you include core.async as a dep, it's a part of your build

15:26 spei: well, I assumed that (take 5000 xs) would return a reducible of 5000 items

15:26 amalloy: but it doesn't! what if xs only has 10 elements?

15:26 dnolen_: bbloom: core.async is a JAR that includes CLJS sources that respect classpath conventions

15:26 bbloom: just do the same for this closure lib

15:27 bbloom: dnolen_: where do i put .js files in such a case?

15:27 in the src dir?

15:27 spei: i see. thanks

15:27 dnolen_: except it's just JS source that respect classpath conventions

15:27 bbloom: oh yeah you can do that too

15:27 amalloy: and anyway, even if it did have over 5000 elements, it's not really feasible to communicate back to the foldable source which parts of itself to fold

15:27 dnolen_: bbloom: just put the wtf source in your project in the write folders

15:27 s/write/right

15:27 amalloy: you're welcome, stuartsierra. i'm a little fuzzier on this stuff than i was when i was submitting reducer patches, but i still remember enough to be useful

15:28 stuartsierra: amalloy: Not as fuzzy as I am, clearly. The distinction between foldable and reducible is one I missed.

15:29 bbloom: dnolen_: that doesn't seem to work. it's searching for src/WTF.js which doesn't make any sense

15:29 dnolen_: js files seem to be treated very differently than cljs files

15:29 technomancy: gfredericks: have you tried checking bin/lein into your project?

15:30 gfredericks: um

15:30 hm

15:30 dnolen_: bbloom: it should work, I've tested it a bit with my own stuff

15:30 bbloom: I do note that wtf.js declares a single segment namespace

15:30 gfredericks: technomancy: that would require the CI server have something in the project on its PATH, no? which would be weird?

15:30 bbloom: dnolen_: is that an issue?

15:30 dnolen_: which has seen very little love in the CLJS compiler

15:30 bbloom: unknown, I never do it

15:30 bbloom: ugh.

15:30 dnolen_: and most other people don't either

15:31 bbloom: well WTF.js is by a team at google... sooo

15:31 gfredericks: technomancy: unless you think it's likely it has <project>/bin on the path

15:31 technomancy: gfredericks: not assuming you control the command to initiate the ci run

15:32 gfredericks: oh hey

15:32 dnolen_: bbloom: I don't have time to poke around at it today, but I can take a look on Friday

15:32 hyPiRion: gfredericks: hey I did some tricks to get hello swearjure working

15:32 gfredericks: technomancy: actually I think this is failing before it ever gets to my code; the CI server runs `lein pprint` for funsies

15:32 hyPiRion: legit tricks or cheating tricks?

15:32 bbloom: dnolen_: i'm going to try to get it working locally, but i would prefer to produce a cljs-wtf library that i can just add as a :dependency and :require

15:32 hyPiRion: gfredericks: legit -- https://github.com/hyPiRion/hello-swearjure/blob/master/.travis.yml

15:33 I'm just dling lein, build and run it from a specific checkout

15:33 gfredericks: oh I thought you were talking about bootstrapping swearjure or something

15:33 dnolen_: bbloom: sure, one fix at time though, and there are several here

15:33 gfredericks: yeah I do control the part that runs my build, but like I said this fails pre-build on `lein pprint`

15:33 hyPiRion: hrm, alright

15:34 I just entered in the middle of the conversation

15:36 technomancy: gfredericks: checking in rebar is pretty common in the erlang world

15:36 I can't see any downsides to doing the same for lein

15:37 but I haven't tried it

15:37 except for lein, which obviously has bin/lein checked in =)

15:39 stuartsierra: I used to check in bin/lein around the time of the 1.x => 2.x transition.

15:39 Specifically for CI builds, as I recall.

15:40 technomancy: stuartsierra: any gotchas?

15:41 stuartsierra: technomancy: Worked fine, as far as I remember.

15:41 I still do the same thing when I'm distributing materials for training courses. Only downside is the difficulty of running Lein without fast/reliable Internet access, e.g. at a hotel.

15:42 bbloom: dnolen_: what causes entries to be added to deps.js ?

15:42 dnolen_: bbloom: it needs to be constructed beforehand

15:43 bbloom: google closure and third party jars ship with it

15:43 gfredericks: stuartsierra: you mean just the first time?

15:44 stuartsierra: gfredericks: Even after. I've had problems even if I specify a :local-repo and pre-cache everything.

15:44 gfredericks: hmmm

15:45 stuartsierra: Especially with artifacts that aren't in a public repo, like Datomic Pro.

15:45 gfredericks: are there tests in leiningen that actually launch another jvm?

15:45 stuartsierra: Even if they're cached, Leiningen tries to download them again.

15:46 technomancy: gfredericks: tons

15:47 gfredericks: I must find myself one of these tests and paste its code

15:47 wait I meant launch another leiningen jvm

15:47 i.e., run the script

15:47 I'm worried that the only way to test this is by actually adding things to the classpath

15:47 which is rather side-effecty=

15:49 technomancy: gfredericks: no tests for bin/lein iirc unfortunately

15:50 gfredericks: technomancy: is this testable otherwise? the bug is in load-plugins, which...probably loads plugins.

15:50 I guess I can with-redefs something somewhere probably

15:52 sdegutis: My website is 54 MB big :)

15:52 Perhaps this is not ridiculous. Although it does at first glance appear so.

15:52 bbloom: dnolen_: this is the issue: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/closure.clj#L711

15:52 dnolen_: that's getting a relative path between an input file and an output file

15:53 mercwithamouth: what do you all think of fireplace compared to cider?

15:54 angusiguess: I'm using fireplace + dispatch and am diggin' it.

15:54 bbloom: dnolen_: in my case, that's adding a whole bunch of extra ../../ to the path

15:54 angusiguess: Still not using it the same way I'd use a repl but it works pretty well.

15:58 mercwithamouth: angusiguess: hmm i may give it a look see. i'm fairly comfortable with emacs/cider as well but i've used vim for years. i am at a point where i'm very productive in emacs though

15:59 mordocai: Hey, is there an easy way to get the source of an anonymous function for debugging/output purposes? Like, (def x [#(+ %1 %2)]) then (print-source (first x)) and get "(fn [x y] (+ %1 %2))" essentially? I know the repl function source exists, but it only seems to work on named functions that originate from a .clj.

15:59 amalloy: mordocai: no

16:00 functions don't have source code attached

16:00 mordocai: amalloy: That's what I thought, but wanted to double check. Thanks!

16:03 bbloom: dnolen_: i just monkey-patched cljs using with-redefs to rewrite the path to be correct & unblock me. if you're up for it, i'll help come by and help you fix this up on friday. thanks for the help

16:10 bacon1989: hello guys, I really want to get clojure working within an existing android project. The plan is to query a server for updates, and download scripts. These scripts would then be loaded into the clojure runtime. I started by building a dalvik version of the clojure runtime from here https://github.com/clojure-android/clojure, and tried a few methods to try and load a file from external storage, which can be seen here:

16:10 http://pastebin.com/xLVV0p7v

16:11 the file 'main.clj' includes nothing else but this: (defn foo [a] (str "Hello " a "!"))

16:11 I feel like i've exhausted my efforts, and i'm doing something clearly wrong

16:13 The error i'm getting is when I call load-string on the slurped file, it gives me a java.lang.NullPointerException, compiling:(null:1:1)

16:15 sveri: hi, Lets say I want to construct a map and the map should contain a certain key / value pair only if the value is not nil, what is the idiomatic way to do this? this is what comes to my mind: http://pastebin.com/n3gEvLE9

16:16 amalloy: sveri: (merge m (when v {k v}))

16:16 dnolen_: bbloom: sure!

16:19 johnwalker: when does send-off occur within a swap! ?

16:19 is it after swap! finishes like in dosync?

16:19 sveri: amalloy: thats shorter and looks nice, thank you

16:19 stuartsierra: johnwalker: Whenever you call it. Atoms don't coordinate with Agents like Refs do.

16:20 johnwalker: darn

16:20 stuartsierra: sveri: (if v (assoc m k v) m)

16:20 gfredericks: johnwalker: and the swap function can be retried too, so it really shouldn't have any side effects, including send-off

16:21 johnwalker: gfredericks: yeah, that was exactly my concern

16:21 well, found a use for refs. thanks gfredericks, stuartsierra

16:22 gfredericks: johnwalker: do you know about watcher fns?

16:23 johnwalker: i do. they're executed after a successful swap, right?

16:24 it would make sense here, but it feels weird using them

16:24 you see old state and new state, but not the difference between them

16:25 i realize you can encode part of the difference within the state, but it doesn't feel right

16:26 rurumate: how to refer to the ns declared above my code? *ns* seems to refer to clojure.core at runtime

16:26 fifosine: I'm having trouble following the Om tutorial that swannodette wrote. Does anyone know of any other good Om tuts out there?

16:27 gfredericks: technomancy: any estimates when 2.4.1 appeareth?

16:30 johnwalker: fifosine: this doesn't have a tutorial, but if you raise an issue here then emallson will probably point you to the slides

16:30 https://github.com/emallson/comment-example

16:31 angusiguess: mercwithamouth: let me know how it goes!

16:37 johnwalker: oh i know

16:37 ahh shit nevermind, that's a stupid idea

16:43 Shayanjm: Does anyone else here using light table IDE?

16:58 technomancy: gfredericks: 1-3 days I think

16:59 tvanhens: how do you include resources in an uberjar?

16:59 johnwalker: how can you find out the arguments passed to an agent that caused it to fail?

17:00 gfredericks: technomancy: roger, thanks

17:08 devn: technomancy: https://github.com/ato/clojars-web/pull/214

17:08 PR out! :)

17:09 tvanhens: Do resource relative paths change in an uberjar?

17:10 akhudek: devn: that looks nice

17:11 Bronsa: (inc devn)

17:11 lazybot: ⇒ 18

17:12 kzar: Is there a simple way to tell if a file is binary / ascii in Clojure?

17:13 devn: akhudek: thanks dude. we think so too. the comps are a bit better, so there are more tweaks coming, but this is a good start.

17:15 dbasch: kzar: the naive way would be to see if all the bytes are 127 or less, but there are java tools to guess file types without looking at all the content

17:16 kzar: dbasch: Oh I just tried slurping a binary file and it worked OK

17:17 :) Clojure is nice

17:19 hiredman: uh

17:21 gfredericks: for binary files you probably want to deal with bytes (like a byte array) instead of characters (like a string); slurp only does the latter

17:22 kzar: For my purposes it's fine, I'm just looking for ascii files starting with a specific string to process in a special way

17:22 I thought I'd have to rule out binary files myself but as they're passed as a string .startsWith works fine

17:25 tvanhens: does slurp use the classpath when resolving file locations?

17:30 cbp: tvanhens: no

17:30 tvanhens: Whats the best way of reliably refering to a file so it doesn't change in or out of an uberjar

17:30 I seem to be able to only get it to work one way or another

17:31 kzar: tvanhens: I think clojure.java.io/resource

17:31 hiredman: clojure.java.io/resource

17:31 cbp: put it inside resources and use io/resource

17:32 tvanhens: gotcha its inside resources but I wasn't using io/resource lemme give that a go

17:32 thank you

17:37 kzar: Trying to get a list of all the files in a directory and sub-directories thereof. I'm getting an error about there not being a matching File ctor. (file-seq (java.io.File. (clojure.java.io/resource "public/")))

17:39 johnwalker: try

17:39 (clojure.java.io/file "public")

17:39 hiredman: kzar: resource does not return something you are allowed to make a file out of

17:39 johnwalker: (-> "public/" clojure.java.io/file file-seq)

17:40 hiredman: resource reads things via a classloader, which basically presents a simple key/value read only api

17:40 not like files at all, no way to do any kind of listing

17:40 johnwalker: and public should be in the same directory as your src directory

17:40 i'm pretty sure file-seq is just (seq (.listFiles file))

17:41 but i haven't looked at the source

17:41 hiredman: no

17:41 ,(doc file-seq)

17:41 clojurebot: "([dir]); A tree seq on java.io.Files"

17:41 hiredman: it is recursive

17:41 johnwalker: ahh gotcha

17:42 kzar: So public contains my html etc for my website, I'm porting my site from static site generator jekyll. I've put public in resources/public. Don't mind not using clojure.java.io/resource but was trying to do things in an idiomatic way I guess

17:42 johnwalker: try "resources/public/" as your directory, then

17:42 hiredman: kzar: something that is a resource is read via a classloader, that means that content could be basically anywhere, not just files on disk

17:43 kzar: In my shoes would you put that stuff in resources/public?

17:43 hiredman: kzar: definitely

17:44 kzar: phew ok

17:44 hiredman: kzar: but I know how resources work, and would not try to make one a file, or listing it like a directory

17:45 kzar: Well does it really matter if I just do as johnwalker suggested? I don't think my site will ever be an uberjar

17:45 hiredman: resouces are a thing, you give it a name, you get inputstream over the bytes from that name or nil

17:45 I dunno, why are you listing the contents of public anyway?

17:46 johnwalker: i'm not sure i would put the stuff in resources/public

17:46 kzar: hiredman: So with Jekyll any file that starts with "---\n" some YAML and then "\n---\n" is formatted based on the YAML

17:46 so that YAML sets the template being used, the file format like markdown etc

17:47 if there isn't that YAML "front matter" at the start the file is copied straight over into the output directory

17:47 if there is the file is processed and the output written to the output directory

17:47 So I am attempting to map over all the files, if .startsWith "---" then process, otherwise copy etc

17:48 hiredman: I think you are confusing things

17:48 johnwalker: wouldn't it make more sense to pass this directory as an argument to your program?

17:48 hiredman: you have a program to do static site generation, and some data that it operates on, but those are distinct things

17:49 so when you run the program, you give it arguments like --in somedir and --out someotherdir

17:50 so that data is definitely not part of the program and even if you did uberjar the program, it doesn't go in the jar

17:50 bbloom: heh, i suspected this *might* be the case, but it seems like cljs' immutable maps are dramatically faster than objects for use as dictionaries for even a few dozen keys

17:51 kzar: so long story short you'd put public outside of the resources directory

17:51 ?

17:51 (What you said made sense)

17:51 hiredman: sure

17:52 wolfcore: kzar: wouldn't it be easier to use grep + pipes to move the non-YAML files and then work on the rest?

17:53 kzar: hiredman: Would you put your config files in the resources directory? (setting stuff like api keys)

18:06 amalloy: kzar: i don't think you can safely slurp a binary file. if it contains byte sequences that are not legal utf-8, i think you get an exception

18:06 kzar: crap OK

18:08 wolfcore: kzar: not sure if I understand what you are trying to do, but

18:08 kzar: find . -type f -exec awk 'FNR==1 && /^---$/ {print FILENAME}; FNR>1 {nextfile}' {} + | xargs -I{} mv {} dest

18:09 kzar: that would move all files that have the first line with "---\n" to dest/

18:09 amalloy: well, maybe not? i expected ##(String. (byte-array (map unchecked-byte [0xc3 0x28])) "UTF-8") to break, but it doesn't look like it just puts in a replacement character

18:09 lazybot: ⇒ "�("

18:11 johnwalker: yeah thats right

18:11 expect to be confused as hell when you call slurp on a file with a bom

18:18 deathknight: no tests for bin/laden

18:24 johnwalker: if you do (locking <atom here> )

18:24 do swap!s and reset!s have to wait?

18:24 on that atom's lock to finish?

18:28 xaloysius: hi

18:28 johnwalker: do swap!s and reset!s outside locking have to wait? *

18:28 bbloom: johnwalker: don't lock an atom

18:29 johnwalker: in fact, you should never use locking at all, if you can help it

18:29 amalloy: johnwalker: you seem to be doing a lot of complicated concurrency stuff. perhaps if you posted a more general question ("how do i do X, it seems like using a future and atom and agent can't be right"), you could get an answer that doesn't need this crazy stuff

18:29 bbloom: johnwalker: and by "if you can help it" i mean "you almost certainly really do not need to use locking ever"

18:30 xaloysius: first time on IRC not sure this is where a question like this is appropriate but basically I am putting together a REST API that will be doing basic CRUD operations. i want to use a nested JSON format so that OOP clients can easily use de/serialization with my API. Is there a good library to transform flat relational data (a map) into nested json if I provide it with mappings?

18:30 johnwalker: darn, seemed like an easy solution

18:30 this problem isn't too hard, but i'm still having trouble with it

18:31 justin_smith: johnwalker: using atoms correctly as intended is easier than using locking correctly

18:31 cbp: johnwalker: what are you trying to do?

18:31 johnwalker: i'm trying to track the state of concurrent file uploads

18:32 so the way i've modeled this problem is that at any point you have a set of files that are being sent to some server

18:32 so what i wanted to do was store a hashmap from files to futures within an atom

18:33 justin_smith: so you use swap! to insert a new entry when an upload starts, and check the future to see if the upload is done?

18:33 johnwalker: checking whether a file has finished uploading or is still in the works would just be (realized? (@file-map file))

18:33 thats right

18:33 justin_smith: right

18:34 if that's all you need, that's easy with an atom

18:34 dbasch: xaloysius: check out cheshire

18:34 johnwalker: well, the problem is - how do you handle timeouts?

18:34 justin_smith: johnwalker: well, if you do a retry, cancel the old future, and swap! in a new one

18:35 johnwalker: for a simple cancel, cancel the future, and (swap! files dissoc file)

18:35 if the future is where the timeout happens, even easier, no need to do the canceling logic elsewhere

18:36 amalloy: justin_smith: "cancel the future and swap in a new one" is not easy to do thread safely, by the way

18:36 justin_smith: oh, ok

18:37 amalloy: is it not a question of waiting for future-cancel to return? where is the trick?

18:37 amalloy: i mean, it's not impossible, and with a ref instead it's fairly easy (your dosync dissocs the future, then returns it); but with an atom, how do you cancel the future and remove it, all in one operation, given that it may be retried?

18:38 johnwalker: with an atom, i think it's still possible so long as you do future-cancel outside of the swap

18:38 amalloy: you don't want to cancel the same future many times, or cancel a future that some other thread just put in there, if they beat you to the punch of retrying

18:38 johnwalker: but it's fragile

18:38 possible for me*

18:39 mileage may vary ._.

18:39 xaloysius: dbasch: would i use the factory functionality in cheshire?

18:39 johnwalker: so this is actually a good place to use refs?

18:40 i've stayed away since stuart halloway implied that you have a bad design if you're using them

18:40 amalloy: most of the time that i actually use refs, it's for this reason: i'd like to swap! an atom, but return something other than its new value

18:41 you can fake that up with an atom, but refs are more convenient for it. i'm not actually using any of the nice STM features

18:41 dbasch: xaloysius: you’d probably use generate-string, do you have an example of what your nested map looks like?

18:42 johnwalker: calls inside dosync need to be pure too

18:42 can future-cancel really fit somewhere here?

18:43 amalloy: johnwalker: the layout i was suggesting was (future-cancel (dosync (let [f (get @m k)] (alter m dissoc k) f)))

18:43 dbasch: amalloy: do you know anyone who’s actually using STM for all its power and glory? I’m curious because I don’t know any projects that do

18:44 amalloy: i've never heard of a compelling use

18:44 johnwalker: wow, that's pretty slick

18:45 dbasch: it would be useful in scenarios like financial order settlement in high volume exchanges, but I doubt anyone is doing that in Clojure

18:45 johnwalker: i don't see any problems

18:45 thanks amalloy, justin_smith

18:45 justin_smith: and thanks amalloy

18:45 (inc amalloy)

18:45 lazybot: ⇒ 121

18:46 johnwalker: (inc amalloy)

18:46 lazybot: ⇒ 122

18:46 johnwalker: (inc justin_smith)

18:46 lazybot: ⇒ 46

18:46 dbasch: if I were to build a bitcoin exchange in Clojure, I’d consider using STM

18:46 amalloy: it's raining karma!

18:46 dbasch: i dunno, anything large-scale enough to benefit from STM can usually benefit more from a transactional database anyway

18:47 justin_smith: dbasch: use something less reliable, like php, then you can steal btc and blame it on hackers or gremlins

18:47 xaloysius: dbasch: {"subscription_canceled":0,"primary_email":"test1@test.com","payment_cycle_end":1431550550,"payment_cycle_start":1399668950,"id":1111,"country":{"name":"United States","id":1,"code":"US","currency":1},"card":{"exp_year":2222,"exp_month":12,"type":"Visa","last_four":"1111"},"plan":{"name":"xxxxx","renewable":0,"price":0.00,"id":1}}

18:47 amalloy: gremlins are well known hackers

18:47 johnwalker: lol

18:47 dbasch: amalloy: yes, but in the case of bitcoin sometimes you don’t need a db because the blockchain is the ultimate db

18:47 that’s for external transactions

18:48 but in that case you probably wouldn’t need stm either

18:48 perhaps in something close to HFT for bitcoin?

18:48 xaloysius: dbasch: thats a basic case - it could get arbitratily deep

18:50 johnwalker: well, this makes me sad

18:51 refs make it easy to cancel these things, but you can't start them haha

18:52 you would have to start your future before the dosync, but you don't know for sure if you really need to trigger an upload beforehand

18:52 xaloysius: dbasch: thats just a mock - i may rearrange the levels/data types later. preferably a solution would be easily changeable. i hacked together a solution but it reminded me too much of a janky ORM so i ditched it and am looking for something cleaner

18:52 johnwalker: because the server might already have the file ._.

18:52 dbasch: xaloysius: use parse-string on that (properly escaped as a string) and you’ll get a nice map

18:53 xaloysius: dbasch: im fine with converting to-from clojure data and json. what i'm having issues with is the impendance mismatch which is usually solved by an ORM

18:53 johnwalker: this hurts my brain.

18:53 can i use locking with refs? haha

18:54 xaloysius: it would be nice if there was a way to bolt an ORM-like solution that consumed edn or something onto the side of this thing.

18:54 dbasch: xaloysius: but why do you care about an ORM? are you going to interact with another system that needs to parse the data into objects of a class?

18:54 xaloysius: yeah legacy java applications

18:54 otherwise id go straight edn

18:54 dbasch: xaloysius: in clojure we usually don’t bother much with ORM

18:55 justin_smith: dbasch: xaloysius: well you can use java orm from clojure

18:55 cbp: that sounds mad fun

18:55 xaloysius: justin_smith: was trying to avoid the overhead of a full ORM if possible

18:55 justin_smith: xaloysius: yeah, edn can be simple if you don't need java compate (as described above)

18:56 and from a java compate perspective, you could always implement some magic java interface for grabbing the data using clojure classes and make java happy that way

18:56 that may be easier than using the java built stuff

18:57 johnwalker: bbloom: is locking OK for refs?

18:57 i just need to ensure that the ref in question's value hasn't changed while i do something messy

18:58 dbasch: justin_smith: yeah, that seems like the best compromise

18:58 johnwalker: (locking <ref> (something_messy) (dosync <something-pure-involving-ref>))

18:58 justin_smith: johnwalker: what if you had a dedicated thread for dispatching the upload jobs, so that part of the job could be strictly single threaded

18:58 xaloysius: justin_smith: yeah thats what I was thinking. it would be nice if I could just have a simple way to go from relational -> object-ish structure but i guess thats why they say the impedance mismatch is a PITA

18:59 justin_smith: if you are only starting tasks from that one thread, you don't need a lock

18:59 and starting the tasks should not be a bottleneck on throughput at all, given the filesystem is involved here

18:59 (plus network, of course)

18:59 johnwalker: justin_smith: i was thinking about something like (async/thread (<!! ) (future ..))

19:00 justin_smith: this is the kind of thing core.async is for

19:00 jynx

19:00 johnwalker: but this doesn't really solve the problem because the issue is starting tasks and cancelling them

19:00 justin_smith: or just a SynchronizedQueue

19:00 xaloysius: perhaps clojure is the wrong tool to use here... thanks anyway

19:00 justin_smith: xaloysius: well, caribou has a map relational modeler for a subset of edn

19:01 johnwalker: well, i know i'll shoot my eye out if i do blocking io with core async

19:01 justin_smith: xaloysius: it won't make java happy though

19:01 johnwalker: *with the go blocks of core async

19:01 justin_smith: johnwalker: you would dispatch jobs from that one thread

19:01 not do any of the work in it

19:02 the idea is if that thread is the only one starting / stopping, and has an ordered queue of stop / start events, then you have no threading issues around those aspects

19:03 johnwalker: i think you're right

19:03 something like (>!! manager "hi, shut down/start thread for file x if it exists)

19:03 justin_smith: right

19:04 and make sure no actual work is done there, just dispatch

19:04 then it can't bottleneck, can't deadlock, and can't go out of sync

19:05 johnwalker: yep, this is the way to go

19:05 am i allowed to inc you again?

19:05 lol

19:05 amalloy: ~guards

19:05 clojurebot: SEIZE HIM!

19:06 johnwalker: speaking of guards, what happened to cedric greevey

19:06 justin_smith: johnwalker: glad I could help, I've just recently read Java Concurrency in Practice so all this stuff is fresh on my mind

19:06 johnwalker: i've asked this so many times. did he just get bored and start trolling some other group?

19:07 i'm going to order my copy

19:08 is that goetz's book?

19:08 oh it is

19:09 justin_smith: yeah, it is really good

19:14 tvanhens: whats the difference between the standalone and the snapshot jar created by lein uberjar?

19:15 technomancy: tvanhens: snapshot is part of the version

19:15 standalone just means uberjar

19:16 tvanhens: what do you mean by part of the version. What is the function of the snapshot jar?

19:17 technomancy: it's a jar of the snapshot version

19:18 aperiodic: tvanhens: the snapshot jar just has your project's code and resources. it needs to be created first before the uberjar can be created. the standalone one is the uberjar with all the dependencies

19:18 tvanhens: cool that makes sense. Thanks :)

19:33 johnwalker: for what it's worth, i wound up using core async and refs

19:33 lol

19:34 justin_smith: cool

19:51 andyf_: Bronsa: ping?

19:52 Bronsa: andyf_: hi

19:53 andyf_: I continue with my insolent nature of asking questions after being confused & wrong too often ... :-)

19:54 About your suggested Eastwood simplification by using :raw-forms, is there an easy way to have the fully qualified vars in the pre-macro expanded version of the expr?

19:54 Bronsa: heh, no worries, ask away

19:54 uh

19:55 andyf_: I'd like to know not only that it was defmulti, say, but that it was clojure.core/defmulti

19:55 Bronsa: right

19:57 andyf_: uhm I guess I could do it on the tools.analyzer side but that doesn't feel right to me

19:58 if you give me a minute I'll give you a way to do it in analyze-ns

19:59 andyf_: If I get back the full env from the analyzer, and I am only wanting to fully qualify the first symbol, not some nested one, would that be straightforward to resolve in the env?

19:59 catern: Oh god no the latest clojure-mode update is so uncolorful

19:59 Bronsa: andyf_: yeah that's what I'm thinking of

19:59 catern: Please help me #clojure

20:00 It's so dull

20:00 andyf_: catern: Can't roll back? Find the color settings & tweak them to your liking?

20:03 catern: I don't want to roll back but I think I must

20:03 amalloy: i don't like updating emacs packages. if it was good enough for 2010 it's good enough for me

20:04 Bronsa: andyf_: http://sprunge.us/KRYC?clj something like that should work I think

20:06 andyf_: Grazie. Will try that out

20:06 Bronsa: uhm wait you really don't need to back up the env

20:07 andyf_: unfortunately since clojure namespaces are global mutable state, if you have (ns foo) (defmacro defmacro ..) that would resolve the defmacro as foo/defmacro rather than c.c/defmacro

20:08 andyf_: but that's some perverse and horrible code anyway so I don't think we should really care

20:09 andyf_: http://sprunge.us/hUfZ this is a bit better

20:09 andyf_: But saving a copy of the env just before each (analyze form) is the way that would even handle the perverse case?

20:10 Bronsa: that's why I put it there in the first snippet

20:10 but then I remembered about ana.jvm/update-ns-map!

20:10 oh well wait nevermind.

20:11 andyf_: it's too late and I'm thinking rubbish. the first example is ok and should work fine

20:12 andyf_: I'll give it a go, and try it out on the perverse example to see what happens. Thx

20:14 Bronsa: andyf_: ok, but if it doesn't work for that, I wouldn't spend time on trying to fix it. even trying to AOT that code with che clojure compiler fails so why should we bother

20:14 andyf_: not the lack of (:refer-clojure :exclude [defmacro]) on the ns decl

20:14 note*

20:15 andyf_: Ok

20:19 The completely unexpected Clojure slogan: We can mutate _anything_.

20:19 (But usually have the good taste and sensibility not to.)

21:06 devn: xeqi: hola sir

21:15 xeqi: devn: hola

21:19 devn: xeqi: how goes?

21:20 xeqi: i dropped a reply on that PR. we can discuss on a google hangout or something if you'd like. my goal is to get this first PR pushed through so we can make future PRs related to this effort a bit lighter and more modular.

21:21 xeqi: but im a reasonable chap, so let's chat if that sounds unreasonable. :)

21:26 xeqi: devn: I get that. Personally I'm big on having master be in a deployable state, in case of emergency like XSS vuln found.

21:27 I'd love to have this on a branch that you could PR to and then just do a ff merge onto master

21:27 devn: xeqi: Agree, but IMO the pages in question are basically what they are in prod right now

21:27 Dashboard is basically the same. a couple of ul's for projects and groups

21:27 y'know?

21:28 xeqi: true

21:28 I'd push for "add new project" to be visually different so it doesn't look like its in the list of projects, but I don't know thats worth continuing to block over

21:28 esp since bendyworks sounds committed

21:29 devn: xeqi: that's an easy fix. I can hit that right now.

21:30 xeqi: then I'm happy to +1 with the future changes planned

21:30 devn: what made you guys decide to redesign clojars?

21:31 *you people

21:31 devn: xeqi: it's been something i've wanted to do for a long time but never got around to it. we also have hired design folks at bendyworks, but we haven't had a lot of recent opportunities to work /together/ on something

21:31 we also have a bunch of people hot on clojure, are pretty community-focused as a company, etc.

21:36 xeqi: devn: I've had a list of UI items I think would provide a better user experience for awhile. Is there someplace I should braindump that at?

21:37 devn: xeqi: yeah dude, we should start a google doc or maybe an issue for it that we can create issues off of? your call.

21:38 xeqi: like hiding SSH key on signup/profile behind some advanced section. (ssh keys aren't required unless you ssh deploy, which should rarely happen for new people since `lein deploy clojars` works)

21:38 devn: ah yeah i think i saw an issue related to that

21:38 "re-authenticate for key changes" or something along those lines

21:38 seems like that's ripe for it's own section

21:38 where we could protect it with a re-auth

21:40 xeqi: k, I'll think about making a google doc for now. None of them need to be gospel or anything so not worried about a formal issue

21:40 devn: thanks for doing this

21:41 its been #3 on my list of things to fix about clojars if I ever get a large amount of time for it

21:41 (the UI refresh)

21:41 devn: xeqi: im happy to just have a more polished clojars. i think it makes people feel like it's a bit more credible, and AFAIK practically everyone in the damn community uses it, so we should make it look nice

21:43 xeqi: there's a longer-term thing here which i think we might be able to tackle /at some point/, but right now i sort of need to play the middle between a designer and the style. enlive for testing and hiccup for templating make this kind of a pain for a lot of designers to work on it

21:43 mdedetrich: im just getting started with light table, does anyone know what the key is for selecting an expression

21:44 devn: xeqi: in some ways i think xpath + plain html templates might be a better way to go in order to encourage more people to hack

21:45 in the meantime im happy to play the middle, but in the long term it might get more people involved if they didn't need to learn about enlive selector state machines to fix a broken test :)

21:46 xeqi: devn: have an example project w/ xpath + html?

21:47 devn: xeqi: somewhere around here. i mean, enlive could do straight HTML as well. i think for testing the enlive stuff can stop some people pretty cold in their tracks, and by people i mean designers

21:47 laser does it, etc.

21:47 so the main thing is i guess xpath or css for the integration test side of things

21:48 xeqi: devn: ah, yeah

21:48 devn: clj-taxi (is that the right project?) does what i think more people would be familiar with on the integration side

21:48 xeqi: I think there was some discussion on a kerodon issue about having other ways to select things, but requires some redesign work

21:48 devn: makes it a bit easier to step through finding an element, etc.

21:49 xeqi: clj-webdriver's taxi api

21:49 devn: because i even had some issues setting up my REPL to test certain things

21:49 mainly due to fixtures

21:50 i think the setup docs have gotten worlds better. i remember not being able to figure out how to run the project years ago

21:50 but there are a couple of pieces missing which i haven't completely figured out

21:50 like, in the repl, the proper way to be able to run scp.clj tests while in the REPL

21:50 xeqi: heh, I think it got better, and then worse again when I did the search/download counts

21:51 devn: ah, i didn't know if that was you! here's a big question that i'd love your input on...

21:51 xeqi: let's just say, pie in the sky, we wanted to make clojuresphere + clojars

21:52 are the query times right now prohibitive for some things in the existing DB?

21:53 xeqi: I will admit to not tracking performance, everything seems fast enough

21:53 devn: im imagining github api integration to try and find the "top 10 projects hosted on github this week"

21:54 so you could query for most watched, intersected with the most watchers, or something

21:54 err most downloads*

21:54 stasiomod: that = cool idea

21:54 xeqi: (#1 of the things to fix was finding a revenue stream to be able to handle a dev+ops person for monitoring, any crashes, time to work on things)

21:55 etc

21:55 devn: oh, well shit... i think we can figure out #1.

21:56 xeqi: so back to you're pie in the sky project...

21:56 *your

21:56 devn: haha

21:57 writing checks my ass can't cash

21:57 but yes, let's continue!

21:57 xeqi: I don't see anything there that would be problematic query wise

21:58 as far as time

21:58 devn: i imagine clojuresphere as having most of what clojars.org should have. "who uses this dep? of those users, sort them by github relevance, etc"

21:58 it introduces a metric ton of github API info

21:58 but with some caching, seems pretty doable

21:58 xeqi: we actually want to remove the underlieing sqlite db and replace it with something else

21:59 devn: datomic :X

21:59 sorry, i just can't help myself

21:59 xeqi: bad license

21:59 thought it actually would be awesome

21:59 devn: what does the open source side of the datomic license look like?

21:59 i thought that was free and clear

22:00 but probably not: "MIT or BSD or GPL if you're an open source project"

22:00 xeqi: devn: you mean datomic-free that isn't open source?

22:00 devn: :X

22:00 * devn sulks

22:01 xeqi: and I don't recall the other restrictions. only memory/h2 storage? limited to 3 connections? I think

22:01 devn: well, we had to try. let the record show we want to use datomic but won't due to licensing restrictions

22:01 postgres. it works.

22:01 xeqi: that would be my vote

22:01 devn: what is doing search right now?

22:02 i think i saw clucy in there as a dep?

22:02 xeqi: lucene

22:02 yep

22:02 _ato: lucene

22:02 devn: what do y'all think of elasticsearch?

22:02 _ato: overkill :)

22:02 devn: fair enough

22:02 xeqi: I have heard lots of good things about it, but know nothing

22:02 _ato: $ du -sh index

22:02 6.5M index

22:03 devn: i used elastisch on getclojure.org

22:03 with a nice custom query parser/tokenizer/etc.

22:03 if we ever want to do advanced search it seems like it might not be a terrible idea

22:03 elastisch from the clojurewerkz folks is really nice. just sayin'

22:04 btw: hi _ato! :)

22:04 xeqi: in general we've limited adding new features to the clojars api (such as the ones in clojuresphere). I'm neither for or against bringing in more, but it would be low on my list of things to work on

22:04 *clojars api -> clojars ui

22:04 a real api would be nice though

22:05 _ato: hi :)

22:05 devn: xeqi: oh man, please put that in whatever google doc you're brain dumping into

22:05 details of what you'd expect much appreciated

22:05 xeqi: haha

22:05 devn: we have some API aficionados who i think might get a kick out of it

22:06 xeqi: mainly based off what I know people have requested and are screenscraping for

22:06 devn: yeah, one more damn good reason to have some google analytics

22:06 it'd be nice to know when we're getting scraped so we can build an API for whatever they're after

22:07 with the exception of whatever baidu is doing ;)

22:08 xeqi: $latest compojure

22:08 lazybot: [compojure "1.1.8"] -- https://clojars.org/compojure

22:08 xeqi: ^ screen scraping https://github.com/Raynes/lazybot/commit/ff013c4b177ec2e3fce43f8513b6503c8f1469f2

22:09 arrdem: it'd be nice if clojars explicitly listed the "latest" png rather than being some backdoor unlisted feature I see some cool people using and others not :P

22:09 xeqi: arrdem: true, but I have no idea where to put that

22:10 one of many UX enhancements to be done

22:10 arrdem: xeqi: even just having a link to it from the project page would be enough

22:10 devn: arrdem: what do you mean latest png?

22:11 _ato: https://clojars.org/compojure/latest-version.svg

22:11 arrdem: ^ that

22:11 devn: oh duh, i always forget about that

22:11 arrdem: right

22:11 and it isn't mentioned anywhere on clojars.org that I've ever seen

22:11 so I always forget to use it.

22:11 devn: we will take care of that :)

22:11 arrdem: <3

22:11 thanks guys, stay awesome

22:11 devn: thanks for mentioning that

22:11 in fact, if you dont mind, make an issue and assign to me if one doesnt exist

22:12 (on clojars-web)

22:12 arrdem: ^

22:13 * arrdem takes issue with clojars

22:15 devn: xeqi: comment + fix for the "Add New Project" thing pushed

22:19 _ato: Added latest-version.svg to the about page FAQ for now so there's at least some reference to it

22:19 devn: _ato: could it be added on the jar page?

22:19 "Add this code to your GitHub markdown to XYZ..."

22:20 _ato: devn: sure

22:21 if you can think of a good way to fit it in, that'd be cool with me

22:21 devn: I'm going to pass it to our designers. Mic and Kelly will probably have some thoughts on how to go about adding it.

22:22 but I'll own the issue and make sure we find a home for it

22:23 _ato: cool, thanks for you and the others hard work on this stuff :)

22:23 devn: _ato && xeqi: mic will get the typekit domain thing fixed within the next hour just FYI

22:24 _ato: yeah dude, i think im probably at least as happy as you. i've wanted to get this done for maybe 2 years and the stars aligned

22:24 *virtual high five*

22:24 _ato: :D

22:25 devn: _ato: now, you just owe me a clojure 1.6 version of your widefinder 2 solution

22:25 i always kind of find myself wondering what that same code looks like in 1.6

22:25 xeqi: haha

22:25 devn: :D

22:25 _ato: hah, oh man

22:27 devn: _ato: tall order, eh?

22:27 how long did that take you originaly, anyway? that was in? 1.1? 1.2?

22:28 _ato: I'd completely forgotten about that

22:28 1.0 I think

22:28 devn: i know you were casting to (int ...) all over the place

22:28 and i think there was some unchecked math in there

22:29 _ato: yeah... can probably remove a whole bunch of the type hinting at the very least

22:29 devn: i know it's ancient, but i remember being like: "wow, this doesn't look very much like clojure!"

22:29 but i suspect it's gotten better

22:30 to the point where it might not look like a crazy aussie martian wrote it ;)

22:30 defrecord, deftype weren't around then either

22:30 xeqi: devn: ! just saw the search page

22:32 * devn hopes that's good news

22:33 xeqi: haha, it needs some help. just a plain list atm

22:34 devn: ahhh shite.

22:34 yeah, not cool. the /projects page styles should probably be applied here as well

22:35 i think i can fix this quick, but i need to figure out how to get this looking right locally

22:36 xeqi: devn: np, there are comments for grabing an index file and stats file now

22:36 devn: i was trying to use the results of `lein test` in dev

22:36 but no dice

22:37 xeqi: happy to help since I messed this part of setup up and must not have documented it

22:37 devn: xeqi: so just to be clear, when you use the all.edn from clojars.org

22:37 you're running using `lein ring server`?

22:37 and using the test data from the README instructions?

22:41 xeqi: devn: stepped away for a moment, let me got ahead and pull a clean copy locally

22:42 devn: xeqi: i think im missing something in the directions, because i still cannot get search results

22:42 im going to blow away my data/ dir

22:43 xeqi: devn: did you have the index from ato/clojars-web#197 ?

22:43 lazybot: search lein-garden with lein-garden -- https://github.com/ato/clojars-web/issues/197 is closed

22:44 xeqi: monopolizing #clojure for the past hour

22:46 devn: xeqi: we're technically on topic :)

22:46 xeqi: where do i drop this index?

22:47 _ato: data/index/

22:48 arrdem: little late to the party but an issue is now open.

22:50 devn: thanks arrdem

22:50 xeqi: devn: clone, db migrate, copy index, copy stats, lein ring server = search locally for me

22:50 devn: xeqi: perfect. i just caught up with you.

22:50 * devn is tempted to commit a script

22:51 devn: xeqi: do you see those "/clojure-utils ..." items?

22:51 where they seem to have no group?

22:52 the href is to "clojure-utils", not sure what's up with that

22:52 xeqi: yeah

22:53 _ato: ah

22:53 that index is probably old

22:53 before stuff got fixed

22:53 xeqi: I think that was ato/clojars-web#132

22:53 lazybot: parent poms aren't parsed for search results -- https://github.com/ato/clojars-web/issues/132 is closed

22:54 devn: gotcha

22:54 xeqi: _ato: haha, just realized you cherrypicked that from me. I thought you had fixed it

22:56 sneak_peek: anyone have any experience with any of the following ORM-like libraries? Carte, Oyako, Caribou-api

22:56 _ato: yeah, it was kind of weird, it sent me a notification like you had closed the issue when it was really the cherry-picked commit doing it :)

22:56 devn: sneak_peek: a little teenie bit

22:56 sneak_peek: whatcha thinkin' about?

22:57 umpa: what do you use instead of counters in while loops ?

22:57 sneak_peek: devn: trying to overcome the relational-object impedance mismatch :/

22:58 devn: I need to take flat data and change it into a nested JSON structure. I use sqlingvo to build my sql queries just want something that will map my flat data to nested data

22:59 devn: umpa: im guessing you want `loop` + `recur`

22:59 sneak_peek: devn: could roll my own based on cristophe grand's suggestions here (https://groups.google.com/forum/#!topic/clojure/X6BVq_RRY1A) but thought I'd check on existing libraries first

22:59 xeqi: umpa: depends on the purpose of the counter. I'm more likely to use something like map-indexed

23:00 devn: ,(loop [cnt 0] (if-not (= cnt 3) (recur (inc cnt)) (println "done")))

23:00 clojurebot: done\n

23:00 devn: ,(loop [cnt 0] (if-not (= cnt 3) (do (println cnt) (recur (inc cnt))) (println "done")))

23:00 clojurebot: 0\n1\n2\ndone\n

23:01 devn: but yeah, listen to xeqi. map-indexed

23:02 ,(for [[idx x] (map-indexed vector (repeat 10 "X")) :when (< 5 idx)] x)

23:02 clojurebot: ("X" "X" "X" "X")

23:03 devn: but that makes little sense...

23:03 ,(map second (take 4 (map-indexed vector (repeat 10 "X"))))

23:03 clojurebot: ("X" "X" "X" "X")

23:03 umpa: let me try it

23:05 devn: xeqi: temporary fix pushed to style the results at least a little bit

23:05 search results*

23:05 umpa: if you post some example code that could be helpful

23:06 xeqi: technomancy: ^ I can haz redeploy?

23:06 sneak_peek: devn: any quick feedback on those libraries - even just which you like best

23:06 technomancy: xeqi: pulling the latest rev of the PR to the instance running on 8002?

23:07 devn: sneak_peek: honestly, none of the above :X

23:07 sneak_peek: devn: any suggestions

23:07 xeqi: technomancy: yes please

23:08 technomancy: sure; on it

23:08 devn: sneak_peek: idk man, i would avoid trying to do what you normally do

23:08 sneak_peek: check out honeysql

23:09 sneak_peek: or datomic.

23:09 honestly. probably check out datomic.

23:10 sneak_peek: devn: :) not sure i can sneak datomic into a polyglot shop quietly. ill hack away at this. thanks for the suggestions

23:10 technomancy: xeqi: redeployed

23:10 devn: xeqi: technomancy: _ato: I was just talking with designer folk and we're going to make our logo size smaller, but if you guys decide to deploy tonight NBD, we'll just hit it next

23:11 technomancy: one thing is that the 8002 deploy doesn't point to the full repo, so it can't parse URL etc from the pom

23:11 umpa: https://www.refheap.com/86465 here is the loop

23:11 technomancy: maybe that was being overly paranoid, but I didn't want it connected to live data

23:12 ddellacosta: sneak_peek: I've used honeysql a lot, I like it because it's a very lightweight layer on top of clojure.java.jdbc, and you can always drop down into raw SQL if you need to.

23:13 sneak_peek: ddellacosta: ill definitely give that a look - i checked out korma but felt like it tried to do too much at once

23:14 devn: ,(doseq [group (partition 3 (range 10))] (println group))

23:14 clojurebot: (0 1 2)\n(3 4 5)\n(6 7 8)\n

23:14 devn: ,umpa that code has the same result as yours

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

23:14 devn: whoops

23:14 ddellacosta: sneak_peek: I personally feel the same way about Korma; I think it's too heavy as a DSL and adds very little

23:14 sneak_peek: while introducing complexity and under-the-covers statefulness that can be hard to debug

23:14 devn: sneak_peek: im not a huge korma fan. honeysql has worked for me.

23:15 umpa: haha

23:15 ddellacosta: sneak_peek: all in all I think that one should either simply embrace SQL in Clojure-land, or move to something like datomic where the challenges are shifted elsewhere

23:15 devn: (inc ddellacosta)

23:15 lazybot: ⇒ 3

23:16 xeqi: technomancy: thanks

23:17 technomancy: xeqi: should be easy to update; just `git fetch devn; git checkout devn/reskin; lein2 uberjar; cp target/... /tmp/reskin/...` and ctrl-c+up+ret in window 0

23:17 devn: I wrote a fairly query heavy toolkit about 4 months ago in clojure and just embraced SQL. As long as you protect yourself from trying to build your own ORM, you'll be fine. Queries can be namespaced and separated from your code. Once you just give in and give up on ORMs, you find that the world is a simpler place to live in.

23:17 sneak_peek: ^

23:17 xeqi: devn: search and new project are good enough for me to +1. looking forward to seeing future changes

23:17 ddellacosta: devn: definitely

23:18 devn: xeqi: yeah, we won't be leaving those pages that way, but they're good enough for a day. you can expect a PR pretty much every day for the rest of the week

23:20 sneak_peek: devn: ddellacosta: I want to definitely get there. my first inclination was to expose an edn API which would allow me to use a very thin wrapper to create my sql calls. I am currently using sqlingvo for sql generation. supporting legacy applications (Java) is the issue

23:21 ddellacosta: sneak_peek: it's best simply to focus on your data rather than try to wrap it up; it becomes more natural as you get more comfortable with it. However, I don't have a great solution for supporting legacy apps--at least there hopefully Clojure lessens the pain through its interop features.

23:23 devn: technomancy: xeqi: I just noticed something that I need to fix

23:23 I don't believe non-canonical forks are now italicized. Can you confirm?

23:25 or is this because the full pom map is not available?

23:26 sneak_peek: ddellacosta: will probably spend the weekend experimenting with this. thanks!

23:27 ddellacosta: sneak_peek: hope it goes well! I'll add one thing about HoneySQL vs. other DSLs (including sqlingvo, it seems) which I think puts it ahead: it produces an intermediary hash-map for which is manipulable, which can be very useful. But definitely depends on your use-case.

23:27 *for SQL

23:28 sneak_peek: ddellacosta: interesting. i took a quick look - does it not have update/insert/delete support or is that because those are relatively simple operations from a data/string manipulation standpoint

23:29 ddellacosta: sneak_peek: it does actually, it's just that the docs don't reflect it: https://github.com/jkk/honeysql/pull/20

23:30 sneak_peek: ddellacosta: nice! ill definitely try it out

23:31 xeqi: devn: doesn't look italizied to me

23:31 sneak_peek: ddellacosta: might also try my hand at creating a simple data mapper that will operate on the data post-query. if i manage to make it work cleanly I'll throw it up on github. username is prachetasp

23:32 xeqi: devn: <a class="fork" ...>, so I think its a css issue

23:32 ddellacosta: sneak_peek: what do you mean, data mapper?

23:32 talios: aftermorning all

23:33 ddellacosta: sneak_peek: I would be wary of doing too much to the data past what your app/business logic dictates...just based on experience.

23:33 sneak_peek: ddellacosta: taking the flat relational data and placing into a nested form that can be exposed as json to legacy OOP applications

23:33 ddellacosta: if i can't make it lightweight then I'll abandon that route - but i need to be able to support those applications without too much overhead

23:34 talios: whats the best clojure sql generation lib out there days? sqlkorma or something more shiny? looking for good composition/reuse

23:34 ddellacosta: sneak_peek: ah. Well, I don't want to be negative and squelch exploration, you should give it a shot and see what you discover. I've had bad luck with those kinds of general approaches, but in the end I think it really depends on the use-case.

23:35 sneak_peek: but will be interested to see what you come up with!

23:36 jonasen: talios: yesql seems like an interesting approach. But it's not really a sql *generation* library

23:36 * talios looks

23:36 jonasen: https://github.com/krisajenkins/yesql

23:37 sneak_peek: what if i approached the issue from this angle. what is best way to implement a public-facing JSON API in clojure. or is it not well suited to that task

23:37 ddellacosta: jonasen: yeah, really interesting approach that. Doesn't fit with what we're doing but cool thinking outside the box

23:38 talios: jonasen - ahhh, yeh - looks nice, but not quite what I'm after.

23:38 ddellacosta: sneak_peek: Clojure is great for that! (JSON API)

23:40 sneak_peek: ddellacosta: but not if I can't get the data into a format that makes it easy for OO languages to de/serialize since the majority of clients are going to be written in them

23:40 devn: sneak_peek: sounds like already know about edn

23:41 talios: jonasen - a clojure wrapper around jooq would almost be ideal for what I'm after actually ( using jooq at the moment on this small project, which is all java, nice - apart from some of the unweildy type signatures when you deviate the norm

23:41 ddellacosta: sneak_peek: I don't see why you need to do anything other than spit out flat records such that a database would produce. How is that hard to consume?

23:42 talios: euuu - don't let the REST NAZI's here you say that!

23:42 oh wait - I'm one of them.

23:42 ddellacosta: talios: but, this has nothing to do with REST, does it?

23:42 talios: sorry, dunno if you were responding to me or not

23:42 talios: JSON API sounds very RESTy related :)

23:43 sneak_peek: ddellacosta: talios: whoops yeah forgot to mention that part

23:43 its an HTTP REST API

23:43 talios: but yes - on the basic level, serialize to JSON and let it fly. Links and other stuff can come ontop. Or you could serialize to something like HAL that includes links etc. in the payload.

23:43 really should update the clojure api for HalBuilder

23:44 also really should release a new version of HalBuilder itself.

23:44 sneak_peek: ddellacosta: so how does the flat representation translate cleanly into an everything-must-be-an-object language like Java. just have one giant flat object?

23:45 ddellacosta: sneak_peek: I don't understand, I thought we were talking about HTTP? You don't have to worry about objects if you are just talking about pushing something out to a restful API

23:45 talios: less object, more structure. a clojure map/list structure translates to JSON fine...

23:45 ddellacosta: talios: yeah, exactly

23:46 talios: which, if given a known structure, could be deserialized INTO a object/class for java clients, or a Map

23:47 sneak_peek: ddellacosta: talios: the json serialization is trivial but im thinking about ease of use for people creating clients in OO languages. I do not want to impose a burden on them to create custom deserializations

23:48 talios: they wouldn't need to - deserialize to a Map - and if they WANT to have a fixed model, they can.

23:48 ddellacosta: sneak_peek: but they will have to anyways. You can't anticipate how people will use the API. All you can do is give them a clean data structure to work with, which is infinitely preferable to some kind of object-mapping interchange thing anyways

23:48 amalloy: just output json. everyone in every language is well used to consuming json-y stuff

23:48 or edn, whatever

23:49 sneak_peek: anyone know of an API that does flat json like this?

23:49 talios: our entire system :)

23:49 my simple sample API on http://www.gotohal.net/restbucks does it to. a bit more richer JSON structure as its HAL+JSON tho

23:49 ddellacosta: sneak_peek: flickr is just records. Most APIs I've used are just records actually. For example: https://www.flickr.com/services/api/flickr.blogs.getList.html

23:50 amalloy: every api in the world? i don't understand the question. like, for example http://www.reddit.com/r/AskReddit.json

23:50 or github's api. it's all json

23:51 talios: http://www.gotohal.net/restbucks/api/orders is a sample order-list resource on my sample API

23:51 HAL+JSON adding links.

23:52 ddellacosta: amalloy: I guess sneak_peek is talking about some kind of hierarchy vs. flat representation, not so much the format. But flat doesn't make it any harder to parse the relationships as long as there are IDs involved.

23:59 sneak_peek: ddellacosta: sorry bout that - internet connection crapped out

23:59 ddellacosta: sneak_peek: no worries.

23:59 sneak_peek: ddellacosta: was something like this what you were talking about? e.g. prefixing with the entity name? {"user.name": "xxx", "account.balance": 10}

Logging service provided by n01se.net