#clojure log - May 20 2015

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

0:19 credulous: Hello. I am trying to learn emacs and clojure at the same time. This may not be wise. Questions are emerging.

0:21 One question I currently have: how do people conveniently run a web server within emacs? I have been running lein ring server from within an emacs terminal, but startup times are long.

0:21 Is there a constantly running server, maybe within nRepl, that can reload code on the fly?

0:29 ballpointcarrot: credulous: have you looked into http-kit? It seems to have a hot reload: http://www.http-kit.org/migration.html#reload

0:30 or, just do a search for ring.middleware.reload; it may help instead of killing/restarting ring

0:32 credulous: thanks, ballpointcarrot I'll look into that now

2:56 [mad]: hi

3:31 tdammers: any vim-fireplace gurus here?

3:31 I'd like to disable how fireplace changes what vim considers a "word"

3:31 is there an easy way to do that without hacking fireplace.vim itself?

3:49 oddcully: tdammers: i sometimes stumble over them too (e.g. /), but i have left them alone for now, since most of the time they work

3:49 tdammers: the way i'd try to do that:

3:50 tdammers: add an "after" ftplugin and put your `set keyword-=<thechar?` there

3:52 tdammers: it's actually `set iskeyword-=...`

3:53 zot: in cider, if I have a stacktrace that points to query.cljc, and I have 2 files (in different subtrees/namespaces) named query.cljc, it often goes to the wrong file when I press enter. any clues on how to give it enough information to go to the right file?

3:58 oddcully: tdammers: works. put `set iskeyword-=/` in your `~/.vim/after/ftplugin/clojure.vim`

4:03 tdammers: ah cool

4:03 will try

4:04 btw, the reason I don't want to treat / as a kw char is because it makes no sense in file paths and such

4:04 and ofc consistent behavior across all the languages I use

4:11 oddcully: the -=/ thing works, thanks

4:11 oddcully: yw

4:13 tdammers: while we're discussing fireplace, I noticed that :Require(!) does not reliably show compilation errors

4:13 it says that it reloads, and everything seems to be working, and then when I restart the entire thing, it fails to compile because there's a syntax error somewhere

4:20 wagjo: I have stateless cloud instances and I'm looking for some approach to pass configuration to them upon start. Any best practices for that? Was thinking about storing it in s3 object, or using zookeeper but the latter may be an overkill

4:21 tdammers: I wonder if that's a problem with fireplace or with nrepl

4:55 okal: Not sure if this is the right place to do this, but is it possible to use inline dependencies, so as to have auto reloading in leiningen when you change a file in a 3rd party lib?

4:55 s/to do/to ask/g

4:59 Seylerius: Is there a parallel equivalent to mapv?

5:00 kaiyin: Is there any performance penalty in using https://github.com/Prismatic/schema ?

5:01 slipset: Seylerius: don't quite know, but https://www.youtube.com/watch?v=BzKjIk0vgzE is a nice video on the subject

5:01 Seylerius: slipset: Thanks.

5:02 slipset: Seylerius, you're basically looking at mapv because of side-effects, right?

5:03 Seylerius: slipset: I'm looking at mapv because get/assoc prefer vectors.

5:03 slipset: ah, ok.

5:04 I've generally used mapv because I'm to lazy to figure out how doseq works

5:04 pastafari: Seylerius: what about (comp vec pmap)

5:49 justin_smith: ~pmap

5:49 clojurebot: pmap is not what you want

5:50 hyPiRion: hah

5:50 claypoole is probably more like what you want

6:36 justin_smith: gfredericks: this seems up your alley https://plus.google.com/101584889282878921052/posts/Fni6x2TTeaS

7:06 donbonifacio: my app on heroku keeps taking more than 60s to boot and heroku kills it. I have it precompiled. Is there anything I can do to speed things up?

7:06 btw my feeling is that the newrelic agent takes the majority of time

7:07 Empperi: how about doing stuff lazily after starting your app?

7:07 donbonifacio: it timeouts _before_ getting to main

7:07 Empperi: ok, you have something seriously funky going on there

7:08 donbonifacio: yes, newrelic agent

7:09 Empperi: anyway, if it dies before getting to main then most likely your library stuff is doing a lot of work in static constructors in java

7:10 you could load those classes lazily within your -main

7:10 so instead of requiring/importing stuff at the ns level do that explicitly inside -main

7:10 and only when it is absolutely necessary

7:11 donbonifacio: kay, I'll investigate, thanks :)

7:13 Empperi: hope that helps

8:08 kaiyin: core.typed has not effect at run time, right?

8:08 s/not/no

8:33 ambrosebs: kaiyin: as of today you can hook it into the compilation process, if that's what you mean

8:34 kaiyin: there's no type based optimisations yet

8:35 kaiyin: ambrosebs: so after an annotated func is compiled, it will still report type error when it occurs?

8:36 ambrosebs: kaiyin: if the current namespace is "typed", yes

8:37 try it out here https://github.com/typedclojure/typed-repl

8:43 kaiyin: ambrosebs: I got stackoverflow error when loading this into repl: https://gist.github.com/kindlychung/2d73bbc2f46ff713535e

8:44 ambrosebs: version 0.2.92

8:45 ambrosebs: don't add a self-recursive check-ns in a namespace

8:45 gfredericks: justin_smith: the way the numbers grow reminds me of goodstein numbers, which start 2,4,6,(3*2^402653211-2), ...

8:46 ambrosebs: either do it at the REPL or add ^:core.typed metadata to the namespace with the project.clj nrepl middleware described in that project

8:49 kaiyin: ambrosebs: doing it in repl gives CompilerException java.lang.RuntimeException: No such namespace: -t

8:51 ambrosebs: I have to leave for something else, will continue this later, thanks a lot!

8:52 ambrosebs: kaiyin: thanks for the report though, that's a regression.

8:52 should be a better error

9:01 mrb_bk: Anyone got recommendations for a good read on packaging/deploying simple Clojure web apps? I have a little 3 route ring JSON API that I want to launch as an executable

9:04 vijaykiran: mrb_bk: generating an uberjar and using a small script to java -jar uberjar.jar should work

9:20 justin_smith: for extra credit, you can use jsvc by making it implement the daemontools interface

9:20 (this has uberjar as a pre-requisite)

9:25 entity: hello, I'm thinking about developing a genetic algo. in Clojure and I need some kind of a fast data structure to hold the genetic information, which would look something like (up down right right ...); i.e. listing actions to take in certain situations

9:26 no sure if that makes much sense

9:26 not*

9:32 mrb_bk: This looks reasonable https://devcenter.heroku.com/articles/clojure-web-application#putting-it-all-together

9:56 entity: how do you make a copy of a string?

9:56 does str make a copy?

9:58 socksy: strings are immutable

9:58 patrickgombert: entity: strings are immutable so it wouldn't necesarrily matter if it made a copy or not

9:59 socksy: (they are just java strings)

9:59 entity: ah, I dodn't know they were immutable, assumed they're mutable since they're java strings

10:00 socksy: java strings are immutable :)

10:00 entity: java.lang.String is immutable?

10:00 socksy: yes

10:01 entity: ah, all the methods return new copies

10:01 right, thanks

10:01 wasamasa: they are in all the sane languages

10:01 socksy: wasamasa: that's not fair, you could say that about nearly every data structure ;)

10:01 wasamasa: ruby and C and elisp are therefore out :>

10:03 socksy: my point is that strings being mutable is the exception

10:03 entity: so suppose I wanted to kinda merge two strings together, taking a random character from each string... so (merge "abcd" "xyzw") could return "xbzw"

10:03 is there a fast way to do this, not making a new string object at each character?

10:05 or would it be more efficient to have the strings represented as lists/vectors of character in this case

10:08 socksy: I'd do vectors of chars personally

10:09 entity: looks like it will be easier to do that

10:09 socksy: actually, I wouldn't care about performance at all until it was slow enough to warrant rewriting it, so I'd probably do any old collection with single char strings

10:10 once you have the map logic hashed out, then look into optimisations, perhaps

10:10 wasamasa: hum, in clojure (seq "foobar") gives you (\f \o \o \b \a \r), but in clojurescript it's ("f" "o" "o" "b" "a" "r")

10:10 entity: socksy: thanks for the tips, I'll go with vectors for now

10:14 mgaare_: anyone have any luck getting clojure.tools.namespace.repl and cljx to play nice?

10:16 patrickgombert: wasamasa: https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure#the-reader

10:16 there are no character literals in javascript

10:19 wasamasa: it totally makes sense, I've just learned that using seq on a string gives me something else than substrings and was surprised about clojurescript behaving differently

10:20 CookedGryphon: Hi, I'm loading a runtime dependency with pomegranate. How can I call a contained static method?

10:20 if it was a clojure function, I'd use resolve and the quoted form

10:21 but I get a NPE doing that with a static java method

10:31 mrb_bk: Anyone got recommendations for simple signal handling?

10:32 Need to handle TERM and INT with a ring server

10:32 gfredericks: mrb_bk: like handling unix signals from the jvm?

10:33 mrb_bk: gfredericks: Oh hi! Yes

10:33 gfredericks: I have some stuff somewhere that casually did this

10:33 * gfredericks digs

10:33 mrb_bk: gfredericks: dope, casual is fine

10:33 gfredericks: please coat this code in disclaimers

10:34 https://github.com/clojure/test.check/blob/gfredericks/prng-comparison/src/dev/clojure/clojure/test/check/prng_comparison.clj#L6-12

10:35 mrb_bk: sun.misc

10:35 Is so dope

10:35 gfredericks: thanks

10:35 gfredericks: mrb_bk: np

10:35 mrb_bk: https://github.com/hyPiRion/beckon looks somewhat reasonable

10:38 gfredericks: yeah I bet so

10:43 entity: I'm trying to use fireplace with vim... I can see fireplace in :scriptnames, but commands like :Connect or :cpp fail, saying they're not an editor command

10:44 although things like 'K' seem to work

10:45 weird, maybe I jsut can't use it :P

10:45 oh, it's not :cpp it's cpp

10:45 kaiyin: hi, ambrosebs. i am back.

10:45 entity: nevermind then

10:45 kaiyin: So what's the better version of that error msg?

11:13 entity: how can I dynamically create a vector of length n?

11:14 the docs for assoc are confusing

11:14 Bronsa: entity: start with an empty vector and just keep adding elements to it

11:14 entity: Bronsa: using assoc?

11:14 Bronsa: ,(conj [] 1)

11:14 clojurebot: [1]

11:14 entity: ah, thanks

11:15 kaiyin: ambrosebs: I have created a bug report on jira.

11:16 justin_smith: entity: if you know the exact size vector (or the contents) ahead of time, there is vec

11:16 ,(vec (repeat 10 nil))

11:16 clojurebot: [nil nil nil nil nil ...]

11:17 Bronsa: justin_smith: it makes little sense to create an "empty" vector of size n in clojure, imho

11:17 justin_smith: usually that's something you need to do in langs with mutable colls/explicit memory allocation

11:18 entity: awesome, I can replace 'nil' with a function, I assume?

11:18 Bronsa: entity: using repeatedly rather then repeat, yes

11:18 entity: ah okay, cool

11:19 Bronsa: ,(repeatedly 10 (constantly 3))

11:19 clojurebot: (3 3 3 3 3 ...)

11:35 wombawomba: So running `lein deps` doesn't seem to download all my dependencies; when I run `lein ring server`, a bunch of extra dependencies are downloaded. Is there any way to get around this?

11:35 justin_smith: wombawomba: by using lein ring you alter your deps

11:36 wombawomba: justin_smith: any way I can make that alteration ahead of time?

11:36 justin_smith: Bronsa: it looks like creating a vector all in one go has perf benefits compared to conj https://www.refheap.com/101346

11:37 wombawomba: not that I know of. I hope this isn't a concern because you want to use lein ring in production. Don't do that.

11:37 Bronsa: whether those are worth it is an open question, and probably depends on context too...

11:38 wombawomba: I'm trying to build a docker container that has my app in it, and that runs `lein ring server-headless`

11:38 justin_smith: wombawomba: make an uberjar instead, and run the uberjar with java

11:38 wombawomba: ...but running lein ring means it takes forever

11:38 Bronsa: justin_smith: it sure does, my point is that I don't think it's something one should need to do in clojure

11:39 justin_smith: Bronsa: OK.

11:39 sobel: +1 uberjar

11:39 works well.

11:39 wombawomba: justin_smith: I could do that, but I'm doing this for development

11:39 justin_smith: wombawomba: with an uberjar, your docker no longer needs to contain git, or lein

11:39 wombawomba: oh

11:39 wombawomba: so I don't want to have to rebuild my container every time I change the code

11:39 sobel: i generally can't hear any meaning in the phrase, "but this is for development"

11:39 code is code

11:40 justin_smith: sobel: point being that he wants eg. the reloading behavior you get with lein ring, and to edit his code while the server runs.

11:40 inside a docker container

11:40 wombawomba: right

11:41 sobel: oh so the whole container is a dev instance

11:41 wombawomba: exactly

11:41 justin_smith: wombawomba: part of what lein-ring does is that it adds deps to be resolved. I'm not sure if there is a simple way to add those deps manually.

11:42 wombawomba: weavejester might be able to tell you if there's a trick for that, if he was around.

11:42 wombawomba: hmm

11:42 arohner: wombawomba: you can probably make it happen using 'lein with-profile

11:43 wombawomba: I guess I could try to find another way to get the autoreloading running

11:43 justin_smith: there is the wrap-reload middleware

11:43 arohner: wombawomba: ah, no, lein ring just adds a dep on '[ring-server/ring-server "0.4.0']. If you add that to your deps, it will probably be downloaded

11:43 justin_smith: that plus some embedded ring server (jetty, aleph, http-kit)? should get you what you want

11:44 arohner: oh, it's that easy? nice.

11:44 arohner: +1 for reading the source :-)

11:44 justin_smith: (inc arohner)

11:44 lazybot: ⇒ 1

11:44 entity: can someone please take a look at this code? I can't fihure out what's going on http://pastie.org/10198865#9

11:44 wombawomba: arohner: neat :)

11:45 justin_smith: entity: defn needs a parameter vector

11:45 entity: so change it to (defn rand-dna [] ...

11:45 entity: ahh

11:45 thanks

11:45 justin_smith: also, that fn rand-gene is a no-op

11:45 it doesn't get called or returned

11:46 so it is effectively not there

11:46 entity: it is called on the line below

11:46 justin_smith: no, it isn't

11:46 because there is no binding :)

11:46 it doesn't exist as far as the next line is concerned

11:46 you need to use let or letfn

11:47 entity: oh, I see

11:47 thanks again :)

12:23 andyf_: cfleming: Bronsa: I was reminded of Eastwood's WARNING in its documentation about how it will 'launch the missiles' if require or use on your namespaces would also do that. I am guessing that whatever static analysis Cursive does would *not* launch the missiles on similar source files? Sounds tricky to get good knowledge of what symbols mean without full eval.

12:25 Lots of common cases could be handled without full eval, of course, so perhaps Cursive just handles the common cases?

12:29 kaiyin: why does this block indefinitely after msg1?

12:30 gfredericks: kaiyin is blocking after the first message and so cannot send the second message with the actual code in it

12:31 kaiyin: sorry, copy/paste stopped working suddenly. https://gist.github.com/kindlychung/3f7c7a82f9dcecc4eb18 why does this hangs indefinitely on msg1?

12:34 ah, i think timeout is misused here.

12:35 how can I make it sleep for some time in a go block?

12:37 gfredericks: I think that would be a misuse of go blocks

12:38 you probably want to read a message from the timeout channel

12:38 but I'm not the bestest with core.async so dunno

12:42 kaiyin: ok

12:52 edbond: how to access environment by environ.core/env in project.clj? I want to pass database-url to ragtime in project.clj

12:53 environ page says I need to add lein-environ to :plugins. What's next?

12:54 https://www.refheap.com/101349

12:58 justin_smith: you add an :env key (usually under some profile), or alternatively set an environment variable in the shell so that lein will see it

12:58 typical is :env key for dev config, shell environment for prod

12:59 edbond: see the second block of source code here https://github.com/weavejester/environ#example-usage

13:00 that hash-map would go under :profiles

13:00 edbond: justin_smith, yes, I created profiles.clj

13:00 justin_smith: OK, then you are done

13:00 edbond: question is how to access it in :ragtime { :database <here> }

13:00 justin_smith: (env :ragtime)

13:01 in your source

13:01 edbond: that's not my source, it's project.clj, see https://www.refheap.com/101349 part of project.clj

13:02 justin_smith: right. That sets the data. In your source you use env to access it.

13:02 but :ragtime has to be under the :env key

13:02 like in the example I pointed out

13:03 edbond: I need to access environ.core/env in project.clj, in :plugins

13:04 hm, wait

13:05 profiles.clj will be merged in project.clj without subkey?

13:05 justin_smith: oh, I misunderstood, sorry

13:05 edbond: I mean as is?

13:06 or under :profiles key in project.clj?

13:06 justin_smith: I'd say for a tool like ragtime, it makes more sense to just have profile-specific configs, rather than using indirection via env

13:08 faveteli1guis: what am i missing here, any ideas? https://gist.github.com/favetelinguis/de0071d7b237a600f310

13:13 edbond: faveteli1guis, #(0 > 1) => #(> 0 1)

13:13 ,(> 0 1)

13:13 clojurebot: false

13:13 edbond: ,(0 > 1)

13:13 clojurebot: #error {\n :cause "java.lang.Long cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.Long cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval49 invoke "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval49 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compiler.java" 6792]\n [clojure.lang.Compiler eval "Compiler.java" 6755]\n [c...

13:14 edbond: justin_smith, yes, I still don't get how to access env in project.clj using :plugins [lein-environ]

13:15 justin_smith: edbond: doing that makes no sense to me, sorry

13:15 edbond: or I don't understand correct "If you want to be able to draw settings from the Leiningen project map, you'll also need the following plugin"

13:16 hm, how the to make project.clj environment aware? (if dev [criterium "x.x"]) for example

13:17 justin_smith: well this is what profiles are supposed to be for, and I really don't see what environ does that would improv it in any way

13:17 but maybe I'm missing something here

13:22 edbond: justin_smith, found in internets this thing: ~(System/getenv "artifactory_username")

13:23 justin_smith: that would get it out of the environment as set by the shell

13:23 I don't see how this would help during development, and in production you shouldn't be using project.clj at all

13:24 edbond: why not? I need to run migrations using ragtime - lein ragtime migrate in production.

13:24 For this I will need another database-url, most likely set in env

13:32 For this I will need another database-url, most likely set in env

13:47 kaiyin: could anyone help with this?

13:47 http://stackoverflow.com/questions/30356859/upper-limit-for-number-of-jobs-in-a-do-block

13:49 noncom: kaiyin: puts and jobs are different

13:49 puts are queued on the channel

13:49 (afaik)

13:50 kaiyin: ok, i see.

13:51 noncom: kaiyin: or, better, 1 channel allows for no more tahn 1024 putting/taking jobs

13:51 you may increase the size or use the buffering window

13:52 also, you may have more channels and more go-blocks

13:52 the keyword is that 1024 is max on a *single* channel

13:55 kaiyin: noncom: how do you use a buffering window?

13:56 noncom: kaiyin: http://clojure.github.io/core.async/ look at sliding-buffer and dropping-buffer

13:58 kaiyin: you can also pass a number of max buffer elements to a channel or buffer when creating them]

14:00 kaiyin: ok

14:03 harrigan: is there any way to stop seque from holding onto the head of a seq?

14:03 e.g. so that (let [r (seque (range 1e8))] [(first r) (last r)]) will not run out of memory

14:06 cfleming: noncom: Did you receive my email? Did it help?

14:31 harrigan: sorry, it's not holding onto head -- some other issue -- (last (seque (range 1e8))) also runs out of memory

14:38 andyf: cfleming: Does Cursive ever eval Clojure source code for the purposes of analyzing it (I don't mean in a REPL)

14:41 sritchie: anyone used a project with lein-modules on dokku or heroku?

14:41 sdegutis: Look. You have a function create-widget which takes [state, number] and returns [state, widget], alright? And you have a seq of numbers, so you want to create a seq of widgets. Normally you could use map, right? But look, you need to thread the returned state from one call into the next call.

14:41 sritchie: ***ing the bed in a big way: java.io.IOException: Cannot run program "lein" (in directory "/tmp/build/queue"): error=2, No such file or directory

14:42 sdegutis: Na'm sa'n?

14:42 So I thought to myself, surely this sounds like a job for some kind of monad. But I don't know Haskell, and this is Clojure.

14:42 So how do you solve this?

14:44 btobolaski: Use the threading macro inside the map?

14:45 sdegutis: Sorry I don't mean threaded like -> or ->>

14:46 I mean, the state returned from one call to create-widget needs to be passed into the next call of create-widget as the first parameter.

14:48 andyf: sdegutis: reduce ?

14:48 sdegutis: Hmm yeah maybe that will work. Seems like a weird way to map, but if it gets the job done...

14:48 andyf: There's always loop, if you have to, or just prefer the way the code looks

14:49 Bronsa: andyf: I think cursive only does static analysis -- no eval

14:50 andyf: Bronsa: Makes sense, if so. Sounds like a lot of work to write, with weird corner cases it won't quite do, unless I'm missing something.

14:50 infinity777: Disco Melee is hiring clojure developers. We are a fun team that is growing rapidly. Help us shape the future of gaming! https://docs.google.com/document/d/1GvnrSCUbYgbY9XdFs_DUx-0QZG2bIYT8Mbr0zdpTeew/edit?usp=sharing

14:51 andyf: I think it is the right way to go for a commercial tool. Not criticizing, just thinking about the approach and what it can do.

14:51 Bronsa: andyf: lot of work for sure. I believe it also requires custom rules for macros in order to do correct symbol resolution

14:54 andyf: I only partially agree -- no eval is definitely better than eval for an IDE but since it's so common to have live repls, runtime code might be available anyway. could have the best of both worlds combining static analysis with slime-like runtime introspection

14:55 but I understand cfleming is just one guy and it'd be probably impossible time-wise to do both :P

14:55 andyf: I'm just idly imagining what a Clojure lint tool would have to look like in order to avoid 'launching the missiles'

14:56 I suppose an approach like clojail might help protect you.

14:56 lvh: Doesn't kibit do a lot of that?

14:56 (It does it by parsing the code and doing pattern matching on the sexps; no evaling)

14:57 Bronsa: andyf: while worth it for a code editor, I don't think it'd be worth for a linter. would require too much config for the user

14:57 andyf: Yes, but kibitz doesn't catch the kinds of potential mistakes that Eastwood does (which evals)

14:57 s/kibitz/kibit/

14:57 lvh: sure

14:57 Bronsa: kibit is significantly less powerful than eastwood

14:57 lvh: it seems like there's an opportunity for limited evaluation for stuff like "is this actually a fn"

14:57 I don't know if that means "clojail" or "implement a handful of behaviors separately"

14:58 sdegutis: Figured it out.

14:58 I shouldn't have side-effect-ish functions like this that take and return state.

14:58 Instead I should be building up descriptions of side effects to run, and then committing them all at once.

14:58 Because working with data is way easier than working with state.

14:59 andyf: Preach it, sdegutis.

14:59 (I mean that in an encouraging, not sarcastic, way)

14:59 sdegutis: Plus I'll be able to add another badge to my nerd sash.

14:59 mlb-: Not trolling, but is there a guide for Java design patterns for Clojure programmers?

15:00 sobel: mlb-: i can explain why that's not 1:1

15:01 mlb-: sobel: I'm not expecting a complete 1:1 mapping of Clojure idioms to Java GoF design patterns ;]

15:02 andyf: mlb-: Do you mean a book on design patterns in Java, targeted at someone who knows Clojure already, but not Java?

15:02 sobel: are you looking for a getting-started group?

15:02 allenj12: this might be a litttle too big of an example but is it possible to make this use a transducer instead of reduce? http://pastebin.com/5tgRccPN

15:03 mlb-: andyf: If such a thing existed, I'd be very interested.

15:04 andyf: Some Lisp developer, maybe Paul Graham, wrote a summary of some OO design patterns, and how many of them were unnecessary in Common Lisp

15:04 mlb-: sobel: "Getting-started group"? I think so?

15:04 sobel: mlb-: are you starting clojure?

15:05 mlb-: andyf: Ah, no. Other way about. I got my team hooked on Clojure, but $WORK has mandated future development should be in Java

15:05 andyf: There may be a link to that article on this page: http://c2.com/cgi/wiki?AreDesignPatternsMissingLanguageFeatures

15:05 atankanow: mlb-: you may want to look up some of Venkat Subramaniam's java books or if you just want Java best practices read Effective Java

15:05 sobel: i can point you at some items to look at if you are trying to solve a specific case, otherwise... start doing stuff, ask specific questions. you will be amazed how fast just using clojure will cause you to need answers to specific questions :)

15:06 oh, bummer

15:06 andyf: Reading that page will be demotivating to anyone tasked with switching from Clojure to Java, I think :)

15:08 cfleming: andyf Bronsa: That's right, Cursive only does static analysis of the source

15:08 atankanow: mlb-: Venkat has a nice Functional Pogramming in java book ... it's better than starting with lots of value objects as I learned when i started

15:08 mlb-: andyf: I was demotivated when I heard the underlying motivation to move from Clojure to Jave :(

15:09 cfleming: andyf Bronsa: It is indeed very tricky and it does also require custom rules for macros (currently only provided by me, but that will change)

15:10 mlb-: atankanow: Ah, thanks. I found it on Amazon

15:10 atankanow: mlb-: yw

15:10 mlb-: what was the motivation to move to java?

15:12 mlb-: atankanow: Concerns over finding qualified candidates and assumptions of salary making them costly to retain.

15:12 cfleming: andyf Bronsa: The main limitation is the macro issue - once that's dealt with, it allows some very powerful functionality. For example, I'm currently doing type inference for Java interop, so completion etc will (hopefully) work as well as Java

15:12 andyf: cfleming: Thanks for the info. I am happy to be amazed at your achievements, without reimplementing them :)

15:13 cfleming: andyf: Hehe - it's definitely been more work than I expected!

15:15 atankanow: mlb-: ah ... well ... there are lots of expensive bad java devs out there too =)

15:16 andyf: mlb-: Might not be possible to convince your management otherwise, but I noticed that Alex Miller at Clojure/West had everyone in the room hiring Clojure developers raise their hands, and then put them down. Then everyone looking for work writing Clojure raise their hands. He commented that they should all be talking to each other :)

15:17 mlb-: Haha, true. Sadly, I've uncovered there's more cargo-culting here than observation of facts :(

15:18 atankanow: mlb-: i write java at work ... it's not a bad language ... like anything it can be corrupted

15:18 sobel: i really like my niche here, where i write extensions to a mostly-java code base in Clojure and call into them as needed.

15:18 library sized extensions

15:19 mlb-: atankanow: I fear that only works when your coworkers also have enough discipline to not do things the sloppy way

15:20 atankanow: nice ... that is cool ... I asked Neal Ford of thoughtworks once how I can get clojure into my java-based work projects, his response was to simply use AOT compilation and put the jars out ... no one will be the wiser

15:20 TEttinger: also never throw an exception

15:20 mlb-: my current escape hatch is to extend the existing Clojure stuff and let "new" projects be Java ;]

15:22 sritchie: gah, why am I still seeing this WARNING: please set :license in project.clj.

15:22 err

15:22 No credentials found for clojars

15:22 I know they’re in credentials.clj;

15:23 under #”https://clojars.org/repo"

15:23 is there something else I need to do to alias the entry as “clojars” or something?

15:28 allenj12: sorry for the repeat, but does anyone have experience with transducers? http://pastebin.com/5tgRccPN

15:29 atankanow: given a map where the vals are vectors, what is the idiomatic way to sort every val in the map?

15:29 this is what i have:

15:29 sritchie: anyone using credentials.clj?

15:29 atankanow: ,(map (fn [[k v]] [k (sort v)]) {:a [4 3 2 1]})

15:29 clojurebot: ([:a (1 2 3 4)])

15:29 atankanow: ,(map (fn [[k v]] [k (sort v)]) {:a [4 3 2 1] :b [\d \c \b \a})

15:29 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: }>

15:30 atankanow: ,(map (fn [[k v]] [k (sort v)]) {:a [4 3 2 1] :b [\d \c \b \a]})

15:30 clojurebot: ([:a (1 2 3 4)] [:b (\a \b \c \d)])

15:31 allenj12: atankanow: that looks good, you could use (into [] .. ) if you want the vector back

15:31 atankanow: right ... the point was actually to sort the map by keys and vals, so i just put the output of that map (into (sorted-map) ...)

15:32 tcrawley: sritchie: I use a ~/.lein/credentials.clj.gpg, with: {#"https://clojars.org/.*" {:username "foo" :password "barbell"}}

15:33 and that works for me

15:33 sritchie: tcrawley: looks like I had two maps in that file by accident. whoops

15:33 fixed my big issue on OS X by installing GPGTools

15:33 tcrawley: gpg is the bestest

15:34 glad you figured it out though

15:35 TimMc: mlb-: Just tell them you'll switch to writing Java but occasionally pull in Clojure "just as a library". ;-)

15:35 allenj12: atankanow: If your using the clojure beta you can use transducers

15:35 (into {} (map (fn [[k v]] [k (sort v)])) {:a [4 3 2 1]})

15:35 TEttinger: atankanow:

15:35 allenj12: ,(into {} (map (fn [[k v]] [k (sort v)])) {:a [4 3 2 1]})

15:35 TEttinger: (doc sorted-map-by)

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

15:35 {:a (1 2 3 4)}

15:37 TEttinger: atankanow, what kind of input to what kind of output do you want?

15:38 sritchie: tcrawley: thanks!

15:38 atankanow: TEttinger: {:a [4 3 2 1} -> {:a [1 2 3 4]} ... yes ... i could rigth a k/v comparator and used sorted-map-by

15:38 write

15:40 allenj12: atankanow: so you want it to be sorted by key aswell?

15:44 TEttinger: ,(into (sorted-map-by (fn [[k1 v1][k2 v2]] (compare v1 v2)) (map (fn [[k v]] [k (sort v)]) {:a [4 3 2 1] :b [\d \c \a \b]} ))

15:44 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

15:45 TEttinger: ,(into (sorted-map-by (fn [[k1 v1][k2 v2]] (compare v1 v2))) (map (fn [[k v]] [k (sort v)]) {:a [4 3 2 1] :b [\d \c \a \b]} ))

15:45 clojurebot: #error {\n :cause "nth not supported on this type: Keyword"\n :via\n [{:type java.lang.UnsupportedOperationException\n :message "nth not supported on this type: Keyword"\n :at [clojure.lang.RT nthFrom "RT.java" 933]}]\n :trace\n [[clojure.lang.RT nthFrom "RT.java" 933]\n [clojure.lang.RT nth "RT.java" 883]\n [sandbox$eval47$fn__50 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.AFunction compare...

15:45 TEttinger: aww

15:47 crack_user: why I should put a '@' in front the keyword when it refers a atom?

15:47 TEttinger: crack_user: @ dereferences it, it gets the current value

15:48 otherwise you are passing the wrapping atom, which can later change, not its current value

15:48 crack_user: TEttinger: so atom store others values beyond the current?

15:48 tcrawley: sritchie: my pleasure!

15:49 fourq: What kind of lists do lines 2 and 3 evaluate to? (They just look like floating keywords) https://gist.github.com/anonymous/6f3059ea59a5713f08e5#file-clj-L2-L3

15:50 puredanger: repl is a macro that takes options as alternating key/value pairs

15:50 I guess I don't know if it's a macro, prob a fn actually

15:50 TEttinger: ,(let [adam (atom [])] (do (print adam) (print @adam) (swap! adam conj :eve) (print adam) (print @adam)))

15:50 clojurebot: #object[clojure.lang.Atom 0x2facf711 {:status :ready, :val []}][]#object[clojure.lang.Atom 0x2facf711 {:status :ready, :val [:eve]}][:eve]

15:51 TEttinger: crack_user, just printing adam isn't very useful, as you can probably tell :)

15:51 atankanow: as an Adam, I appreciate that reference ... and dereference ... thanks TEttinger!

15:51 TEttinger: heh

15:52 fourq: puredanger ty

15:59 crack_user: TEttinger: thx, I get it

16:20 Reefersleep: Hey peeps

16:20 Anyone use Vim for Clojure development?

16:21 I'd like to pick your brain about vim-fireplace and indentation via =G

16:21 or = anything

16:25 oddcully: Reefersleep: i do and = usually leaves my brain alone

16:27 Reefersleep: Cool oddcully

16:27 So you never experience anything weird when using = to indent?

16:28 kaiyin: Here is the hotdog machine example from Clojure for the brave and true: https://gist.github.com/kindlychung/36ffd585378c69b4895c

16:29 Using one channel seems quite enough, what's the advantage of using two channels?

16:29 Reefersleep: I've experience a weird, unnecessary deep level of indentation after a line containing \[, that is, the character "["

16:29 I think the indenting mechanism interprets it as the beginning of a vector

16:29 or something like that

16:30 oddcully: Reefersleep: let me try that...

16:31 Reefersleep: Cheers :)

16:32 oddcully: cheers in deed. need a beer. well could you provide some snippet via pastebin/gist/refheap/... ? my naïve attempt don't break (e.g. (str "asdf" \[ "adsf"))

16:33 Reefersleep: lemme whip something up

16:41 here you go oddcully

16:41 http://pastebin.com/dCN5iHwx

16:41 That's as it appears when I do gg =G

16:42 I've got stuff in my .vimrc of course

16:42 let me just try with an empty .vimrc

16:44 oddcully: i pasted this, paredit added the ] and after cleaning out some whitespace the internet gods gave me, this indents quite correct for me

16:44 the (+ is under (prn

16:48 Reefersleep: here's with an empty .vimrc

16:48 it actually looks fine. Well, not wrong, anyway.

16:48 http://pastebin.com/6t7Bxvik

16:49 sorbo_: I'm trying to "roll up" a vector of maps into a map of maps. Anyone done something like this? Gist here: https://gist.github.com/anonymous/05428c95465d590400be

16:50 vector of maps -> map of maps makes sense to me, but I'm not sure how to "update" fields as I zip

16:51 Reefersleep: I guess I gotta find the culprit in my .vimrc

16:51 I don't use paredit

16:51 for some reason, the Leader key does not work in my current Vim

16:52 oddcully: paredit most likely does not fix indenting

16:52 Reefersleep: and without it paredit doesn't work the way it's supposed to

16:52 Well, just to say that I don't use it :)

16:54 oddcully: i am the first to turn of stupid "autocomplete" stuff in any program... but paredit + i/a motions is really handy

16:54 gfredericks: sorbo_: you just have the id key and the one other key?

16:54 sorbo_: gfredericks: there are other keys, but those don't need to accumulate. they're the same from map to map.

16:55 gfredericks: sorbo_: okay so those would not be included in the return value?

16:56 sorbo_: I think this does what you want https://github.com/Prismatic/plumbing/blob/master/src/plumbing/core.cljx#L160-169

16:56 Reefersleep: hm, it was not "set filetype indent on"

16:56 sdegutis: Is there an idiomatic Clojure pattern for this that doesn't use a custom function?

16:57 I have a list of maps, and I want to get the first one (if any) with a key matching a given value.

16:57 Reefersleep: oddcully, I'm sure it's neat (paredit), and I'd love to give it a go - I think I need to recompile Vim or something to fix the Leader key first, though

16:57 sorbo_: gfredericks: this looks promising, I'll give it a go

16:57 thanks!

16:57 sdegutis: Only way I know how to do it is with (first (filter #(= value (:key %))))

16:58 Hi I'm new to Clojure, please help?

16:58 oddcully: Reefersleep: maybe you have just configured it wrong? my leader is the default \ iirc. i have several commands on , as pseudo leader

16:58 justin_smith: sdegutis: lol

16:58 oddcully: Reefersleep: at least things like \sh for slamhound work

16:59 sdegutis: I mean new to writing good Clojure.

16:59 Sorry for ambiguity.

16:59 oddcully: Reefersleep: but paredit (for me) needs no leader at all. it just works its magic with (){}[]""

16:59 gfredericks: sdegutis: I think that's how most people do it

16:59 sdegutis: gfredericks: there must be a better way

17:00 I thought I found one the other day, but I can't remember it.

17:00 I think it used juxt and set.

17:01 gfredericks: there's certainly weirder ways to do it

17:01 sdegutis: Sorry no I am looking for idiotic way.

17:01 idiomatic

17:01 justin_smith: (first (filter (comp #{:v} :field) [{:field :a} {:field :b} {:field :v}])) ; something like this?

17:01 ,(first (filter (comp #{:v} :field) [{:field :a} {:field :b} {:field :v}]))

17:01 clojurebot: {:field :v}

17:02 sdegutis: Looks right.

17:02 How the..

17:02 justin_smith: it's classier I guess, but not neccessarily better

17:02 sdegutis: Why not better?

17:02 gfredericks: readability

17:02 sdegutis: I'm trying to idiomatic my Closure code.

17:02 justin_smith: a simple equality check is more directly what you want, and more efficient than the set lookup I would assume

17:02 sdegutis: I want repeatability over readability.

17:03 And generalizationiability.

17:03 This is more general solution which works for more than just maps and attributes.

17:03 For example, the function I want to compare right now involves comp, not just a key test.

17:03 Ima comp a datomic entity attribute to another lazy datomic entity relationship and get *that guys* attribute key.

17:04 justin_smith: I think the main thing it has going for it is it makes the reader thing "gee whiz, I bet the person who wrote that is a functional programmer"

17:04 sdegutis: I always thought it was better form to write more general and functional code and fewer anonymous functions.

17:04 Since anonymous functions encourage repeating the same algorithm everywhere instead of giving it a name.

17:05 justin_smith: I'm being a bit glib there

17:05 sdegutis: Even after reading the definition of glib I don't know what you mean sorry.

17:05 gfredericks: you could argue that readability is a lot more important than maximizing generality

17:05 Reefersleep: Whatever I comment out, stuff is not right

17:05 I can get rid of the \[ problem, but then other stuff happens

17:06 sdegutis: (def get-first [things finder value] (first (filter (comp #{value} finder) things)))

17:06 gfredericks: they're equally important

17:06 gfredericks: they both have a precedence of 120

17:06 gfredericks: okay

17:06 good to know

17:06 sdegutis: (if you compile with default flags)

17:06 justin_smith: sdegutis: if the person is looking for false or nil, that will fail

17:07 sdegutis: justin_smith: ugh dangit

17:07 then maybe just =

17:07 (partial = value)

17:07 justin_smith: I would use (partial = value) yeah

17:07 sdegutis: Great.

17:07 Still feels better than #(= value %)

17:07 justin_smith: if you had values (partial contains? (set values))

17:07 sdegutis: I'm sure it is better, even though I can't fully explain why.

17:08 justin_smith: ,((partial (contains? (set [:a :b :c]))) :a)

17:08 clojurebot: #error {\n :cause "Wrong number of args (1) passed to: core/contains?"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/contains?"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 32]\n [sandbox$eval49 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang....

17:08 justin_smith: ergh

17:08 ,((partial contains? (set [nil :a :b :c])) nil)

17:08 clojurebot: true

17:09 sdegutis: justin_smith: thanks for helping me with this i appreciate the patience

17:09 and gfredericks thank you for your persistence in helping finding a good solution

17:09 gfredericks: np

17:10 sdegutis: attribute is too specific to objects, whats a better word for a function that can be operated on a value to turn it into another value somehow

17:10 maybe function?

17:10 like "its a function of this thing"

17:11 gfredericks: key-fn is used a lot in clojure.core

17:11 ,(doc min-by)

17:11 clojurebot: Excuse me?

17:12 gfredericks: &(doc min-by)

17:12 lazybot: java.lang.RuntimeException: Unable to resolve var: min-by in this context

17:12 gfredericks: &(doc min-key)

17:12 lazybot: ⇒ "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is least."

17:12 sdegutis: but it mightnt be a key, it might be any arbitrary derivation

17:12 derivation-fn seems more apt

17:12 amirite

17:12 Reefersleep: oddcully: some stuff worked in paredit without the leader key

17:12 gfredericks: sdegutis: the min-key and max-key functions use "key" in a more abstract way

17:12 that is similar to yours

17:12 sdegutis: oh

17:12 ok maybe keyfn

17:12 why the dash tho?

17:12 keyfn isnt ambiguous

17:13 gfredericks: somepeoplelikedashes

17:13 Reefersleep: oddcully: it was kind of weird, though. According to the documentation, stuff that was supposed to be preceded with the leader key just worked without

17:13 sdegutis: keyfn is short enough to not be difficult to visually parse

17:13 gfredericks: okay

17:13 sdegutis: so-mepe-ople-liked-ashes btw fwiw

17:13 Reefersleep: oddcully: and this caused a problem whenever I passed over function names from clojure core (I think), because it would try to look up the documentation (I think)

17:14 oddcully: which caused lag. Which, you can guess, was immensely annoying. Imagine lag for every third w

17:14 horrible.

17:15 oddcully: Reefersleep: brain fade... i actually use the leader there all the time for \W, \w{ and \s etc

17:16 Reefersleep: oddcully: Anyhow, I looked through my .vimrc with /indent and commented out any line I found, one by one, and tried to indent afterwards with each individual change.

17:16 oddcully: Reefersleep: but i feel the pain. i have configured plugins to my needs because they used some odd leader which cramped my style

17:16 sdegutis: It workd be.

17:16 btw

17:16 Reefersleep: oddcully: And I could not get sane indentation with any of the individual options left out.

17:17 oddcully: I've read that this is a common problem with Vim :(

17:17 oddcully: not with my vim it aint ^_^

17:17 Reefersleep: oddcully: Good for you :)

17:18 oddcully: Reefersleep: i run std gentoo vim 7.4.273

17:18 Reefersleep: oddcully: I'll figure the leader out eventually, and I'm looking forward to parediting :)

17:18 oddcully: how do you get the version?

17:18 oddcully: run vim - it's in the middle of the screen

17:18 Reefersleep: VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Apr 22 2014 11:08:18) MacOS X (unix) version Included patches: 1-258 Compiled by buildbot@tenseven-slave.macports.org Huge version without GUI. Features included (+) or not (-):

17:19 (from :version)

17:19 oddcully: there for sure is some --version too

17:19 Reefersleep: Hm. I thought it would be compiled by me. Maybe I've accidentally removed a symlink or something

17:20 oddcully: maybe relevant plugins are: paredit, fireplace, typedclojure, slamhound, eastwood, surround, matchit

17:20 rather excessive list for a try-and-error-run :/

17:20 Reefersleep: Of those, I only have fireplace

17:20 I could try commenting out pathogen infect

17:22 No difference without vim-fireplace

17:22 oddcully: i have used all my vim foo for today. i have no clue, where i would start to look for such an indenting problem

17:22 Reefersleep: Well, thanks for spending it on me, oddcully :)

17:22 oddcully: its hard to believe, that they broke it in those about 15 patches

17:22 Reefersleep: Huh?

17:23 oddcully: haha! no i actually helped one today with a oneliner on the right place

17:23 Reefersleep: Of whom are you talking, and what patches?

17:23 oddcully: 258 vs 273

17:23 Reefersleep: aah

17:23 Hm

17:23 oddcully: i assumed your "included patches" there refers to my patchlevel

17:23 Reefersleep: Guess so

17:24 Well

17:24 Do you have any idea who I could ask about this stuff?

17:24 A forum or specific peeps?

17:25 oddcully: do you have some account in the world, where you could test at least another version? if nothing else, i'd try to report a bug

17:25 Reefersleep: I guess I could just try a different version

17:26 oddcully: i meant, if you have an account to some unix box somewhere. opening a .clj file there should give some results

17:26 Reefersleep: oh, no. :/

17:26 But I could run Linux from a USB I guess

17:26 ?

17:26 Some Linux.

17:27 oddcully: na no hastle

17:29 sandbags: is it possible to redefine count for a record type?

17:30 gfredericks: don't think so

17:30 kind of the point of defrecord is to be map-like in all the mappy ways. deftype is the lower-level thing that lets you make whatever alien thing you want

17:31 sandbags: gfredericks: yeah, my record is essentially a list + some housekeeping info

17:31 so i wanted it to act like a list in some contexts

17:31 gfredericks: it's probably cleaner to just explicitly convert it when necessary

17:32 sandbags: gfredericks: yeah, i was hoping to avoid having to create type specific functions for common ops

17:32 but you could be right

17:32 gfredericks: metadata can be an okay way to sneak housekeeping info along for the ride if you're passing things through code you don't control

17:32 sandbags: gfredericks: i thought about that, but it didn't feel right

17:33 gfredericks: making a record have a different count is a lot less right :)

17:33 sandbags: okay, i guess i give up the yak shave and get on with solving my problems

17:33 gfredericks: i'm not sure about that but i'll take your word for it

17:35 gfredericks: sandbags: magical data structures can confuse the hell out of people that don't know what you're doing

17:35 sandbags: gfredericks: and thanks for the info

17:36 gfredericks: i do agree although i think context is important in making that judgement

17:36 gfredericks: I once spent hours debugging only to find out that clj-http or ring or something was using a magical case-insensitive map for http headers

17:36 sandbags: i suppose i could deftype if i really care enough

17:38 amalloy: !lm . abyss.exit x=turn

17:38 oops

17:39 Reefersleep: oddcully: Thanks a lot for your help :)

17:39 gfredericks: amalloy: seems like a weird password to me but who am I to judge

17:39 I wouldn't have guessed it so I guess it's a good one

17:40 amalloy: /msg nickserv identify amalloy<3gfredericks4ever

17:40 oddcully: BUSTED!

17:40 Reefersleep: oddcully: I'm heading off. hope I'll figure it out eventually. Starting to consider checking out Emacs with Evil mode or maybe Spacemacs

17:40 oddcully: Reefersleep: yw, good luck, like any state ridden blob this is sometimes hard...

17:41 Reefersleep: Aye

17:41 Thanks :)

17:41 gfredericks: amalloy: ha

17:53 danielcompton: Does anyone have a guide for porting clojure libraries to cljc libraries? I'm fine with writing the reader conditionals, but I'm getting stuck with how to build the ClojureScript part of it

17:57 arohner_: with friend, is there a way to make unauthorized requests return 40x rather than 302 to "/login"? I've found :login-failure-handler, but that only handles POST to /login, not unauthorized requests to e.g. /api/foo

17:58 aha, looks like I need :unauthenticated-handler

18:01 TimMc: Anyone know of a lein plugin that will diff two versions of a project file? Perhaps just looking at what resolved dependencies differ between them?

18:01 Thinking of writing one, don't want to waste effort.

18:02 justin_smith: TimMc: well, you could use read + data.diff I guess

18:02 kaiyin: ,(get (iterate inc 1) 14)

18:02 clojurebot: nil

18:02 TimMc: justin_smith: This would be slightly more than that since I have to resolve the deps, and add a little around profiles.

18:02 justin_smith: kaiyin: vectors are associative, lazy-seqs are not

18:02 kaiyin: ok

18:03 justin_smith: kaiyin: but nth would work

18:03 ,(nth (iterate inc 1) 14)

18:03 clojurebot: 15

18:03 kaiyin: ah, cool.

18:03 justin_smith: the difference is that get guarantees constant time

18:03 kaiyin: i see.

18:03 justin_smith: but there is no constant time way to get the nth item of a lazy-seq

18:04 kaiyin: sure, you might have to realize stuff.

18:05 TimMc: justin_smith: What's data.diff?

18:06 justin_smith: ,(require 'clojure.data)

18:06 clojurebot: nil

18:06 justin_smith: ,(dir clojure.data)

18:06 clojurebot: Diff\nEqualityPartition\ndiff\ndiff-similar\nequality-partition\n

18:06 justin_smith: ,(doc clojure.data/diff)

18:06 clojurebot: "([a b]); Recursively compares a and b, returning a tuple of [things-only-in-a things-only-in-b things-in-both]. Comparison rules: * For equal a and b, return [nil nil a]. * Maps are subdiffed where keys match and values differ. * Sets are never subdiffed. * All sequential things are treated as associative collections by their indexes, with results returned as vectors. * Everything else (including...

18:06 TimMc: Man, how long has this been around?

18:06 ,(-> clojure.data/diff var meta)

18:06 clojurebot: {:arglists ([a b]), :doc "Recursively compares a and b, returning a tuple of\n [things-only-in-a things-only-in-b things-in-both].\n Comparison rules:\n\n * For equal a and b, return [nil nil a].\n * Maps are subdiffed where keys match and values differ.\n * Sets are never subdiffed.\n * All sequential things are treated as associative collections\n by their indexes, with results returned...

18:06 TimMc: ,(-> clojure.data/diff var meta :added)

18:06 clojurebot: "1.3"

18:06 justin_smith: ,(clojure.data/diff {:a 0 :b [1 2]} {:a 0 :b [1 2 3]})

18:06 clojurebot: (nil {:b [nil nil 3]} {:b [1 2], :a 0})

18:06 TimMc: WTF, I need to go spelunking again.

18:07 justin_smith: heh :)

18:09 anyway, I could see data.diff being helpful in comparing two project maps

18:10 even if it has to be after some normalization

18:11 TimMc: For now my use-case is "what dependencies changed between these two git commits".

18:12 I'd like to eventually have this be integrated into a build agent so that Github pull requests can be annotated with a dep diff.

18:12 justin_smith: get project files -> extract :dependencies -> put in sets -> set/difference ?

18:12 TimMc: more or less

18:12 justin_smith: ahh, that's a cool idea

18:12 TimMc: Not a huge amount of work, obviously.

18:13 justin_smith: it would be useful to do it with recursive dependencies

18:13 TimMc: exactly

18:13 "Oh, clj-http updated its version of Apache HTTP client? Fascinating."

18:14 m1dnight_: why dont I ever have any good ideas like that! :p

18:15 justin_smith: or "this one dep I added has 1,000 deps of questionable quality?"

18:15 oddcully: quit slacking around in irc! ;P

18:16 and print it out in a git bisect

18:16 TimMc: m1dnight_: Becuase you haven't had the pleasure of dependency hell recently?

18:18 m1dnight_: just today i was bragging about how lein is so fantastic with deps!

18:18 is there a plugin to detect unused deps? i think i could manage that

18:18 i had deps hell today with cabal too though (haskell)

18:19 oddcully: there ya go! this is a good idea

18:20 justin_smith: m1dnight_: I think eastwood can find unused required namespaces

18:20 that would maybe be a start

18:20 wasamasa: argh, why does C-c C-c in figwheel's repl just abort the process

18:21 justin_smith: wasamasa: within what interface?

18:21 wasamasa: justin_smith: I'm using it from the shell

18:21 "Exit: Control+C or :cljs/quit"

18:21 * wasamasa throws up hands in the air

18:21 oddcully: justin_smith: eastwood left me in the eastern woods while trying out clara rules

18:22 wasamasa: I'd expect it to happen on C-d

18:22 justin_smith: wasamasa: C-c is kill, C-d is end-of-input

18:22 oddcully: is there a way around to have import the defrecords (for their class-iness)?

18:22 amalloy: wasamasa: i think i submitted a patch with that feature added, a long time ago

18:23 to cljs, not figwheel or whatever

18:24 justin_smith: wasamasa: note that if you have anything typed in but have not hit return, C-d does nothing

18:24 wasamasa: justin_smith: of course, just like in everything else on linux

18:24 justin_smith: right, so why would C-c do anything different?

18:24 wasamasa: where C-c aborts the current computation and C-d ends the process

18:25 justin_smith: aborting the current computation is not a standard behavior

18:25 and C-d is eof, and that is not always ending the process

18:25 amalloy: justin_smith: a lot of repl-ish tools do that with C-c though

18:25 wasamasa: it is, type in something in a shell prompt, hit C-c and watch the next one coming in

18:26 so, you can use a C-c C-d chord to quit pretty much any shell

18:34 justin_smith: hmm, I always thought of C-c as "kill the program in the foreground", but I guess that's less widespread than I thought

19:06 gfredericks: does anybody have non-trivial test.check test suites and would like to help me test the performance of the new RNG code?

21:01 creese: What does this mean? java.lang.ClassCastException: clojure.test$test_vars$fn__7209 cannot be cast to clojure.lang.Atom

21:01 justin_smith: creese: inside test-vars, an anonymous function is created. Somebody is trying to deref it

21:02 or maybe swap! on it

21:02 creese: there is a swap!

21:02 (defn stubbed-publish!

21:02 [_ message]

21:02 (swap! stubbed-queue conj message))

21:02 What's wrong with this?

21:02 justin_smith: what is stubbed-queue ?

21:03 creese: atom set to nil

21:03 (def stubbed-queue

21:03 (atom nil))

21:03 justin_smith: if that's the case, then that isn't your issue

21:03 do you have a stack trace to go with that error?

21:03 creese: yeah

21:03 justin_smith: if you can share it on refheap.com or gist or something that would help

21:04 don't paste the whole thing here though

21:04 creese: https://gist.github.com/creese/18e701ecfd36bc0c80d4

21:04 I would never do

21:04 justin_smith: so persister-test has something called init

21:04 and it calls reset! on a function

21:05 that's the issue here

21:05 creese: (defn reset-queue!

21:05 []

21:05 (reset! stubbed-queue []))

21:06 stubbed-queue is an atom

21:06 justin_smith: is that called in init?

21:06 because init is the one doing it

21:06 creese: (defn init

21:06 []

21:06 (reset! system {:db-spec nil :out-queue {:event nil}}))

21:06 justin_smith: I bet system isn't an atom

21:06 I bet it's a function

21:06 creese: (def system

21:06 (atom nil))

21:06 justin_smith: that's what the stack trace is saying at least

21:07 trying adding (print (type system)) to the definition of init

21:07 creese: how do you get that from the stack trace? (not doubting… just...)

21:08 justin_smith: the stack trace tells you which functions were called

21:08 the innermost at the top

21:09 so from your stack trace, line 17, we see that persister-test is called by the test setup

21:09 err, I mean something called init inside persister-test

21:09 and that calls reset

21:09 *reset!

21:10 and the next thing, we get an fn that cannot be cast to atom

21:10 so it has to be in init that the problem is happening (or at least the symptom)

21:11 creese: there must be another "system" that is taking precedence

21:11 justin_smith: yeah, could be a scope problem

21:11 creese: main has one

21:12 but it's an atom there too

21:12 justin_smith: stack traces may be confusing, but in my experience they don't lie

21:14 creese: where do you get L17?

21:14 justin_smith: the gist has line numbers

21:14 TimMc: justin_smith: Or you may not have the whole thing, such as with pst.

21:14 which drops part of the chain sometimes :-(

21:14 justin_smith: TimMc: fair enough, but this looks like the real deal

21:15 creese: justin_smith: oh, I thought you mean L17 of the code

21:16 justin_smith: sorry, I should have been more explicit

21:16 line 17 in that stack trace, moving up, is the part that is running your code

21:18 creese: I change the name to "system2" and it still does it.

21:21 justin_smith: did you try adding the print to show the type?

21:21 creese: yeah, no

21:22 wrong file

21:22 persister != processor

21:23 justin_smith: oh, so you had an error in persister and were trying to fix it in processor

21:23 creese: yeah :(

21:48 gfredericks: hello

22:14 madan: I want to try out Om for React Native application, but couldn't find any DETAILED discussions happening - just a couple of very short videos in youtube and supporting git repo. Can someone share me any good material?

22:21 justin_smith: madan: have you looked at http://swannodette.github.io/todomvc/labs/architecture-examples/om/ and https://github.com/omcljs/om/wiki/Basic-Tutorial ?

Logging service provided by n01se.net