#clojure log - Jun 09 2015

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

3:20 jonathanj: how does putting a .jar on a classpath work?

3:20 i guess if i want to address something contained in the jar i have to use syntax like: something.jar/path/to/thing?

3:21 path/to/thing doesn't get merged into the classpath as though it were just a directory, i assume

3:22 so using Joplin, i want to call joplin/migrate-db but i need to specify a path to my migrator scripts, i'm not quite sure how to construct a path that is valid when run with `lein run` and `java -jar uberjar.jar`, any ideas?

3:32 oddcully: jonathanj: according to the GH page it will pick up resources (from classpath)

3:33 jonathanj: oddcully: hrm, my migrators are in ./joplin/sql/... and joplin is in my :source-paths vec

3:34 oddcully: i don't think those are then considered resources, are they?

3:35 oddcully: you might want to check, where it ends up in your target/uberjar

3:36 i am only familiar with the java side of things here (not leiningen)

3:37 if they end up in the jar's root joplin/sql/... i would expect them to be accessible

3:41 jonathanj: so the path on disk is something like: my_project/joplin/sql/file.clj

3:41 uh

3:41 i think it's actually something like: my_project/joplin/migrators/sql/file.clj

3:41 in the uberjar they end up looking like: migrators/sql/file.clj

3:42 but if i give the path "migrators/sql" to migrate-db then it complains about not being able to find any migrators when run as an uberjar

5:34 kungi: What is the current state of the art for using component in conjunction with compojure? I would like to reach around a DB connection as parameter to my routes for example.

5:35 justin_smith: kungi: def* macros are annoying to use with component, though I guess you could put all your defroutes inside your start method

5:35 is there a non-macro version of them?

5:35 kungi: justin_smith: there is (route) for that.

5:36 justin_smith: cool, so yeah, it would make sense to use that inside your start method

5:36 and bind your routes to the returned component

5:37 kungi: justin_smith: So you advise just building a "routes component"

5:37 justin_smith: kungi: thats how I do it (though not with compojure), I also start the http server in the same component

5:37 because the http server would be a very small component otherwise, and the separation gains nothing

5:38 kungi: justin_smith: I do that as well in another project but I think that code can get out of hand pretty fast and become a bit ugly.

5:38 justin_smith: I just found this idea: https://stackoverflow.com/questions/19776462/passing-state-as-parameter-to-a-ring-handler

5:38 justin_smith: Use a middleware to inject the app state int the request

5:38 justin_smith: I make a function that takes the db connections, and other stateful resources, and returns the properly wrapped routed

5:38 *routes

5:40 kungi: that makes sense if the http server is the apex of your app I guess

5:40 kungi: justin_smith: It is in my case.

5:40 justin_smith: kungi: the second option in the top answer is pretty close to what I do

5:42 kungi: the difference is that the http server is inside a component, so that I can cycle the whole app state - that version doesn't leave a top level of the component in global state to stop / restart

5:44 with the component at the top level, I retain control of the system, with the component created inside the app definition, my only option is to redef, or hope that only shutting down the http server is sufficient and nothing else is really stateful...

5:45 kungi: justin_smith: makes sense. I will wrap my routes in a function which get's the state.

6:31 justin_smith: I have to nag you again :-)

6:31 justin_smith: I created a function app-routes which takes the db and returns a bunch of routes.

6:32 justin_smith: And I created a JettyServer component

6:32 (component/using

6:32 (map->JettyServer {:options {:port 3333}

6:32 :routes-fn #'core/app-routes})

6:32 [:db])

6:32 When using my component like this the app-routes don't get updated when I reset my application.

6:43 wombawomba: I'm having some issues defining a macro.. how do I fix this? https://gist.github.com/aeriksson/072546aafcaee64c6db6

6:44 hanzo215: Can i get help on wireless settings for my thomson router

6:44 kungi: hanzo215 I think you are in the wrong channel. THis one is about clojure and clojure development.

6:44 hanzo215: oh snap, my bad :)

6:45 kungi: wombawomba: have a look at the expansion.

6:45 wombawomba: id expands to your-ns/id

6:46 wombawomba: That is why you can't use it as a parameter

6:46 wombawomba: you might want to use a gensym. That would be id#

7:30 wombawomba: kungi: thanks!

7:38 Kneiva: (inc kungi)

7:38 lazybot: ⇒ 3

7:57 crocket: https://groups.google.com/forum/#!topic/clojure/PTy89Y0WDkk

7:58 Which project do I best contribute if-let-all to?

9:23 c-qjv0xfi: http://pastebin.com/ccmnjBhf

9:24 Is there any blaringly obvious reason this would keep throwing "Assert failed: unused keys in regular expression map

9:24 The URL I'm trying is /foo/bar/ABCD/1234/

9:26 pbx: c-qjv0xfi, what code is doing the assert?

9:27 the POST function i assume, but in any case that's where i think you'd need to look

9:48 afhammad: Is it possible to pass config data to a library via the host app project.clj?

9:54 schmir: afhammad: https://github.com/weavejester/environ may help

9:56 afhammad: schmir: thanks was just looking at that. What is the best approach to set a single config setting (i.e url) to be used by a test lib, instead of passing it into each function call

9:56 schmir: thanks was just looking at that. What is the best approach to set a single config setting (i.e url) to be used by a test lib, instead of passing it into each function call, environ seems overkill

10:27 wasamasa: hmm, are there any specific idioms on the re-* functions?

10:28 I've only seen re-seq used heavily, probably because it's the shortest one for code golfing

10:28 justin_smith: ,(apropos "^re-")

10:28 clojurebot: ()

10:29 wasamasa: lol

10:29 justin_smith: ,(apropos "^re-.*")

10:29 clojurebot: ()

10:29 justin_smith: ,(apropos #"^re-.*")

10:29 clojurebot: (clojure.core/re-find clojure.core/re-groups clojure.core/re-matcher clojure.core/re-matches clojure.core/re-pattern ...)

10:29 justin_smith: finally!

10:29 dnolen: Bronsa: hrm trying to read cljs.analyzer, it looks cljs.tools.reader dropped alias-map how are namespaced keywords supposed to get resolved?

10:29 justin_smith: wasamasa: anyway, they all do distinct things, use the one that concisely does the operation you require?

10:29 Duke-: wasamasa: Joy of Clojure recommends only using re-seq

10:30 wasamasa: Duke-: does it name any specific reason for that?

10:30 Duke-: yes, the other functions expose some mutable stuff I think

10:30 and re-seq wraps everything nicely

10:31 wasamasa: hmk

10:32 justin_smith: ,(clojure.string/join " " (map name (apropos #"^re-")))

10:32 clojurebot: "re-find re-groups re-matcher re-matches re-pattern re-seq re-quote-replacement"

10:33 Bronsa: dnolen: oh, uhm. currently there's no support for ::foo at all but I guess with alias-map we could support at least ::foo/bar

10:33 justin_smith: out of those, re-pattern, re-matcher, re-quote-replacement and re-groups are of a different category altogether

10:34 dnolen: Bronsa: yeah w/o that can't really read any of the ClojureScript .cljc files

10:34 justin_smith: which leaves re-find if you want the first match, re-matches if you want a boolean, and re-seq if you want a lazy-seq of matches

10:36 wasamasa: but isn't re-matches on the whole string and re-find only on substrings?

10:37 justin_smith: wasamasa: actuall yeah, you're right

10:37 dnolen: Bronsa: it needs more thought but I think I will add `*ns*` dyn-var just to support the bootstrapping use case. Will just be a bound to a map. Also `ns-aliases` will be present.

10:38 Bronsa: dnolen: that would be nice. if we could also have a ns-interns we could support all of the auto-qualifying features

10:40 actually we'd need ns-interns and ns-map

10:40 dnolen: could just be a set of symbols, no need for a map sym->Var like in clojure

10:41 in the meantime I'm re-adding alias-map and ::foo/bar support

10:42 dnolen: Bronsa: yeah I don't know about that set of symbol, anything that requires adding a whole bunch of runtime information is undesirable.

10:43 would have to add a bunch of runtime bookkeeping.

10:43 Bronsa: as I suggested earlier all this information is already present in the JS environment.

10:43 I think all you need is a table of namespaces identifying which paths in the global environment represent namespaces

10:44 resolve, ns-interns can all use this

10:45 Bronsa: dnolen: couldn't cljs.core/ns-map just perform the necessary reflective calls into the js env rather than using a runtime map then?

10:46 dnolen: Bronsa: you mean to add `ns-map`? `ns-map` isn't a thing right now.

10:46 reflecting on the js env isn't going to work

10:46 Bronsa: dnolen: yeah, to add it

10:46 dnolen: you'd have to walk a bunch of things that don't matter

10:47 think browser

10:47 like a complete walk

10:47 you need a table of paths that represent namespaces

10:47 then no walking, except to collect vars

10:47 Bronsa: ah, gotcha

10:48 dnolen: Bronsa: k I think I have a simple plan. Will ping you when it's in place :)

10:49 Bronsa: cool thanks

10:50 stain: is there a trick to forward a future to a promise without starting another future?

10:50 (and not block)

10:54 justin_smith: stain: what does "forward a future to a promise" mean?

10:54 stain: you may be thinking of a definition of future and/or promise that doesn't match clojure on the jvm

10:55 ,(future? (promise))

10:55 clojurebot: false

10:55 stain: justin_smith: I've made a (future) that depends on incoming (promise) -- and then I want to the result of that future to be delivered to other (promises)

10:56 so perhaps I can make my future simply do (deref (deref that-promise)) or something silly

10:56 I won't know inside the future body where to deliver it to

10:56 justin_smith: stain: oh, you are delivering a future to a promise?

10:56 stain: right

10:56 they are kind of chained together

10:56 well, they should be

10:57 https://github.com/stain/flowing-clj/blob/master/src/flowing/core.clj#L14

10:57 now I have to implement the linking

10:57 justin_smith: wait, you shouldn't be able to apply fn

10:57 oh, never mind, macro

10:57 silly me

10:58 stain: yeah, so it will deref inside the future

10:58 and not block outside

10:58 https://github.com/stain/flowing-clj/blob/master/test/flowing/core_test.clj if you are interested

11:00 justin_smith: stain: so what is the functionality being implemented here?

11:00 stain: justin_smith: see the test

11:00 you define a series of steps

11:01 then wire them together to provide the parameters from other steps (or outside values)

11:01 justin_smith: I saw the test and lack the imagination to see a situation where I would want to do that

11:01 stain: it's to have easier flexibility about the wiring

11:01 in scientific data analysis for instance

11:01 justin_smith: oh, so the kind of thing prismatic/plumbing does?

11:02 or maybe that was prismatic/graph

11:02 or both

11:02 stain: I think so

11:02 but I'm trying to stay close to the computational model of Apache Taverna, as I will plug this in as an alternative workflow engine

11:03 thanks for the links

11:04 justin_smith: n/p, I hope that provides some help, because at this point I really don't understand enough about what your code is trying to do to provide much input - maybe someone else could grok it though

11:07 stain: justin_smith: thanks for your help :)

11:08 should be easier if I wrote some documentation

11:09 I added a deref-deep function

11:09 so then I can do

11:09 (defn deref-deep [ref]

11:09 (loop [ref]

11:09 (if (not (ref? ref)) ref

11:09 sorry

11:09 then I can do (deliver (:a step) (future "double-ref!"))

11:09 justin_smith: stain: the future returns the promise?

11:10 kungi: Can someone please have a look at this gist and help me find out what I am doing wrong: https://gist.github.com/Kungi/beaed8b0bea16beb8ce6 When I change my routes in routes.clj and (reset) the whole system the routes don't change. Somewhere must be a reference to the old routes.

11:10 stain: justin_smith: no, I deliver the future to the promise

11:10 and then inside the future I call (deref) twice, if needed

11:10 justin_smith: never mind, that still wouldn't work - if the future returned a promise you could do (deliver (:a step) @(future ...))

11:11 stain: but then the delivery would block

11:11 justin_smith: oh, the promise is the first val, never mind

11:11 stain: and I would need another future

11:35 kaffeeboehnchen: I remember a site where one could learn clojure interacitvly with ranking and stuff. I just dont remember the url. Any ideas? :D

11:35 wink: 4clojure?

11:35 clojurebot: 4clojure is the place to go for Clojure exercises

11:35 kaffeeboehnchen: ah yeah, thanks

11:42 Shayanjm: I need to split my application into two components, a "generator" component (generates a huge vector that needs to be fed to workers), and a "worker" component (does stuff with the data it's fed)

11:43 How do I go about building two different jars when I run lein uberjar?

11:43 dstockton: Shayanjm: split them into separate projects perhaps

11:44 Shayanjm: dstockton: since they're so tightly coupled, i'd love to be able to build them both in one go

11:44 justin_smith: Shayanjm: another option is one uberjar - you can choose when invoking a jar which class is run as main

11:44 Shayanjm: justin_smith: I considered that, but my hesitation is that the jar loads a lot of stuff as of right now

11:44 dstockton: http://stackoverflow.com/questions/19334454/create-multiple-uberjars-in-leiningen

11:45 Shayanjm: which would introduce some non-trivial overhead for worker spin-up time

11:45 justin_smith: so for one case you run java -cp my.jar clojure.main -m my.core1, in another you could run java -cp my.jar clojure.main -m my.core2

11:45 Shayanjm: oh, OK

11:45 schmir: Shayanjm: https://github.com/zcaudate/lein-repack

11:46 Shayanjm: looking schmir

11:46 oh interesting

11:46 justin_smith: Shayanjm: so in order to not include all the deps, you would have different :dependency vector per uberjar profile?

11:46 Shayanjm: justin_smith: Yeah preferably

11:47 justin_smith: err, I mean :dependencies of course

11:47 Shayanjm: I saw something about using profiles and building via lein with-profile x1:x2:x3 uberjar

11:47 but i didn't see anything about splitting the deps

11:58 justin_smith: Shayanjm: what about separate project.cljs in one repo with overlapped :source-paths as apropriate?

11:59 Shayanjm: justin_smith: that sounds interesting. Anywhere I can read about proper :source-path use?

11:59 i'm not even seeing it in my currently project.clj

11:59 justin_smith: Shayanjm: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L278

12:00 Shayanjm: thanks justin_smith

12:00 Oh wow

12:00 i didn't even know this existed

12:00 this is excellent

12:01 wei: Shayanjm: you could also try looking into boot, it offers more flexibility with “non-standard” builds

12:01 Shayanjm: how do you select the different project.clj's in a single repo justin_smith?

12:01 i.e: how do I tell lein which project.clj i'm looking at?

12:01 wei: will definitely look into it. Boot is just another build tool, right?

12:01 wei: yup

12:02 justin_smith: Shayanjm: my approach would be to have subdirectories with the different project.clj files, and use "../src" etc. in the source-paths

12:02 Shayanjm: Gotcha that makes sense

12:03 justin_smith: Shayanjm: bonus, each one would have its own target dir isolated from the others

12:03 Shayanjm: that sounds like an ideal situation actually

12:03 justin_smith: the negative is managing multiple project files, but that may not be so bad depending

12:03 wink: I'd also never thought of this. brilliant :P

12:03 Shayanjm: For the most part, the project files will be set-and-forget

12:04 distributed computing is hard to architect locally :\

12:04 I guess most people don't do hacky distributed computing with Clojure. Seems like most of the literature floating around is all about hadoop/spark integrations

12:05 justin_smith: Shayanjm: I assume you have looked at sorenmacbeth 's stuff like flambo and marcellene?

12:05 *marceline

12:05 Shayanjm: justin_smith: Yeah I did. I watched his talk too

12:05 wink: is there even non-hacky distributed anything? anywhere?

12:05 Shayanjm: Awesome stuff

12:05 the issue is that we're primarily a python shop

12:06 so our current distribution pipeline is python-based, so I'll have to write the hypervisor in python

12:06 justin_smith: wink: bitcoin?

12:06 dunno, maybe that's hacky

12:06 the Internet

12:06 wink: justin_smith: hm, it's eventually consistent, but definitely not fast :P

12:06 Shayanjm: which makes deploying a bit of a weird thing since it's a non-JVM tool, I'll have to spin everything up and handle everything pretty much manually

12:07 wink: I'm just sayin, for a majority (I think) of people real distributed stuff is just too hard

12:07 Shayanjm: so I don't know how people 'usually' architect their distributed projects

12:07 wink: Yeah, most people don't need distribution

12:07 wink: it makes going from solving a problem a day.. to thinlking for 2 weeks

12:07 Shayanjm: but for those that do, they usually just jump on the hadoop bandwagon

12:07 wink: thinking isn't bad... but it's really opening a different can of worms

12:08 monoliths can be so nice to work with :)

12:08 Shayanjm: lol, the current code base is hella monolithic

12:08 https://github.com/ableeng/hexpacker

12:09 But doing 1m queries on a single box is suicide

13:42 irctc: would anyone be willing to look at my code on codereview and give me some feedback? I'm worried everything I'm doing is not idiomatic.

13:42 http://codereview.stackexchange.com/questions/93051/structure-of-parser-in-clojure

13:44 (I once looked at some python code that doubled every item in a list using a while loop and i+=1, which is SO NOT pythonic. Just worried I might be making some similar errors with my first foray into clojure)

13:54 hyPiRion: irctc: One would generally prefer keywords over symbols, and vectors over lists. So it's more common to see something that looks like {:shared [[:record-type 2] [:entering-firm 4] ...] :1A [[:filler 9] [:poss-dupe 1] ...]}

13:56 pandeiro: using ring-defaults' wrap-defaults, shouldn't setting {:session nil} within a response map delete browser cookies as well?

13:58 irctc: hyPiRion: and then have a second hash map linking the keys to the functions? The need for that extra dictionary was what prevented me from using keywords or plain strings in the first place.

14:01 hyPiRion: irctc: I've only skimmed the source, but if the symbols are there for evaling stuff, then yes, definitely. It's very uncommon to use eval in the first place (although it's warranted in some cases)

14:04 bensu: irctc, ask if you have any questions on the feedback.

14:09 amalloy: irctc: i agree with hyPiRion. it wasn't totally clear to me until i was already done writing up my review why all your names were funky and what you're using eval for, but hyPiRion's suggestion is the right one to get rid of that nonsense, and make explicit the implicit mappings you're currently using

14:11 eraserhd: gfredericks: AFAICT, there's no way to conditionally call a generator. Is that right? If not, I'm missing something super-obvious.

14:14 gfredericks: eraserhd: depends on what the condition is; bind could do that

14:14 if you describe the use case better I could tell if that's the best approach

14:14 eraserhd: I mean, I could call (gen/vector conditional-generator (if (= other-generated-name some-value) 1 0))

14:15 I'm generating events (maps). The event types are keywords (generated using gen/elements). I then generate the other fields, some are only present in some maps.

14:15 amalloy: eraserhd: so you need bind, indeed

14:16 or, well, maybe you can use fmap

14:16 eraserhd: fmap always generates. I realized that I forgot what bind actually does, so I'm looking it up.

14:17 amalloy: (gen/vector (bind conditional-generator (fn [the-map] (if (make-whatever? the-map) (make-whatever the-map) the-map))))

14:17 or, well, i guess that is missing some returns. i am just slapping together stuff that is not very helpful. listen to gfredericks

14:20 gfredericks: eraserhd: if you used fmap it'd probably be that you're generating all possible fields, then use fmap to remove the ones that don't apply to the event type

14:20 which could be more elegant if your event types have overlapping fields

14:21 another option is instead of gen/elements use gen/one-of and have a generator for each event type, that generates the full map for that type

14:21 eraserhd: That actually sounds pretty nice.

14:23 gfredericks: ~test.check actually sounds pretty nice

14:23 clojurebot: It's greek to me.

14:24 gfredericks: ~test.check |actually sounds| pretty nice

14:24 clojurebot: Roger.

14:25 eraserhd: I've noticed that my cases seem exponential. This kind of makes sense. E.g. 25 cases take 25 seconds, 30 take 35, I've never seen 125 complete. This is probably not a way to resolve :)

14:27 gfredericks: well

14:27 that kind of means you've set up your generators so they can't tolerate a size up to 125

14:28 which you can handle three ways

14:28 A) it doesn't matter I'll just only run my tests with n=30

14:28 B) I want to be able to run with more test cases so I'll cap the size at the generator level

14:29 C) I'll figure out how to rewrite the generators at a lower level so they don't get too big

14:29 D) does defspec have an option for max-size? maybe it could

14:29 E) that's four ways, or 3.5 maybe, but not 3

14:31 version 0.8.0-alpha3 has a new gen/generate function that can make it easy to explore how large things get at different sizes

14:32 hyPiRion: gfredericks: D is a suggestion I've put up on jira

14:33 gfredericks: will probably tackle that while re-vamping the API for the quick-check function

14:33 justin_smith: gfredericks: a funny number problem http://www.ericharshbarger.org/dice/go_first_dice.html

14:34 hyPiRion: yeah, http://dev.clojure.org/jira/browse/TCHECK-10 it is

14:35 gfredericks: justin_smith: sweet

14:35 hyPiRion: yeah I expect some way to pass arbitrary args to quick-check should be included

14:40 Shayanjm: justin_smith: do I need to have a :gen-class for both namespaces I intend to generate jars for?

14:41 I don't think I've fully grok'd what gen-class actually does...

14:41 justin_smith: Shayanjm: if you use java -cp my.jar clojure.main -m my-ns.core you don't need :gen-class at all

14:42 Shayanjm: it creates a class that a java process knows how to invoke, usually used in order to have an invokable main method

14:42 Shayanjm: gotcha

14:42 so if I have :gen-class in there I don't need to specify an entrypoint when I execute my jar?

14:42 i.e: namespace.gen and namespace.work become gen.jar and work.jar

14:42 each have their own -main's

14:43 I've just been doing java -jar my.jar to execute (my namespace.core is being split to namespace.gen & namespace.work. namespace.core currently has :gen-class)

14:43 justin_smith: Shayanjm: well, that route involves setting your :main-ns and having :gen-class and setting up your :aot field in project.clj

14:43 Shayanjm: that sounds dirty

14:44 I'll just kill the :gen-class's. Will that fuck anything up re: uberjaring?

14:44 I think I'm still using the boilerplate uberjar setup in my project.clj

14:44 justin_smith: Shayanjm: only that you'll need a command line arg specifying the main ns for clojure to invoke

14:44 Shayanjm: kk

14:45 justin_smith: which is a small hassle in my experience, compared to the complexity an otherwise unneeded gen-class can create

14:45 Shayanjm: True that

15:11 tahmid: Hello! I need some help with immutant 2

15:11 I am handling webscoket request

15:11 Immutant provides nice callbacks like :on-message :on-open and :on-close

15:12 But what should I do If I want to send a message to a websocket without those callbacks

15:12 I mean arbitrarily , without any event happening

15:15 gws: tahmid: if you don't get help here, you may have a better shot asking in #immutant

15:16 justin_smith: tahmid: with sente it's just a question of having a handle to send-fn and having the unique ID of the client you wish to send to

15:16 tahmid: and you can use sente with immutant

15:16 https://github.com/ptaoussanis/sente

15:17 tahmid: I looked at sente, it seemed a bit daunting

15:17 I will give it a try

15:17 justin_smith: tahmid: it's not that bad in my experience. The key is that you need to hook up its handler functions to your http server, and then when you initialize it it will provide you with the send-fn that will send to a client

15:19 tahmid: justin_smith: I am storinng the channels that I get from ring request in a vector.

15:19 justin_smith: oh, if you already have that you can use those, right?

15:21 Seylerius: Can keywords have a colon in them, later in the keyword? Like ":Foo:bar" and "Foo:baz"?

15:21 tahmid: justin_smith: printing the vector that contains the channels giving me this [#object[org.projectodd.wunderboss.web.async.websocket.UndertowWebsocketChannel 0x79aa8b3d org.projectodd.wunderboss.web.async.websocket.UndertowWebsocketChannel@79aa8b3d] #object[org.projectodd.wunderboss.web.async.websocket.UndertowWebsocketChannel 0x67435a65 org.projectodd.wunderboss.web.async.websocket.UndertowWebsocketChannel@67435a65]]

15:22 Seylerius: tahmid: Dude, paste that shit somewhere.

15:22 tahmid: Sorry

15:22 Seylerius: sprunge.us or ix.io is a good idea.

15:23 amalloy: if it's just a single long message it's not a big deal, really. the problem is when people paste 15 lines as 15 separate short messages

15:24 Seylerius: amalloy: Fair point.

15:25 Hmm... Quick and dirty way to invert a map of sets? I need a map where the keys are the items from the sets, and the values are sets of which keys contained the key.

15:26 amalloy: Seylerius: https://github.com/flatland/useful/blob/develop/src/flatland/useful/map.clj#L234 ?

15:26 Seylerius: Basically, I need to turn {:Foo #{:Bar :Baz} :Flib #{:Bar :Box}} into {:Bar #{:Foo :Flib} :Baz #{:Foo} :Box #{:Flib}}

15:26 Taking a look at that now, thanks amalloy.

15:27 amalloy: if you wanted to use it without pulling in useful, you could remove the code that supports {x 1 y #{2}}

15:28 at which point it's just (apply merge-with into {} (for [[k vs] m, v vs] {v #{k}}))

15:28 ,(let [m '{:Foo #{:Bar :Baz} :Flib #{:Bar :Box}}] (apply merge-with into {} (for [[k vs] m, v vs] {v #{k}})))

15:28 clojurebot: {:Baz #{:Foo}, :Bar #{:Flib :Foo}, :Box #{:Flib}}

15:29 H4ns: if i have a lazy seq bound to a variable and then traverse it while still keeping a reference to the head, will that cause the whole sequence to be realized? or can i safely keep a reference to the head and traverse it two times?

15:29 justin_smith: ,(into {} (for [[k vs] {:a #{1 3 5} :b #{7 9}}, v vs] [v #{k}]))

15:29 clojurebot: {1 #{:a}, 3 #{:a}, 5 #{:a}, 7 #{:b}, 9 #{:b}}

15:30 justin_smith: ^ my golf of that

15:30 amalloy: justin_smith: a totally incorrect golf...?

15:30 justin_smith: incorrect?

15:30 amalloy: try it on the input originally requested

15:31 justin_smith: amalloy: oh, I missed a constraint, OK

15:31 amalloy: H4ns: you will realize it all

15:32 Seylerius: amalloy: That's great, just tried it.

15:32 Works perfectly.

15:32 (inc amalloy)

15:32 lazybot: ⇒ 277

15:32 H4ns: amalloy: ok, i kind of suspected that without really understanding why

15:33 justin_smith: H4ns: the locals-clearing or gc cannot reclaim memory when you have a handle to it, the head of the list counts as a handle to the rest after it

15:35 H4ns: justin_smith: ok - so i basically want to avoid binding large lazy sequences to variables.

15:35 justin_smith: H4ns: right, or make sure those variables go out of scope

15:35 H4ns: justin_smith: thanks!

15:36 justin_smith: eg. (let [nums (range)] (foo nums)) is fine as long as foo does not return nums as part of its result

15:36 because locals-clearing knows that nums can't escape otherwise

15:39 m1dnight_: https://www.refheap.com/102345 <- can anyone give me *any* clue where to start looking? A stackoverflow

15:40 but I dont get an origin from within my own code.. :<

15:41 justin_smith: stack overflow while printing a sequential, makes me wonder if there are recursive concat calls somewhere?

15:42 m1dnight_: oh there are

15:42 justin_smith: or a collection that contains itself...

15:42 m1dnight_: oh

15:42 !

15:42 that gave it away

15:42 i think

15:42 to the debugcopter

15:42 justin_smith++

15:42 (inc justin_smith)

15:42 lazybot: ⇒ 262

15:42 m1dnight_: okay :p

15:43 justin_smith: (inc palindromes)

15:43 lazybot: ⇒ 2

15:43 Shayanjm: justin_smith: I'm blanking on this project.clj. Just sorta divorced the gen/worker stuff from the existing core

15:44 now need to rewrite the project.clj's for both gen & worker

15:44 unsure how overlapping :source-path's help with dependency isolation?

15:44 justin_smith: Shayanjm: well, of course they wouldn't overlap entirely

15:44 for that to help

15:45 but if you can't isolate like that, then you don't gain anything by having separate uberjars either

15:45 Shayanjm: Maybe i'm unclear on :source-path itself. In all examples I see it points to src/clojure - so I'm assuming it's just pointing to clojure itself?

15:45 err, src/main/clojure or something

15:45 justin_smith: Shayanjm: the default binding is "src" which is the directory under which we have our clojure src

15:45 Shayanjm: gotcha

15:45 ahhhhh

15:46 justin_smith: and src/main/clojure as the second entry

15:46 Shayanjm: okay that makes way more sense

15:46 justin_smith: so you might hav something like src/common/ src/app1 src/app2

15:46 whatever makes sense for your case

15:46 Shayanjm: Right, perfect. And in each project.clj I can define separate deps

15:46 justin_smith: though do take a moment to verify it wouldn't be simpler to just have two totally independent repos

15:46 Shayanjm: right

15:47 Shayanjm: so in order to uberjar, i'd have to cd into the subdirectory which has each project.clj and lein uberjar?

15:47 justin_smith: right

15:47 Shayanjm: Okay great, just making sure I'm not overlooking some lein magic

15:47 m1dnight_: justin_smith: indeed. I had a an atom that contained itself

15:48 justin_smith: m1dnight_: yeah, that would do it

15:48 m1dnight_: by luck I printed some variable and its enormous :>

15:48 gfredericks: ,(let [a (atom nil)] (reset! a a))

15:48 clojurebot: #object[clojure.lang.Atom 0x3460a511 {:status :ready, :val #object[clojure.lang.Atom 0x3460a511 {:status :ready, :val #object[clojure.lang.Atom 0x3460a511 {:status :ready, :val #object[clojure.lang.Atom 0x3460a511 {:status :ready, :val #object[clojure.lang.Atom 0x3460a511 {:status :ready, :val #object[clojure.lang.Atom 0x3460a511 {:status :ready, :val #object[clojure.lang.Atom 0x3460a511 {:status ...

15:48 Bronsa: it's not as fun anymore :<

15:48 justin_smith: m1dnight_: my preferred way to deal with this sort of thing is an adjacency-list representation - it allows arbitrary cycles in the data without any recursion in the structure itself

15:49 at the cost of one layer of indirection

15:50 m1dnight_: because, of course, sometimes your data really is a graph and not a tree

16:01 oddcully: given, that vim-fireplace calls piggieback like this (cemerick.piggieback/cljs-repl'.arg.'); is there any vile trickery to write `arg` that only `arg` gets executed?

16:04 m1dnight_: I think im closing in

16:05 but I have a question, if I have macros that expand a single line (the macro call) to say, 10 lines, do the line numbers in stacktraces and such match the actual lines, or the expanded lines?

16:05 Im guessing the latter?

16:10 justin_smith: m1dnight_: I recall various bugs regarding this line numbering behavior

16:13 m1dnight_: Well, I have pinpointed (some what) the problem; I print a message (map) and that contains a cycle somewhere

16:13 clojurebot: Excuse me?

16:14 justin_smith: m1dnight_: right, my suggestion was that an adjacency-list representation allows arbitrary

16:14 "nesting" in a flat one level structure

16:15 or if the nesting isn't needed, just not having it is a simple fix too :)

16:18 m1dnight_: Well, I predicted this issue, and I wrapped the entire concat in a (set ..) but that doesnt seem to fix it

16:18 so Im guessing I dont have the exact cause yet.

16:42 zot: when using prismatic schema, is there a way to concisely say, (s/either #{Foo} [Foo] '(Foo)) to cover the basic grounds for all things seqable?

16:44 anthgur: zot: what about pred? http://prismatic.github.io/schema/schema.core.html#var-pred

16:45 zot: that's what i was just writing up as the more verbose alternative. wondered if i missed some other better idea...

16:46 m1dnight_: I'm trying to debug my project with IntelliJ/Cursive but I get the error: "Exception in thread "main" java.lang.ClassNotFoundException: actransors.stm.RetryEx"

16:46 That is a custom exception I implemented and has genclass, but it works fine in leiningen.

16:47 Im not running the project as lein in intellij btw. I just put (-main) in my core.clj file and then "run core"

16:47 justin_smith: m1dnight_: are you requiring the namespace inside cursive that would create that class?

16:47 m1dnight_: Yes, I am

16:48 And also importing it

16:48 https://www.refheap.com/102355

16:51 Its odd that it works fine in leiningen though.

16:53 canweriotnow: Anybody up for a slightly insane question about string/json parsing?

16:53 amalloy: ~anyone

16:53 clojurebot: anyone is anybody

16:53 justin_smith: canweriotnow: in general, just go ahead and ask

16:53 amalloy: argh

16:54 canweriotnow: lol clojurebot

16:54 amalloy: i wish i knew how he was inferring that so i could remove it

16:55 canweriotnow: So, I'm looking at core.match, prismatic schema, doing a prewalk... too mnay options. I have some insane json, thus: https://gist.github.com/canweriotnow/56f737784db1d2bd293f

16:56 My issue is that I have keys like "[question(n)]" for each n (question number).

16:56 justin_smith: canweriotnow: what are you trying to do with this json?

16:56 canweriotnow: I need to correlate the question numbers (among other things) from this response data to the questions themselves, for which I have id's.

16:57 justin_smith: sounds like a json parse (I like cheshire) plus a map-kv, plus a regex and a group-by

16:57 something like that

16:58 canweriotnow: What I'd like is to restructure into a map like {:question {:4 "Drifter"}} instead of the flat "[question(4)]":"Drifter"

16:58 justin_smith: yeah, that's where the group-by comes in

16:58 but before that you need to do some parsing with regex

16:58 and :4 won't work

16:58 but 4 will

16:59 canweriotnow: The best I've done to make it usable is to give cheshire a keyfn that strips the \W chars, so I get :question4 "Drifter"

16:59 justin_smith: canweriotnow: that's where map-kv comes in - you can call a function on the keys to transform them

16:59 canweriotnow: So you think maybe multiple capture groups to grab (question) and (4) and then use group-by?

16:59 justin_smith: right

17:00 canweriotnow: Oh! I forgot map-kv!

17:00 justin_smith: and probably some update-in in a reduce

17:00 canweriotnow: sorry, not map-kv, I meant reduce-kv

17:00 canweriotnow: justin_smith: right, gotcha

17:01 justin_smith: This gives me a great place to start, thanks so much.

17:04 justin_smith: ,(reduce-kv (fn [m k v] (let [[_ a b] (re-matches #"([a-z]*)([0-9]*)" k)] (assoc-in m [a b] v))) {} {"abc12" :a "abc13" :b "abd42" :c}) ; canweriotnow

17:04 clojurebot: {"abc" {"12" :a, "13" :b}, "abd" {"42" :c}}

17:04 justin_smith: clojure is an excellent language for this sort of insanity

17:05 m1dnight_: Can one force clojure to print an atom in a particular way?

17:06 Im trying to debug using print statements but the datastructure is just way too massive to pick it out by hand

17:06 justin_smith: m1dnight_: my preferred technique is to bind the thing, then use (-> ...) plus the up-arrow keys to drill down into it

17:06 (in the repl of course)

17:12 cfleming: m1dnight_: WRT your gen-class issue, you need to tell Cursive to compile your namespace, under Settings->Build etc->Compiler->Clojure

17:19 canweriotnow: justin_smith: that's perfect. Clojure is excellent for many kinds of insanity :)

17:59 justin_smith: from our friends at circleci (built in clojure / cljs) - this blog post is hilarious http://blog.circleci.com/its-the-future/

18:00 jarjar_prime: which profile does "lein release" load?

18:01 m1dnight_: cfleming: thanks. that was what I was looking for.

18:01 (inc cfleming)

18:01 lazybot: ⇒ 16

18:01 m1dnight_: btw justin_smith fwiw, I found the error. Im using code from my professor and he simply creates circular maps. he just never prints them and that way it works..

18:02 so I see a nice PR coming up :>

18:02 after my thesis

18:03 jarjar_prime: uberjar has its own profile

18:04 justin_smith: m1dnight_: ahh - so I stand by my initial proposal, that with clojure you are better off using an adjacency list rather than a circular map

18:08 m1dnight_: Im not clear exactly on what you mean by that. Ive googled a bit and isn't a map an adjacency list?

18:09 devth_: ,(= false)

18:09 justin_smith: an adjacency list can be represented by a pair of maps

18:09 clojurebot: true

18:09 devth_: ,(= nil)

18:09 clojurebot: true

18:09 devth_: what's the deal w/ that

18:09 justin_smith: ,(= Double/NaN)

18:09 clojurebot: true

18:10 m1dnight_: reflexivity devth

18:10 no wait

18:10 well, that X is equal to X

18:11 yes, reflexivity

18:11 justin_smith: m1dnight_: the idea with an adjacency list is that all the keys (in both maps) are your nodes. One map is nodes to values, the other is nodes to edges, each node having edges being a set of keys for nodes you have outgoing connections to

18:11 m1dnight_: not quite because of Double/NaN, but kind of

18:11 devth: there must be a use? why is = even defined for a single arg?

18:11 justin_smith: devth: because we like to use apply to call a function on all the elements of a list as the args

18:11 ,(apply = ())

18:11 clojurebot: #error {\n :cause "Wrong number of args (0) passed to: core/="\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: core/="\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.RestFn invoke "RestFn.java" 399]\n [clojure.lang.AFn applyToHelper "AFn.java" 152]\n [clojure.lang.Rest...

18:12 justin_smith: ,(apply = '(Double/NaN))

18:12 clojurebot: true

18:12 justin_smith: it's not fully consistent, but it at least has a flimsy rationale

18:12 devth: i see.

18:12 justin_smith: ,(apply = [1 1])

18:12 clojurebot: true

18:12 justin_smith: ,(apply = [1 2])

18:12 clojurebot: false

18:16 m1dnight_: doesnt (=) make sense that it errors?

18:16 jarjar_prime: (inc clojurebot)

18:16 lazybot: ⇒ 53

18:16 m1dnight_: ,(=)

18:16 jarjar_prime: :-D

18:16 clojurebot: #error {\n :cause "Wrong number of args (0) passed to: core/="\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: core/="\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.RestFn invoke "RestFn.java" 399]\n [sandbox$eval193 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler...

18:17 m1dnight_: ,(+)

18:17 clojurebot: 0

18:17 justin_smith: m1dnight_: more sense than (= Double/NaN) not being an error (or at least false)

18:17 m1dnight_: oh, odd

18:17 justin_smith: ,(*)

18:17 clojurebot: 1

18:17 jarjar_prime: m1dnight_: what does , mean?

18:17 m1dnight_: well, thats needed for reducing and such I assume

18:17 justin_smith: ,(= Double/NaN)

18:17 clojurebot: true

18:17 m1dnight_: jarjar_prime: you type ,<sexp> to evaluate it

18:17 justin_smith: ,(= Double/NaN Double/NaN)

18:17 clojurebot: false

18:18 m1dnight_: because a double is a reference type so thats normal too

18:18 justin_smith: m1dnight_: read it again

18:18 it's not equal to itself, that's the spec

18:18 m1dnight_: oh

18:19 justin_smith: but = is short-circuited to always return true if it has one arg

18:20 Bronsa: justin_smith: how could it behave in any differnt way?

18:20 there's no way to make (= x) return false IFF x is NaN

18:20 I think?

18:21 no nevermind, there's Double/isNaN

18:21 justin_smith: Bronsa: it's more of a silly thing to me, it's very unlikely to lead to bugs

18:22 Bronsa: justin_smith: I've lost my sleep because of sillier things

18:22 justin_smith: I'm sorry to hear that

18:22 andyf_: Bronsa: So, a JIRA ticket and patch are forthcoming, then? :-)

18:22 clojurebot: Gabh mo leithscéal?

18:22 Bronsa: andyf_: that's justin_smith's pet peeve, not mine :P

18:22 andyf_: (completely, 100% joking there)

18:30 Bronsa: dnolen: do you have a way to make hudson run the cljs tests on the core.match/core.logic port?

18:30 dnolen: Bronsa: nope, need to sort that out with puredanger at some point

18:30 likely via Node.js or something

18:31 Bronsa: ok

18:31 dnolen: Nashorn still seems too unstable to depend on

18:32 justin_smith: feeling a bit better about my own cljs test automation woes right now...

18:38 puredanger: We should probably use docker coreos etcd and kubernetes right dnolen

18:38 dnolen: lol

18:42 jarjar_prime: there doesn't seem to be a way to specify a profile for :release-tasks huh?

18:42 ["deploy"] gets called with no profile set it seems

18:45 seems some projects are getting around it by using uberjars

18:45 but I am trying to avoid sending a fat jar to artifactory

18:48 "lein with-profile docker deploy" works

18:48 but "lein with-profile docker release" doesn't

18:49 is there another profile that release uses?

18:49 justin_smith: jarjar_prime: I'm not sure about this stuff, but one thing that might help is "with profile +foo" which adds the profile, rather than replacing

18:51 jarjar_prime: justin_smith: thanks, but it appears release is stripping that away too :(

18:55 stain: justin_smith: https://github.com/stain/flowing-clj -- perhaps easier to explain now that it works :)

19:04 TEttinger2: I did the workflow thing we discussed yesterday, have a look at https://github.com/stain/flowing-clj -- pretty basic so far (can only run the workflow once!)

19:04 also it can be changed from push to pull by replacing "future" with "delay".. I'll probably make that an option somewhere

19:06 hiredman: stain: have you seen prismatics stuff for this?

19:07 https://github.com/Prismatic/plumbing#graph-the-functional-swiss-army-knife

19:08 stain: hiredman: yes, I looked at it earlier

19:09 but I wanted to finish mine first before trying it

19:18 hiredman: what is smooth with the prismatic graph is how it has autowiring of the parameters

19:20 but it seems ironically to not have a good way to do the plumbing independently

19:29 hiredman: stain: I would take plumbing and extend it with component's dependency system then

19:30 e.g. avoid the dsl macros and use a sort of environment map of names to functions and a dependency map of functions to arguments

19:44 stain: hiredman: yeah, that sounds like a doable approach as well.. a bit different style, though

21:10 lvh: Is there anything obviously wrong with these compojure routes? I'm getting 404s, which leads me to believe that resources is taking precendence: https://gist.github.com/lvh/af3a2825d7647345437b

21:21 xulfer: Looks okay to me

21:22 justin_smith: lvh: have you tried restarting your server since the definition?

21:23 lvh: justin_smith: ah; good idea :) figwheel has spoiled me!

21:23 justin_smith: if restarting fixes it, try passing #'app to your http server as the handler instead of app

21:25 lvh: justin_smith: yep! thanks :)

21:25 justin_smith: wait, ring knows how to deref stuff?

21:47 justin_smith: lvh: ##(#'+ 1 1) ; vars deref when invoked

21:47 lazybot: ⇒ 2

21:50 justin_smith: lvh: the difference ends up being, of course, if the server is using your var, it will see any new definitions, not so if it is using a function

Logging service provided by n01se.net