#clojure log - Jul 28 2014

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

1:22 sm0ke: is some port for reducers http://clojure.org/reducers available for 1.4?

1:57 kelseygi: i have this function: (def reply-or-manual-rt?

1:57 (some-fn #(.startsWith % "@")

1:57 #(.startsWith % "\"@")

1:57 #(.startsWith % "“@")

1:57 #(.startsWith % "RT")

1:57 #(.startsWith % "MT")))

1:58 i'd like to store those strings in a vector and dynamically create that function but i'm getting stuck

2:05 TEttinger: ,(defn reply-or-manual-rt? [s] (map (partial .startsWith s) ["@" "\"@" "“@" "RT" "MT"])

2:05 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

2:05 TEttinger: ,(defn reply-or-manual-rt? [s] (map (partial .startsWith s) ["@" "\"@" "“@" "RT" "MT"]))

2:05 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: .startsWith in this context, compiling:(NO_SOURCE_PATH:0:0)>

2:06 TEttinger: ,(defn reply-or-manual-rt? [s] (map (partial (memfn startsWith s)) ["@" "\"@" "“@" "RT" "MT"]))

2:06 clojurebot: #'sandbox/reply-or-manual-rt?

2:06 TEttinger: ,(reply-or-manual-rt? "whee")

2:06 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/reply-or-manual-rt?/fn--92>

2:10 TEttinger: kelseygi, I'm a bit unsure what some-fn should do

2:10 is it supposed to call all these .startsWith fns?

2:11 kelseygi: i think it could have been or

2:11 either way i was getting tripped up with the order of arguments using partial

2:11 that's a much simpler way to write it, thanks

2:12 TEttinger: so reply-or-manual-rt? should be a function that just checks if an arg starts with certain prefixes?

2:12 kelseygi: yeah

2:13 TEttinger: ,(defn reply-or-manual-rt? [s] (reduce #(.startsWith s %) ["@" "\"@" "“@" "RT" "MT"]))

2:13 clojurebot: #'sandbox/reply-or-manual-rt?

2:13 TEttinger: ,(reply-or-manual-rt? "whee")

2:13 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox/reply-or-manual-rt?/fn--142>

2:17 TEttinger: ,(defn reply-or-manual-rt? [s] (reduce #(if (.startsWith %1 %2) (reduced false) s) s ["@" "\"@" "“@" "RT" "MT"]))

2:17 clojurebot: #'sandbox/reply-or-manual-rt?

2:17 TEttinger: ,(reply-or-manual-rt? "whee")

2:17 clojurebot: "whee"

2:17 TEttinger: ,(reply-or-manual-rt? "\"whee")

2:17 clojurebot: "\"whee"

2:17 TEttinger: ,(reply-or-manual-rt? "\"@whee")

2:17 clojurebot: false

2:18 TEttinger: kelseygi, you can tweak that so it returns true if the reduce is non-falsy

2:18 kelseygi: ok, that makes sense

2:18 i was really stuck on map--thanks TEttinger!

2:18 TEttinger: yeah, I tried a lot of things -- it was a hard task! no prob, thanks for the challenge!

2:21 kelseygi: reduced is interesting to learn about

2:21 TEttinger: I

2:21 I've actually never used it before, but I've seen it in eval here all the time

2:22 it was introduced a while after I started learning clojure

2:43 gws: ,(def reply-or-manual-rt-2? (apply some-fn (map #(partial (fn [p s] (.startsWith s p)) %) ["@" "\"@" "“@" "RT" "MT"])))

2:44 clojurebot: #'sandbox/reply-or-manual-rt-2?

2:44 gws: ,(reply-or-manual-rt-2? "test")

2:44 clojurebot: nil

2:44 gws: ,(reply-or-manual-rt-2? "@test")

2:44 clojurebot: true

2:44 gws: kelseygi: alternate implementation using some-fn just for fun

2:45 kelseygi: some-fn would be useful to pass in a collection of strings to test, right?

2:45 ,(reply-or-manual-rt-2? ["test","@test","RT test"])

2:45 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: startsWith for class clojure.lang.PersistentVector>

2:45 kelseygi: hrm or not

2:45 TEttinger: wait some-fn is a real fn not a placeholder?

2:46 ,(doc some-fn)

2:46 clojurebot: "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns the first logical true value returned by one of its composing predicates against any of its arguments, else it returns logical false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical true result against the original predicates."

2:46 gws: nah in that case what i did was build up a set of predicate fns (it's like your original list of #(.startsWith % "@") and so on)

2:46 and that can be run directly against the candidate string

2:48 so basically.. map over your list of prefixes, creating partial fns which each look something like #(.startsWith % "@") for each of those elements. once you've got that, you apply that mapping of fns to some-fn, which will try them in order

3:51 kitallis: has anyone used https://github.com/ckuttruff/clj-sql-up and deployed to heroku?

3:53 I'm trying to run the migrations using heroku run, but it complains about "Could not locate cemerick/pomegranate__init.class" – but it works fine on dev. Curiously, I also don't see pomegranate as a dep in the project.

4:04 SagiCZ: .

4:05 .

4:10 .

4:25 __daniel__: .

4:25 SagiCZ: __daniel__: top of the morning to ya

4:26 __daniel__: top of the morning to you

4:56 Kototama: i'm having trouble with sql korma generating a query with my table as "metadata" when the name is metadata (without quotes)

4:56 even the sql korma tests themselves use double quotes for table names

4:56 https://github.com/korma/Korma/blob/master/test/korma/test/integration/per_query_database.clj#L18

4:56 any idea how to disable this behavior?

5:12 Glenjamin: you need to tell it which type of database you're using

5:12 so it knows how to quote

5:14 Kototama: Glenjamin: my connection specificies the h2 database, do I need to do something extra for korma?

5:15 Glenjamin: if you're using korma's (h2) function, then it should be correctly quoting for h2

6:42 piranha: I feel like my brain is still not woken up. I have a list of items like [{:id 5}, {:id 3}, etc]. Any ideas how do I find an index if I have :id of an element?

6:47 vijaykiran: &(.indexOf [ {:id 1} {:id 3} {:id 5}] {:id 5})

6:47 lazybot: ⇒ 2

6:47 vijaykiran: piranha: does that work ?

6:50 __daniel__: vijaykiran: wouldn't work if there were more keys, which i would guess there are

6:52 clgv: ,

6:52 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

6:53 pyrtsa: Something like (defn index-where [f xs] (first (keep-indexed #(if (f %2) %1) xs))) (index-where #(= (:id %) 5) [...])

6:54 vijaykiran: __daniel__: yeah, but I assumed "find an index" means there's no duplication

6:54 piranha: vijaykiran: not really, there are more keys

6:55 vijaykiran: well, there is no duplication, but there are more keys

6:55 vijaykiran: &(.indexOf [ {:id 1} {:id 5} {:id 3} {:id 5}] {:id 5}) < will only give the first index of

6:56 &(.indexOf [ {:id 1} {:id 5} {:id 3} {:id 5}] {:id 5})

6:56 &(.indexOf [ {:id 1} {:id 5} {:id 3} {:id 5}] {:id 5})

6:56 lazybot: ⇒ 1

6:56 pyrtsa: piranha: Got the above? ^

6:57 piranha: pyrtsa: yeah that looks good!

6:57 thanks!

6:59 pyrtsa: piranha: No problem. Just watch out, it often turns out in the end you're better with not dealing with indices but by e.g. searching the tail where the first item matches or something more general like that.

7:00 ...Which would be just (drop-while (complement f) xs).

7:00 piranha: pyrtsa: well, in my case I display them from this vector and I need to display next/previous, and ids are unique, so I guess should be more or less ok :)

7:00 haha, drop-while isn't bad

7:00 hm :)

7:00 pyrtsa: :)

7:01 The problem with indices is they often go out of sync and fail silently.

7:25 ro_st: i need help debugging "Can't define method not in interfaces: get_file_name"

7:25 works on one machine, but not another. same .lein/profiles.clj, same lein deps :tree output

7:25 same project.clj

7:25 anyone encountered this?

7:26 xsyn: environment variables?

7:27 ro_st: thanks xsyn. hadn't thought of that. validating...

7:45 xsyn: weird

7:52 TimMc: ro_st: I'd chalk it up to either crap left behind in ./target/*/classes or /m2/repository

7:52 Try lein clean in both places.

7:52 And are you depending on SNAPSHOT versions of anything?

7:52 ro_st: can you lein clean in m2/repository ?!

7:53 TimMc: Oh! No, that's not what I meant.

7:53 __daniel__: [

7:53 TimMc: lein clean at the project root on both computers. :-)

7:53 ro_st: yes. there are several snapshots, all clojurescript-only though

7:53 ok, so lein clean on the working computer could break things on the working computer :-)

7:54 ok. clearing out ./target entirely made no difference

7:55 TimMc: Then you might have different SNAPSHOT artifacts for something.

7:55 TEttinger: lein deps

7:55 TimMc: TEttinger: All dependencies are up to date.

7:55 TEttinger: then I'm going to bed

7:55 ro_st: -grin-

7:57 Glenjamin: same jvm version?

7:58 ro_st: same jvm version

7:58 identical lein deps :tree output

7:58 only google results talk about core.typed which we aren't using at all

8:00 TimMc: ro_st: Move .m2/repository out of the way on both machines and try again. (Put it back later; it's a pain to redownload everything...)

8:01 ro_st: yup. broken machine is doing it first.

8:01 if it still fails, then i'll do the same on the working one

8:01 SagiCZ: &(println "what")

8:01 lazybot: ⇒ what nil

8:01 SagiCZ: ,(println "what")

8:01 clojurebot: what\n

8:05 ro_st: TimMc: ok. a fresh m2 didn't fix it. now running the same test on the working machine. (?!)

8:14 TimMc: ok. now the working machine is also broken

8:14 that means some sort of dependency tangle in the project, right?

8:42 hyPiRion: ro_st: usually, yes.

8:43 ro_st: i'm no closer to a resolution. i'm utterly baffled

8:43 hyPiRion: ro_st: and this worked fine previously?

8:43 ro_st: yes. now that i've moved my .m2/repository aside and made a new one, it's also broken

8:44 Caused by: java.lang.IllegalArgumentException: Can't define method not in interfaces: get_file_name, compiling:(clojure/tools/reader/reader_types.clj:107:1)

8:45 my deps tree: https://www.refheap.com/88641. there are no warnings about ranges or overides being printed along with this tree

8:47 hyPiRion: ro_st: yes... this sounds like a record/type issue.

8:47 ro_st: a lein check fails before it can start compiling any namespaces. i can't get a repl up at all to poke at things

8:49 hyPiRion: ro_st: lein downgrade 2.4.0 and check if it works

8:50 I know there were some AOT issues appearing going from 2.4.0 → 2.4.x

8:50 ro_st: trying that

8:50 no, that appears to make no differene

8:52 hyPiRion: even after lein clean?

8:52 ro_st: yep

8:52 hyPiRion: you can try to force tools.reader to 0.8.4 to see if that helps

8:52 add [org.clojure/tools.reader "0.8.4"] into the dependency list

8:54 ro_st: no, that didn't help either

8:54 looking at the source, i bottom out at a defprotocol for IndexedReader

8:54 boxed: does anyone know the correct way to get the clojure version in leiningen plugins? I have clojure 1.2.0 in my project.clj but when my plugin is run I get 1.5.1

8:54 * hyPiRion scratches beard.

8:54 ro_st: is it that it can't find the proto or is it that it doesn't have a valid object to which the proto has been extended?

8:55 hyPiRion: ro_st: do you extend it? It may be that you attempt to use get_file_name instead of get-file-name

8:55 But I would expect that get-file-name is munged and that the error necessarily isn't there

8:56 ro_st: no, i'm definitely not invoking tools.reader directly

8:56 the stacktrace goes via cljs.analyzer in clojurescript

8:56 hyPiRion: Ok, let me take a look at the dep tree again

8:57 ro_st: i'm updating the refheap with the latest tree and the full strace

8:58 https://www.refheap.com/88641

9:01 boxed: nm.. the answer seems to be to use leiningen.core.eval/eval-in-project

9:04 hyPiRion: ro_st: My guess is that there's some AOT issue going on

9:04 at least there's something with protocols/records extending protocols.

9:04 * SagiCZ sings a song

9:05 ro_st: so it's a name munging issue? _ where it should be -?

9:06 Reflection warning, clojure/tools/reader/reader_types.clj:34:1 - call to method get_file_name on clojure.tools.reader.reader_types.IndexingReader can't be resolved (no such method).

9:06 i disabled my dev time user.clj and was able to get this warning as well

9:07 gfredericks: boxed: yeah the nature of plugins is that they run in the leiningen process

9:08 boxed: what does your plugin do?

9:08 boxed: converts README.md into a midje style test file

9:08 the problem I have now is that I need to make it delete that test file if we’re running on a clojure version midje doesn’t support

9:08 Bronsa: ro_st: I haven't followed the convo but get-file-name has been in tools.reader since 0.7.8

9:09 gfredericks: boxed: why would someone use your plugin if they're using a clojure version midje does not support?

9:09 ro_st: Bronsa: something is causing it to want get_file_name instead

9:10 boxed: gfredericks: they’re running tests on multiple versions of clojure, and they are ok with only testing the examples againsts the latest

9:10 ro_st: i don't know enough about AOT or protocols and types to know why

9:10 boxed: well…. againsts 1.4+

9:11 Bronsa: ro_st: that's how it gets munged, the error is not about that

9:12 ro_st: ok. i have a barebones lein project with the same behaviour

9:13 boxed: well shit, eval-in-project always returns nil, that’s a bit blech

9:15 SagiCZ: hey guys, what do you do in case you are developing an api for example, you define a function which takes 2 parameters, you presume that one of them is a simple string and the other one is a map with some special keys.. you are expecting those. How do you force the users of your API to send the correct parameters to the function? Check it with asserts or "pre:" ?

9:15 thenge: Use prismatic schema or something similar

9:15 Bronsa: ro_st: I'm sorry I really don't know much about leiningen to help, but that error suggests some of your deps is pulling an AOT compiled tools.reader version prior to 0.7.8

9:16 ro_st: thanks bronsa

9:17 SagiCZ: ,(map "string-is-not-a-function" {:a 0 :b 1 :c 2})

9:17 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>

9:17 boxed: SagiCZ: as for the map, just destructuring it is probably ok, otherwise maybe look at core.typed?

9:18 I’m just guessing though :P

9:18 SagiCZ: this is how clojure does it.. and i dont like it.. it should say: "The first parameter should be a function"

9:18 augustl: SagiCZ: according to clojure.core, nothing, your problem, fail run-time, etc ;)

9:18 SagiCZ: augustl: yeah.. i see that.. but it could lead to some hard-to-find bugs

9:19 stuartsierra: The problem is that this kind of type-checking has a significant runtime performance cost.

9:19 SagiCZ: stuartsierra: does it really though..

9:19 stuartsierra: Rich has accepted patches that improve error messages, but only if they don't effect performance.

9:19 *affect

9:19 SagiCZ: stuartsierra: uh-huh

9:20 ro_st: Bronsa: yes. i deleted 0.7.3 and 0.7.5 from m2/repositories and a lein deps redownloaded them

9:20 augustl: that's what you get for not doing it compile time :)

9:20 hyPiRion: SagiCZ: linters, type checkers might help you

9:20 boxed: SagiCZ: I agree with you. At least we should have a debug mode that has errors that can be used

9:20 Bronsa: ro_st: if this can help, the last version of tools.reader that was AOT compiled shoule be around 0.7.3

9:20 ro_st: how would i find out which dependencies are pulling them in?

9:20 Glenjamin: the build profiles thing in clojure 1.7 might open the door to better error messages in the debug build

9:21 SagiCZ: let me restate the question.. lets say i expect the user to pass a map with keyword ":a" but he passes a map without it. what is the idiomatic way to deal with this in clojure?

9:21 stuartsierra: Yes, I'm hoping for that as well.

9:21 hyPiRion: boxed: I agree fully with this. But it's time consuming to keep both clojure versions (normal vs debug) up to date

9:21 at least naively, but of course possible to optimise that overhead

9:21 ro_st: hyPiRion: how would i determine which of my deps are pulling in the older tools.reader jars?

9:22 boxed: hyPiRion: could be something like asserts that are removed in some non-debug mode

9:22 ro_st: hyPiRion: same tree as before. i deleted 0.7.* from m2, did a lein deps, and it redownloaded 0.7.3 and 0.7.5. if i can find out which deps are doing this, then i can exclude and it should work

9:23 TimMc: ro_st: You ahve consistency between your two machines. My work here is done.

9:23 * TimMc flies off into the sunset

9:23 ro_st: TimMc: thank you. your advice was very helpful :-)

9:24 hyPiRion: ro_st: Hrm. Can you dump out `lein deps :plugin-tree`? There may be some interference there somehow

9:24 augustl: isn't there a way to disable pre/post when you compile jars for production?

9:24 ro_st: zero output for that

9:26 hyPiRion: ro_st: oh, riiight. you know that [org.clojure/tools.reader "0.8.4"] dependency I asked you to add in? Could you move that to the very top of the dependency list?

9:27 * hyPiRion wants to burn aether dependency resolution algorithms on a wooden stake.

9:27 hyPiRion: It's too much magic for me to handle.

9:28 ro_st: it's at the very top now, no change.

9:29 if it only downloads .pom, that means it isn't actually using that code right?

9:29 hyPiRion: right

9:29 ro_st: i only have 0.8.* jars in m2

9:30 hyPiRion: Hrm, I would guess there's a problem if you have a dependency depending on an AOT-compiled version?

9:30 ro_st: now i only have 0.8.5 jar in m2. still no dice.

9:31 how would i check for that?

9:31 hyPiRion: I don't know, unfortunately.

9:32 stuartsierra: `lein deps :tree`

9:32 hyPiRion: stuartsierra: https://www.refheap.com/88641 – doesn't show which version they depend on

9:33 unfortunately, hrm.

9:33 ro_st: actually, could you file an issue for this on the Leiningen issue tracker? Because I guess we want to find out of this as well.

9:34 ro_st: sure, i will do

9:34 hyPiRion: thanks, much appreciated

9:35 stuartsierra: Oh, you want to know every version that appears in the dependency tree?

9:35 * TimMc hands hyPiRion a three-way switch labelled "magic", "more magic", and "aether"

9:35 ro_st: yes please :-)

9:36 stuartsierra: OK, `lein deps :tree` only shows you the resolved deps the app is going to use.

9:36 ro_st: stuartsierra: the core issue: "Reflection warning, clojure/tools/reader/reader_types.clj:34:1 - call to method get_file_name on clojure.tools.reader.reader_types.IndexingReader can't be resolved (no such method)."

9:36 hyPiRion: I guess, if you want to figure out if some dependency depends on an old AOT-compiled version of the library.

9:37 stuartsierra: Try `lein pom` then `mvn dependency:tree -Dverbose`

9:37 ro_st: we now think that one of my deps' deps is requiring an AOT compiled reader older than 0.7.8. it fetches 0.7.3 and 0.7.5 poms when i do a fresh deps with an empty m2

9:38 thanks. trying that now. hopefully i can spot which libs want the older readers so i can exclude

9:42 stuartsierra: You can also make a global :exclusions in your project.clj

9:43 ro_st: ok. i found (org.clojure:tools.reader:jar:0.7.5:compile - omitted for conflict with 0.8.5)

9:43 adding an exclusion to that dep made no difference, however

9:45 the full mvn output is now also on https://www.refheap.com/88641

9:46 if lein deps :tree only shows a modern tools. reader, doesn't that mean that's the only one that'll load into memory?

9:46 if so, why then do i get the stacktrace in the middle of the refheap?

9:47 gfredericks: bbloom: ha I just had a minor unexpected issue with comparing floats

9:53 and I'm pretty sure it's because of serailization roudntrip issues (with a db)

9:55 jcromartie: Paredit command of the day: when inside a string, M-S splits it just like a sexp!

9:56 that's meta-S not shift

9:56 or Super or whatever S is on the left side of an Emacs keybinding

9:59 ro_st: and M-J splits it

9:59 __daniel__: and in paredit.vim?

10:02 ro_st: hyPiRion: fixed it

10:02 i have a fork of another project that uses an old t.r. i had updated the t.r in my fork but had not `lein install`ed it

10:03 raj91: Hello, does someone have the power to add a 1.6 tag to https://github.com/clojure/clojure ?

10:03 ro_st: so deps reports the right t.r version but check uses the one from m2 which is the older t.r

10:03 raj91: I'd like to properly hyperlink to some source code there.

10:03 ro_st: raj91: probably stuartsierra does

10:03 raj91: Meaning that I'd like a branch name to use; currently I can use d6baf6e1 which is a little ugly

10:04 arrdem: no 1.6 tag? that's weird...

10:04 ro_st: the reason is because i had that fork in checkouts

10:04 arrdem: raj91: there's a 1.6 tag

10:04 raj91: https://github.com/clojure/clojure/releases/tag/clojure-1.6.0

10:05 raj91: arrdem raj91 my fault, I was searching the branches

10:05 should there be a 1.6.X branch?

10:05 hyPiRion: ro_st: oh, nice

10:05 stuartsierra: There will only be a 1.6.X branch if we have a need for a 1.6.X release.

10:05 raj91: sorry for the false alarm

10:05 arrdem: there's no official branching standard specifying how Rich and co structure 1.6.X/1.7 devel.

10:05 hyPiRion: ro_st: hard to find such errors though

10:06 ro_st: hyPiRion: i made a new proj and copied all the deps and removed them one by one until it worked :-(

10:06 just glad it's fixed.

10:06 thanks for your assistance!

10:08 hyPiRion: yw

10:08 TimMc: Checkouts + local-only installs? Yuck.

10:31 GenaraL: sLm

11:40 gfredericks: there's a lein plugin for running standalone clojure scripts somewhere amirite?

11:41 in particular supporting some sort of dependency declaration at the top of the file

11:42 technomancy: gfredericks: you could include direct calls to pomegranate

11:42 arrdem: gfredericks: lein-oneoff showed up recently..

11:43 awwaiid: gfredericks: I recently had good luck with lein-exec

11:44 gfredericks: lein-oneoff looks good, since it explicitly supports the deps

11:45 technomancy: arrdem: awwaiid: thanks

11:45 arrdem: I need to look at how lein-oneoff is built..

11:45 it's a little weird to me that it's built on a #_ prefix

11:46 gfredericks: yeah I just checked that

11:46 they delete any initial #"\s*#_" before reading

11:46 arrdem: slurps, drops to chars, reads a form with lispreader?

11:46 yeah

11:46 *two

11:48 awwaiid: gfredericks: the issue with lein-exec can be in the #!/usr/bin/env portability. On my system I was able to cheat with "#!lein exec" and avoid adding a special "lein-exec" to my path

11:49 gfredericks: awwaiid: yeah I don't mind having to use lein to execute the file; I'm just trying to avoid the whole project filesystem

11:50 awwaiid: Yeah. Especially with [insert whatever is the most modern equivalent of nail-gun] you might actually be able to use it as a scripting language :)

11:53 arohner: gfredericks: there's lein jarbin

11:55 gfredericks: arohner: interesting but not obviously related?

11:55 arohner: ah, read things out of order

11:55 if you want a single file, yeah oneoff looks like a better fit

12:15 arrdem: john2x: ping

12:26 seangrov`: technomancy: I can open your eyes--take you wonder by wonder over, sideways and under on a magic carpet ride.

12:26 * seangrov` has a sparkle in his eyes now

12:26 technomancy: seangrov`: <3

12:26 best way to start your week

12:27 seangrov`: My repl feels so pleasant and nice now

12:31 bbloom: your repl will feel even more warm and fuzzy with https://github.com/greglook/whidbey

12:31 arrdem: bbloom: does that behave wit cider?

12:32 *with

12:32 bbloom: arrdem: no idea, i use vim

12:32 arrdem: o

12:32 bbloom: arrdem: but it seems to behave fine there

12:32 seangrov`: bbloom: Doesn't look like it's using fipp

12:33 technomancy: oh yeah, the guy who made this demoed it at seajure a while back

12:33 seangrov`: Looks nice though

12:33 technomancy: looks like he got it working more smoothly now

12:33 bbloom: seangrov`: it is using fipp via pudget

12:34 seangrov`: Very nice, didn't recognize pudget

12:34 bbloom: er pudget

12:34 seesh

12:34 puget*

12:34 made the same typo twice

12:35 anyway, puget nicely sorts maps and such, but sadly has to lose some performance promises to do that :-/ but still, it's fast enough for interactive work

12:35 one of these days i might try to modify puget to support a mode where it gives up on sorting for collections over a certain size

12:56 bordatoue: could anyone using gloss framework tell if how to skip bytes while decoding ; for example if want to read only third byte how do I skip byte 1 & 2

13:00 seangrov`: bbloom: Yeah, my concern would be accidentally hosing my repl in emacs because of it

13:00 bbloom: seangrov`: it's worked flawlessly for me for months with vim-fireplace

13:01 seangrov`: bbloom: Emacs struggles with large text in nrepl/cider buffers, biggest source of emacs crashes for me

13:01 bbloom: :-/

13:01 tbaldrid_: +1 I hate working in emacs for that reason

13:01 didn't seem to be an issue until the cider switch

13:02 tbaldridge: not sure what changed when that update happened.

13:02 technomancy: I'm still on 0.5.0 which is pretty stable

13:03 bbloom: tbaldridge: btw, i read the mu-karen paper & implemented it. the implementation has always made sense to me, it's the way you use it that feels weird.... the "fact" based workflow of prolog just makes more sense to me vs the "relation" workflow of kanren... but i'm still exploring

13:03 tbaldridge: bbloom: yeah, it started making a bit more sense to me when I rewrote it using lazy seqs instead of monads.

13:04 bbloom: tbaldridge: ah the good ol' list monad. really, the only one you *strictly* need :-P

13:04 so much easier to debug too b/c you can *see* how it works

13:04 i did my mukanren impl in mathematica so that i could see inside to the thunks

13:04 tbaldridge: nice

13:06 that being said, I think datalog has a more common use case: querying sets of data.

13:07 Clojure could really use a light-weight, cross-platform Datalog.

13:07 mdrogalis: +1

13:07 To some extent, didn't DataScript accomplish that?

13:07 tbaldridge: mdrogalis: to some extent, although last I looked, their query language wasn't exactly fast

13:08 mdrogalis: tbaldridge: Ah, I didn't dig into it.

13:52 i-blis: if I ((juxt keys vals) m), is there any guarantee that keys and vals will be in order?

13:52 or should I better opt for a safer (apply map vector m)?

13:53 mthvedt: i-blis: probably yes, but map has no ordering guarantees

13:53 joegallo: keys and vals are in the same order, yes

13:53 bbloom: keys & vals are documented to match seq

13:53 (doc keys)

13:53 clojurebot: "([map]); Returns a sequence of the map's keys, in the same order as (seq map)."

13:53 bbloom: (doc vals)

13:53 clojurebot: "([map]); Returns a sequence of the map's values, in the same order as (seq map)."

13:53 mthvedt: bbloom: that's interesting i didn't know that

13:53 that is stronger than java.lang.map

13:54 i-blis: oh, thanks

13:54 bbloom: but the map seq itself already returns vector-like key entries

13:54 ,(seq {:x 1 :y 2})

13:54 clojurebot: ([:y 2] [:x 1])

13:54 bbloom: ,(map vec {:x 1 :y 2}) ; for true vectors

13:54 clojurebot: ([:y 2] [:x 1])

13:54 stuartsierra: In general, anything returning a sequence will return a consistent order for the same input.

13:54 i-blis: yep, thsi is why i did not seq before the map

13:58 thanks :)

14:04 ahoenigmann: 15

14:04 amalloy: oh nice, bbloom, i didn't realize that had finally gotten documented

14:04 as of this february, apparently

14:05 ahoenigmann: I need a environment for clojure

14:06 justin_smith: ahoenigmann: what kind of environment?

14:06 ahoenigmann: well I know emacs

14:07 so I need to know what tools to go setup for a clojure development environment?

14:07 justin_smith: than you are in luck, integration with emacs is pretty good

14:07 you should definitely be using lein

14:07 and then, you should find a recent stable version of cider

14:07 arrdem: pshaw stable

14:07 justin_smith: I think cider also needs a clj plugin lib to be in your ~/.lein/profiles.clj

14:08 arrdem: I'm not trying to destroy this person's sanity

14:08 arrdem: justin_smith: he used emacs before clojure. I argue I'm not destroying anything.

14:10 justin_smith: ahoenigmann: anyway, there is lein (definitely use) and cider (depends on how brave you are / how willing you are to fiddle with broken things, how recent a version of that to use)

14:12 arrdem: cider is usable... if your definition of usable means you do daily system snapshots before and after a package upgrade in case today's top of tree is horked.

14:12 after several months of cider usage there've only been one or two days when it was totally horked and I had to roll back

14:12 technomancy: if you want something stable you can stick with nrepl.el

14:13 arrdem: or join Bronsa in the slime users club

14:13 amalloy: i will become a cider contributor just to sneak an rm -rf into arrdem's emacs

14:13 technomancy: the one upside of the gratuitous rename shuffle: nrepl.el isn't gonna break

14:14 llasram: Man, #clojure has gotten cantankerous

14:14 Well, or maybe just curmudgeonly

14:15 * arrdem isn't sure he's old enough to curmudgeon correctly

14:15 amalloy: sounds like someone has a case of the mondays!

14:15 llasram: hah

14:16 cminus: What library are folks using for async http that plays nice with core.async?

14:16 justin_smith: yeah, I still use nrepl, one of these days I will find and switch to a stable cider version (if such a thing is available)

14:17 llasram: I've been on 0.5.0 (from marmalade) for a while, and its been totally fine

14:17 arrdem: upsides of using cider: in addition to amalloy's attempts at sabotage, you get cool new features like M-x cider-grimoire :P

14:18 technomancy: arrdem: which totally shouldn't be hard-coded into cider =

14:18 =\

14:19 arrdem: technomancy: meh... I can see an argument that cider-grimoire or cider-clojuredocs should be packages rather than making cider monolithic

14:19 technomancy: arrdem: especially with cider's stability track record

14:20 if you want a new grimoire feature, do you really want to spin the Wheel of Batsov to risk upgrading the whole lib?

14:20 * arrdem shrugs

14:20 bridgethillyer: Is there a canonical reference for how to get setup for Clojure development with emacs?

14:20 justin_smith: technomancy: that sounds like a really scary game show

14:20 bridgethillyer: That is a rhetorical question I just asked.

14:20 technomancy: bridgethillyer: the one on clojure-doc.org was good last I checked

14:20 justin_smith: technomancy: it's time for... WHEEL! OF! BATSOV!

14:20 arrdem: technomancy: I woke up to find the wheel had spun itself and landed on "new cool feature" rather than "rm -rf --no-preserve-root /"

14:21 bridgethillyer: Emacs for Clojure Development: http://clojure-doc.org/articles/tutorials/emacs.html

14:22 martinklepsch: are there any great starting templates for Clojure+Clojurescript apps?

14:22 I know Luminus but I assume there might be others

14:28 bridgethillyer: martinklepsch: what do you mean by template? project template? or tutorial? or libraries? or?

14:28 martinklepsch: bridgethillyer: project template

14:28 this looks neat as well, super minimal: https://github.com/konrad-garus/cljs-kickoff

14:31 bridgethillyer: How about mies or cljs-webapp? I have no idea myself. I have not used any of them.

14:31 ahoenigmann: hmm

14:32 does cider have paredit?

14:33 martinklepsch: ahoenigmann: nope

14:33 ahoenigmann: oh cider is just the repl

14:33 martinklepsch: ahoenigmann: nrepl integration, yes

14:33 technomancy: you can turn paredit on for cider

14:33 it's just a minor-mode

14:42 ahoenigmann: whats best online resource for learning clojure?

14:43 technomancy: this IRC channel

14:43 ahoenigmann: :)

14:43 my first project tail/parse a log file

14:44 nullptr: ahoenigmann: there are many answers to that question, here is one: http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome

14:47 bridgethillyer: I really like aphyr’s Clojure from the Ground Up

14:47 ahoenigmann: thanks

14:47 amalloy: i'll let him know, bridgethillyer

14:47 bridgethillyer: But I also really like nonrecursive’s Clojure for the Brave and True http://www.braveclojure.com/

14:48 :) Oh, he knows how I feel about it.

14:49 And, goes without saying, 4clojure is the best for practicing basic Clojure skills

14:50 pbalduino: bridgethillyer: agreed

14:50 hi there. I have a doubt about gen-class. I'm using inside lein repl and nothing happens.

14:50 hiredman: ,(doc gen-class)

14:50 clojurebot: "([& options]); When compiling, generates compiled bytecode for a class with the given package-qualified :name (which, as all names in these parameters, can be a string or symbol), and writes the .class file to the *compile-path* directory. When not compiling, does nothing. The gen-class construct contains no implementation, as the implementation will be dynamically sought by the generated class i...

14:50 hiredman: "When not compiling, does nothing.

14:50 "

14:50 that should really say "when not aot compiling" but whatever

14:51 pbalduino: "When not compiling, does nothing."

14:51 hiredman: and how could I enable "aot compiling" inside repl? I'm following these: https://kotka.de/blog/2010/02/gen-class_how_it_works_and_how_to_use_it.html

14:51 justin_smith: hiredman: yeah, I was gonna say "wait, isn't every clojure form compled?". When aot makes it much more clear

14:51 pbalduino: aot inside a repl is not a thing

14:52 pbalduino: ouch

14:53 hiredman: clojure at one time had something like gen-class that would let you generate classes whenever like that, but there are all kinds of classloader/visibility issues with that

14:53 pbalduino: justin_smith: I'm trying to explain java interop using the REPL, and gen-class is the next step. so to work I would need to create a project and compile calling the app?

14:54 hiredman: so (gen-class) is deprecated nowadays?

14:54 hiredman: how is gen-class the next step?

14:54 justin_smith: pbalduino: not sure - I haven't tried gen class outside of fully aot compiled projects, because I only need the aot-only features when java needs to access my stuff

14:54 hiredman: pbalduino: it isn't deprecated, it just isn't used much

14:54 technomancy: justin_smith: it's technically possible, just a bad idea

14:54 rhg135: proxy if you're extending

14:54 idk

14:55 java does have a framework for thi s i believe

14:55 justin_smith: pbalduino: maybe I can express that more clearly: if you need the things that gen-class provides, that likely means java is using your .class files, which probably means aot at product packaging time

14:56 s/product/project

14:56 in my experience at least

14:56 pbalduino: justin_smith: in my tiny experience, I think so

14:59 rhg135: doesn't deftype generate a class at runtime?

15:00 justin_smith: rhg135: yes, but there are things gen-class does that deftype cannot

15:01 llasram: Yes. And it's actually possible to wire up the same dynamic class loader plumbing to gen-class. I actually wrote a tiny library which does that: https://github.com/llasram/shady

15:01 The fact that clojure.core didn't bother is another reason to consider it semi-deprecated/largely-unused

15:02 rhg135: justin_smith, i know i meant like llasram did

15:02 hacking it into gen-class

15:05 Raynes: tbaldridge: arrdem requested your presence for unknown reasons, hence the invite.

15:06 gooc: hello, anyone free to answer a quick clojure question?

15:06 llasram: ~anyone

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

15:06 mi6x3m-alt: hey clojure, do you respect 80 chars boundary?

15:07 gooc: Why are clojure programmers such pussies compared to python programmers?

15:07 llasram: Wow. It must be the trolling hour

15:07 mi6x3m-alt: Go go go

15:07 rhg135: hmm smells troll-like

15:11 schmee: can a multimethod dispatch based on a string passed to it?

15:11 I want to use something like that to handle user input

15:11 rhg135: yes

15:11 on anything really

15:12 schmee: I've been experimenting in the REPL but I can't figure out the correct way to write it

15:12 amalloy: (defmulti handle-input [command & opts] command) (defmethod handle-input "quit" [& args] (System/exit 0)) (handle-input "quit" "now")

15:12 mi6x3m-alt: schmee: what?

15:13 rhg135: (defmulti on-hi (fn [s] (= "hi" s)))

15:13 pbalduino: thank you

15:13 rhg135: amalloy, i forgot it could dispath on strings lol

15:14 cbp: I have an emacs thingy that paints text red when it goes over 80 columns but I sometimes ignore it

15:14 It might be whitespace.el or something

15:14 schmee: amalloy: when I type (defmulti handle-input [command & opts] command) in the REPL I get "Exception The syntax for defmulti has changed. Example: (defmulti name dispatch-fn :default dispatch-value)"

15:14 amalloy: rhg135: that defmulti example you gave is like super-awful, it's not a multimethod at all, but an if statement in a big floofy dress

15:15 oh, ugh. it's (defmulti handle-input (fn [command & opts] command))

15:15 cbp: (defmethod foo [s] (cond (= s "hi") ..)) ; eheheh

15:15 rhg135: amontalenti, i haven't written clo‌jure in months

15:15 amalloy,

15:16 darn tab

15:16 amalloy: rhg135: it's the fanciest name anyone's called me in months

15:16 cbp: I can never remember the correct syntax the first time

15:16 rhg135: i'm practically shaking from clojure withdrawl by now

15:17 schmee: amalloy: (handle-input "quit" "now") <-- is the `now` in here necessary?

15:17 amalloy: try it and see

15:19 schmee: Any idea why this won't work? (defmulti tester (fn [command] command)) (defmethod tester "quit" [_] (println "quitting!")) (tester "quit")

15:20 rhg135: idk

15:20 amalloy: it would work fine, except multimethods have this awful "feature" where if you try to change the dispatch function of an existing multifn nothing happens

15:20 rhg135: also use identity as a dispatch fn

15:21 amalloy: you have to def the multifn as nil in between, or reload your repl or whatever

15:21 cbp: use (def tester nil) before modifying and recompiling a multimethod

15:21 jeremyheiler: amalloy: are you implying that is desired? i've always felt that was a short coming

15:21 schmee: amalloy: haha wow, that is indeed aweful

15:22 amalloy: jeremyheiler: it's on purpose for sure. the alternative is not very nice either

15:22 schmee: amalloy: REPL restart did the trick, thanks a lot for the help!

15:22 rhg135: like so? (defmulti tester identity

15:22 )

15:22 jeremyheiler: amalloy: the alternative being a set-dispatch-fn fn?

15:23 rhg135: schmee, yup

15:23 jeremyheiler: therefore making it mutable

15:23 amalloy: suppose i have a defmulti using some dispatch function in ns A, and defmethods for it in B and C. if i redefine the dispatch function in A without reloading namespaces B and C, what happens?

15:23 rhg135: more readable imo

15:23 schmee: rhg135: absolutely, thanks!

15:23 amalloy: do those methods get thrown away? attached to the new method even though the new dispatch function would dispatch to them differently?

15:24 rhg135: amalloy, i'd think it'd get nasty in mutability-land but agree it's surprising

15:24 amalloy: obviously the existing behavior is awful, but there are no obviously non-awful behaviors available

15:25 jeremyheiler: amalloy: i see. makes sense

15:25 rhg135: imagine, you require namespace D edits dispatch fn

15:25 jeremyheiler: in general, i think it works to use a function defined with defn so you can independently reload it.

15:26 rhg135: FBBOOM,, none of your defmethods work right

15:26 schmee: man, I have this feeling that once I get used to Clojure, programming in any other language is going to suck

15:26 rhg135: schmee, ain't it the truth

15:27 although bitemyapp enjoys haskell

15:27 ahoenigmann: I setup a new project with lein following: http://clojure-doc.org/articles/tutorials/emacs.html#using-the-repl

15:27 Now when I run test with C-c ,

15:28 I get:

15:28 clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException: clojure.test.mode

15:30 hugod: Is there a pattern for providing/consuming plugin components in clojurescript? ie, I want to add library X to my dependencies, and be able to discover some function/object that X provides.

15:33 I wonder if I could do the plugin discovery in clojure, and expose this via a macro to clojurescript.

15:48 gfredericks: comparing two doubles of unknown scale is tricky

15:49 the_banksy: hey

15:50 amalloy: gfredericks: (defn compare-doubles [a b] :probably-different)

15:50 lpvb: are top level defs realized on application start

15:50 gfredericks: amalloy: aaaahh

15:50 lpvb: e.g. when is a def'd object created

15:50 gfredericks: I need to detect that 0.0903293108114148 and 0.09032931081141483 are mostly the same

15:50 the_banksy: I wonder if anybody could let me know whether it's possible to do a 'let' over the various definitions of an overloaded function?

15:51 gfredericks: the_banksy: you can let around a defn

15:51 the_banksy: the other style is more defns as helpers

15:52 amalloy: gfredericks: (defn similar-doubles? [a b] (< 5 (levenshtein (str a) (str b))))

15:52 gfredericks: amalloy: omg

15:52 the_banksy: gfredericks: ah I see, thanks

15:52 * amalloy <= having bad ideas since 1985

15:52 jeremyheiler: (defn compare-doubles [a b] (rand-nth [1 -1]))

15:52 justin_smith: gfredericks: there is also java.lang.Math/ulp

15:53 gfredericks: ,(def x1 0.0903293108114148)

15:53 clojurebot: #'sandbox/x1

15:53 gfredericks: ,(def x2 0.09032931081141483)

15:53 clojurebot: #'sandbox/x2

15:53 gfredericks: ,[(Math/ulp x1) (Math/ulp x2)]

15:53 clojurebot: [1.3877787807814457E-17 1.3877787807814457E-17]

15:53 rhg135: amalloy, dafuq?

15:53 gfredericks: ,(= (Math/ulp x1) (Math/ulp x2))

15:53 clojurebot: true

15:54 halogenandtoast: Can anyone explain to me why nothing gets printed here? https://gist.github.com/halogenandtoast/1a4cfe9691429f1b0836

15:54 oh wait I might have an idea. idk why I’m trying to map print.

15:54 justin_smith: gfredericks: ulp can also be used to calculate the range of effectively identical values around a given value (and that is its intended usage)

15:54 gfredericks: ,(let [ulp (Math/ulp x1)] (< (Math/abs (- x1 x2)) ulp))

15:54 clojurebot: false

15:54 nkozo: halogenandtoast: map returns a lazy-sequence

15:54 gfredericks: ,(let [ulp (Math/ulp x1)] (< (Math/abs (- x1 x2)) (* 2 ulp)))

15:54 clojurebot: false

15:54 gfredericks: ,(let [ulp (Math/ulp x1)] (< (Math/abs (- x1 x2)) (* 4 ulp)))

15:54 clojurebot: true

15:55 halogenandtoast: nkozo: can you not map on a lazy sequence.

15:55 nkozo: halogenandtoast: try doing (doall (map print-card deck))

15:55 schmee: what's the best way to avoid repetition here? (f1 x) (f2 x) (f3 x)

15:55 halogenandtoast: I tried mapv still nothing

15:55 gfredericks: justin_smith: cool, thanks

15:55 schmee: juxt

15:55 schmee: now I'm using ((juxt f1 f2 f3) x)

15:55 halogenandtoast: nkozo: OOOH

15:55 Yep derp.

15:55 hiredman: amalloy: you would want to augment levenshtein distance with some notion of significance

15:55 halogenandtoast: Didn’t even try it, but I understand now.

15:55 nkozo: halogenandtoast: doall enforces "realizing" the lazy-seq returned by map

15:55 justin_smith: gfredericks: no matter what your desired equivalent range, if you want it scaled based on your input, ulp is a good starting point I think

15:56 schmee: gfredericks: nice, just wanted to check if there was a more idiomatic way

15:56 amalloy: hiredman: i was hoping nobody would treat my suggestion as having any signifigance at all

15:57 justin_smith: is that a rimshot I hear in the distance?

15:59 halogenandtoast: nkozo: would this be more idiomatic? (doseq [card deck] (print-card card))

16:01 nkozo: halogenandtoast: I think yes

16:01 amalloy: halogenandtoast: print-card's implementation doesn't look right at all either. (5 some-vector) is not going to work

16:01 halogenandtoast: amalloy: yeah fixed it with (println (str (values (card 0)) (suits (card 1))))

16:03 amalloy: i kinda like (apply str (map get [values suits] card))

16:03 halogenandtoast: amalloy: that is neat, I don’t use apply enough.

16:13 schmee: how do I expand a macro without actually running it?

16:13 teslanick: Without running the expanded result?

16:14 verma: macroexpand/macroexpand-1/macroexpand-all

16:24 sveri: Hi, I have a vec with maps: [{:foo "f" :bar "baz"}{:foo "f2" :bar "baz2"} ...] and I know the key and value of one map :foo "f", what is the idiomatic way to get the whole map from that vec: {:foo "f" :bar "baz"}?

16:25 seangrove: bbloom: Had this linked to me on twitter, think you might be interested as well http://lambda-the-ultimate.org/node/5001

16:28 justin_smith: sveri: (first (filter (comp #(= "f" %) :foo) maps))

16:29 sveri: justin_smith: thank you, thats similar to what I came up with, I was wondering if there is a shorter way :D

16:33 AimHere: ,(some #(when (= (:foo %) "f") %) [{:a 3} {:foo "g"} {:foo "f" :bar "z"} {:x 1}])

16:33 clojurebot: {:bar "z", :foo "f"}

16:34 arrdem: lpvb: no, top level defs are realized when the containing namespace is loaded

16:34 AimHere: some (...) looks like better style to me than (first (filter ...)) but there's not much difference in size

16:34 gfredericks: holy crap these doubles have gotten quite different

16:34 I gotta multiply the ulp by 32

16:35 technomancy: double your refreshment

16:35 lpvb: arrdem: does that include when it is required by another namespace?

16:37 gfredericks: s/32/64/

16:38 arrdem: lpvb: yes, require is a wrapper over load, as is use.

16:39 sveri: AimHere: thaank you :-)

16:39 lpvb: so it will just get loaded at application start anyway because eventually require in the main namespace will load the def

16:39 arrdem: right?

16:41 arrdem: lpvb: at application start, Clojure will load only your entry namespace. In evaluating its (ns) form, it will generate (require) statements which will cause the loading and compilation of other namespace recursively until everything is loaded at which point the rest of the entry namespace will begin to evaluate.

16:42 lpvb: does that make sense?

16:42 lpvb: sounds like what I just asked o.o

16:42 gfredericks: anybody know if the transit repos accept PRs?

16:42 arrdem: lpvb: mod the detail that ns is imperative not declarative.

16:43 gfredericks: they don't appear to... bbloom tried to give dnolen a PR a while back and was turned down.

16:43 technomancy: gfredericks: your a funny guy

16:43 lpvb: so I guess if I don't want a def to run something at start I should turn it into defn

16:43 arrdem: lpvb: defn is a macro that reduces to (def .. (fn))

16:43 gfredericks: technomancy: I wasn't sure about the scope of opinions about PRs

16:43 arrdem: lpvb: using defs for load time side-effects is a no-no

16:44 gfredericks: transit-clj has a significant typo in the docstring

16:44 lpvb: well I didn't want the side effects and I think it's affecting my application

16:44 mi6x3m-alt: technomancy: any combo of run and repl?

16:44 lpvb: because right now I have a bunch of swing components and I think they're being created before my application can configure them

16:44 * technomancy blinks

16:45 arrdem: if you're using defs, then yes they will be created at load time

16:45 technomancy: mi6x3m-alt: what

16:45 justin_smith: lpvb: make an init function that creates any java class instances

16:45 lpvb: don't def to them directly

16:45 mi6x3m-alt: technomancy: lein run+repl, something that launches the program and runs a repl

16:45 gfredericks: I'm gonna just try it

16:45 lpvb: justin_smith: are you implying to do it indirectly?

16:46 justin_smith: lpvb: by wrapping class instantiation in an init funciton, you can decide when it happens

16:46 lpvb: justin_smith: (def my-frame (init JFrame. args))

16:46 technomancy: mi6x3m-alt: probably best to embed an nrepl server in your -main method

16:46 gfredericks: any bets about how it gets handled? https://github.com/cognitect/transit-clj/pull/13

16:46 justin_smith: (def my-frame (atom nil)) (defn init [] (reset! my-frame (init JFrame. args)))

16:47 lpvb: you want to be able to control when that class is instantiated

16:47 lpvb: okay

16:47 justin_smith: another unrelated question, is using reset! safe, even though it doesnt compare the previous value?

16:48 mi6x3m-alt: technomancy: thanks :)

16:48 technomancy: mi6x3m-alt: you could make a profile that puts an :injections entry that runs a namespace too and repl in that

16:48 justin_smith: lpvb: you could use swap! and either return the old value (if not nil) or create a new value - it depends if your initialization is thread safe / guaranteed to only be invoked once

16:49 gfredericks: welp that answers that

16:49 lpvb: justin_smith: so reset! isn't safe for mutating the atom repeatedly?

16:49 technomancy: gfredericks: we don't "accept" PRs

16:49 akhudek: has anyone dealt with permgen leaks? I’m seeing a lot of “Loaded sun.reflect.GeneratedConstructorAccessor121 from __JVM_DefineClass__ “ that never seem to be unloaded. Trying to figure out where to lay the blame here. Could proxy cause these?

16:49 gfredericks: they made the change and now alex gets the internet points for it :)

16:49 justin_smith: lpvb: the pattern I generally use is have an init function in any ns that needs a singleton class instance, and then call the init functions once in my top level ns, (in its one time init function)

16:49 gfredericks: technomancy: this is an exciting new win-win way of engaging the community

16:50 justin_smith: lpvb: the atom / reset! is an implementation detail, it's not really the core thing here. The important thing is to have an init function that binds any singleton class instance your namespaces use, and to ideally have just one place where that is called

16:51 lpvb: and you can bind that to a def or a reference type inside a def or whatever makes sense in your code, at runtime

16:51 lpvb: justin_smith: yeah I understand the init thing, I'm just confused by reset! separately idk if it's safe to use or not

16:51 in other purposes

16:52 akhudek: hmm, maybe it was visualvm

16:52 gfredericks: does this mean they don't accept changes at all or do they have a jira somewhere

16:52 schmee: is it possible to write a macro so that instead of (with-open [socket (Socket. "localhost" 8888)]

16:52 (connect socket user)

16:52 ) I can write (with-socket (connect socket user))?

16:52 gah sorry for multiline

16:53 justin_smith: lpvb: I only use reset! if I know I won't care about a previous value. In this example it was easier to use reset! but likely you would want a swap! that checks for an old binding and just returns that if you have any suspicion init would be called one too many times

16:53 gfredericks: oh I see it's in the README

16:54 "Because transit is incorporated into products and client projects, we prefer to do development internally and are not accepting pull requests or patches."

16:54 seems fair I guess

16:55 might be the kind of situation where a community fork could do okay if needed

16:56 lpvb: why isn't there a function for atoms called set! that regards the current val? seems like indirection to try to mutate an atom with functions only

16:56 halogenandtoast: If anyone is interested, here’s a program that deals out 4 poker hands and then prints what the highest hand value they have is (royal flush, straight, etc.): https://gist.github.com/halogenandtoast/1a4cfe9691429f1b0836

16:56 feedback welcome of course :p

16:56 cbp: lpvb: reset!

16:56 lpvb: yea but I get the feeling it's unsafe?

16:56 cbp: lpvb: if by regards you mean disregards

16:57 gfredericks: lpvb: the point is that if you're using reset! from multiple threads it's inherently racey; but if your particular use doesn't care about that then it's fine

16:57 lpvb: or actually maybe a better question is what's the point of compare-and-set!, what purpose would comparing serve

16:58 gfredericks: lpvb: what if you were using an atom for a counter

16:58 ,(def request-count (atom 0))

16:58 clojurebot: #'sandbox/request-count

16:58 gfredericks: ,(swap! request-count inc)

16:58 clojurebot: 1

16:58 gfredericks: ^ you wouldn't want to use reset! for that if there was any concurrent use

16:58 cbp: lpvb: to be thread-safe

16:59 gfredericks: and (reset! request-count (inc @request-count)) is harder to write anyhow

16:59 so the "indirection" can often be more straightforward

16:59 cbp: or uh atomic rather

17:00 lpvb: let's say the atom represents a random number

17:00 ,(def random-num (atom 4))

17:00 clojurebot: #'sandbox/random-num

17:00 arrdem: gfredericks: I don't think that's an atomic transaction... which (swap! inc) would be

17:00 lpvb: ,(compare-and-set! @random-num 8)

17:00 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core/compare-and-set!>

17:00 amalloy: justin_smith: (comp #(= % "f") :foo) is kinda weird - either (comp #{"f"} :foo) or #(= "f" (:foo %)) would make more sense

17:00 lpvb: ,(compare-and-set! @random-num 4 8)

17:00 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.Atom>

17:00 lpvb: erm

17:00 gfredericks: arrdem: yes that was my point?

17:00 lpvb: ,(compare-and-set! random-num 4 8)

17:00 clojurebot: true

17:01 lpvb: sorry about that

17:01 arrdem: gfredericks: sorry missed that bit.

17:01 lpvb: why not a function ,(defn set! [atomic new-val] (compare-and-set! atomic @atomic newval))

17:02 gfredericks: lpvb: if the successive values of a reference are independent of the previous values, then the update function isn't very useful, but there's also limited use for that due to the raceiness

17:02 lpvb: what's the advantage of that over reset?

17:02 lpvb: I don't know, compare-and-set! does a compare and reset! doesn't

17:03 but I fail to see beyond that

17:03 gfredericks: all that compare does is slow you down

17:03 no wait

17:03 I guess it fails to set the value sometimes

17:03 which is a strange thing to want

17:03 (defn set! "fails if somebody else updates the atom at just the right instant" ...)

17:04 lpvb: oh

17:05 gfredericks: then atoms to me seem like not something you use to replace mutable state, it's purity in disguise

17:06 because the current value of the atom is continually fed through a linear chain of functions

17:06 to set the new val of the atom

17:06 gfredericks: lpvb: it's definitely mutation...but the big idea is having a singular reference to immutable values

17:06 amalloy: well yeah. that's the point. it's mutable state but without the part where everything explodes if two threads race

17:06 gfredericks: rather than having a large structure that can have different parts mutated individually

17:07 like a generic collection or a classic OO bean thing

17:07 lpvb: amalloy: well then I've been using it for the wrong purpose :(

17:09 gfredericks: what purpose?

17:10 lpvb: a bunch of reset!'s everywhere trying to use it like a global mutable variable

17:13 halogenandtoast: Is there any way to make this look more sane? (= 2 (count (filter #(= 2 (count %)) (partition-by first (sort-by first hand)))))

17:14 gfredericks: lpvb: well it works okay like that if that's what you need; the question is if you actually need that ;-)

17:14 I think when clojure programmers want a global mutable variable, they use atoms

17:15 amalloy: halogenandtoast: you're trying to detect two pair?

17:15 halogenandtoast: amalloy: yes

17:16 amalloy: (= [1 2 2] (sort (vals (frequencies (map first hand))))) maybe?

17:17 halogenandtoast: interesting… not sure if that is better, but it’s neat to see another solution using frequencies.

17:18 It’s at least less verbose.

17:21 gfredericks: (->> hand (map first) frequencies vals sort (= [1 2 2]))

17:24 halogenandtoast: gfredericks: I’m thinking maybe I should write some function composition instead of the thread-last macro.

17:24 amalloy: gfredericks: blech. it's arguably easier to read as like... (= [1 2 2] (->> (frequencies (map first hand)) (vals) (sort)))), but the fully arrowed version is no fun at all

17:25 halogenandtoast: I use (partition-by first (sort-by first hand)) in a couple of places so it seems like a good opportunity for composition.

17:25 gfredericks: amalloy: it's = at the end of arrows that you hate?

17:32 amalloy: gfredericks: no, i just like the important/interesting stuff at the beginning, where it's easy to see, and the boring stuff at the end so you can gloss over it while reading

17:32 here, we're looking at the frequencies of the first cards, and we want them to be 1 2 2. sorting and calling vals are just details

17:33 halogenandtoast: amalloy: I kept the original but extracted methods. Now looks like: (= 2 (count (groups-of-size 2 hand)))

17:33 amalloy: (whereas comparing to [1 2 2], calling frequencies, and mapping first over the hand are all *not* details, but the key point of what we're doing)

17:35 gfredericks: amalloy: INTERESTING

17:36 amalloy: gfredericks: to me the real value of ->/->> is not reducing nesting, which is pretty boring, but letting you reorder things in an articulate way

17:37 hlship: I agree, threading macros make it easy to see the flow

17:37 much easier than parsing deeply nested function calls

17:37 technomancy: they *can* make it easier to see the flow

17:37 amalloy: hlship: you are saying the opposite of what i just said. which is fine, i guess, but you said "i agree"

17:37 technomancy: if they're not used indiscriminately

17:38 nullptr: threading macros are all fun and games until you need a parallel trystero furcula

17:38 hlship: the flow which is explicit and convinient for the reader is not the flow that is readable for the programmer

17:38 not for me, anyway

17:44 turbofail: hm. i actually kind of like having the important stuff at the end

17:44 usually when reading i just assume the stuff at the top is just preliminary setup

17:46 also if you want to get really silly, you could do (-> (map first hand) frequencies vals frequencies (get 2 0) (= 2))

17:48 halogenandtoast: I’d like to avoid silly :p

17:49 hyPiRion: psh

17:49 silly is what this stuff is for

17:49 (-> (map first hand) sort (partition 2 1) (filter (partial apply =)) distinct count (= 2))

17:51 This also returns true if you have three of the same card as well, but I'd argue you technically have two pairs if you have a full house.

17:52 halogenandtoast: hyPiRion: You could argue you have 3 pairs with a full house as well

17:52 1,1,1,2,2 = (1,1),1,2,2 | 1,(1,1),2,2 | 1,1,1,(2,2)

17:52 hyPiRion: halogenandtoast: Sure. And with four cards

17:53 amalloy: hyPiRion: also you got your silly arrowing wrong: (filter coll f) doesn't work well

17:53 hyPiRion: amalloy: yeah, I meant ->>

18:09 halogenandtoast: Is there a thread-first like version of cond with a binding, that may seem strange but I’l lookinf for something like (condx hand royal-flush? “royal flush” staight-flush? “straight flush” etc…)

18:09 *looking.

18:11 Oh an advanced condp would work

18:12 hyPiRion: yeah, condp surprise me with that functionality.

18:12 halogenandtoast: (condp #(%1 %2) hand …) seems like it would work

18:12 danielcompton: Is there a way to name the Clojure applications that show up in Jvisual VM? At the moment they're only distinguished by their PID

18:13 amalloy: halogenandtoast: you can also do it like (first (for [[test name] [[royal-flush? "royal flush"] ...] :when (test hand)] name))

18:15 condp is fine here, and probably better, but the pattern of looping over a seq of tests is a useful one to keep in mind

18:16 hiredman: (but for is not a loop)

18:20 amalloy: hiredman: funnily enough, neither first nor for is a loop, but using them both together is a lot like looping

18:23 halogenandtoast: amalloy: Interesting, not sure if I entirely understand it (I’ve found I often don’t understand things in the functional world until I need that solution for the first time, and then it clicks).

18:23 oh nvm I get it now.

18:23 The bindings threw me off

18:24 amalloy: Does that handle a default case?

18:25 I guess something like [(fn [hand] true) “High card”]

18:25 hiredman: amalloy: magic

18:26 amalloy: halogenandtoast: right indeed. or use (constantly true). or use (or (first (for ...)) "High card")

18:26 halogenandtoast: amalloy: oh neet, hadn’t seen constantly yet.

18:27 *neat

18:41 johnwalker: how do you handle edn's tagged literals in clojurescript?

18:42 i get errors like "Could not find tag parser"

18:54 ahoenigmann: Hi, I have emacs, cider, lein setup src compiled, and when running tests with C-c C-, I get:

18:54 CompilerException: java.lang.ClassNotFoundException: clojure.test.mode

18:55 in cider-error buffer

18:56 johnwalker: ahoenigmann: i get that sometimes too

18:56 ahoenigmann: have you tried restarting cider?

18:56 ahoenigmann: how do i do that?

18:56 johnwalker: M-x cider-restart

18:56 justin_smith: last I heard clojure-test-mode was outdated anyway

18:56 johnwalker: it's different

18:57 i don't know what the deal is ._.

18:57 technomancy: justin_smith: it's undesirable, but its replacement isn't polished.

18:57 slash finished

18:58 johnwalker: is cider test using clojure test mode?

18:58 no thats not it

18:59 ahoenigmann: that worked, but before I ran test i compiled each source and test file

18:59 johnwalker: ahh, i dont think you need to do each pair

18:59 ahoenigmann: how do you do all instead of each?

19:01 johnwalker: have you tried evaluating just one source file

19:01 and then doing cider test?

19:01 it could just be that the first namespace hasn't been evaluated

19:02 (speculation)

19:09 ahoenigmann: hmm I’ll try that next time i restart

19:38 danielcompton: What's a guy got to do to get a new version of Clojure.java.jmx released? Last release was in Feb 2012

19:39 TEttinger: danielcompton: a guy could got to release a new version to clojars

19:40 danielcompton: TEttinger: fork it and publish under my own clojars account?

19:40 arrdem: when all else fails fork...

19:41 TEttinger: if the existing dev isn't working on it, you could maybe get him/her to transfer ownership to your fork

19:41 I dunno how that works

19:42 arrdem: AFAIK taking over contrib projects with inactive maintainers is an open question

19:44 danielcompton: arrdem: how do you know if a project is contrib or core?

19:44 * arrdem checks where clojure.java.jmx floats

19:45 arrdem: danielcompton: if it's in org.clojure/clojure it's in core and it's probably frozen for eternity

19:45 danielcompton: I can't add anything more useful than checking the source unfortunately.

19:46 danielcompton: arrdem: thought that might have been the case.

19:46 arrdem: Frozen but not the good one

19:47 arrdem: heh

19:47 technomancy: clojurebot: let it go. let it goooooooooooo.

19:47 clojurebot: Gabh mo leithscéal?

19:48 danielcompton: arrdem: think I'll vendor the bug fixed function for now and cry myself to sleep tonight

19:49 TEttinger: let?

19:49 clojurebot: let is creating a local binding in your lexical scope

19:50 arrdem: idk why yall like this ice wielder... http://imgur.com/SFyQ18g

20:28 johnwalker: wow sente is really confusing me

20:28 has anyone used it with tagged edn?

20:29 it appears to have zero tests, so it wouldn't surprise me if it were broken for tags

21:00 TEttinger: this was posted in #scala , thought it should be mentioned here http://blog.ontoillogical.com/blog/2014/07/28/how-to-take-over-any-java-developer/

21:03 technomancy: discussion in lein issue tracker https://github.com/technomancy/leiningen/issues/1604

21:03 hiredman: it was sort of a center piece of technomancy's conj talk 2 years ago

21:06 (was two? maybe 1.5)

21:06 johnwalker: is there an easy way to strip the tags out of edn?

21:06 i'm trying to isolate a bug

21:08 TEttinger: the easiest way would be having a copy of clojure's repos on maven central on clojars, no?

21:09 talios: run a local nexus

21:09 technomancy: yeah, you have to run your own nexus

21:09 talios: which is a wise idea anyway.

21:10 technomancy: depends on the context

21:10 it's a terrible idea to make it impossible for freelance OSS devs to responsibly develop clojure without setting up a remote server somewhere

21:11 talios: well true. but for a company who wants to like, release artifacts to use in multiple projects - they _need_ some repo server somwhere.

21:11 technomancy: not really true

21:11 you can use S3 if you don't want to run a server

21:12 talios: thats still something serving a "repo" tho.

21:12 but yes

21:12 technomancy: depends how pedantic you want to be I guess =)

21:13 talios: I think I've been podcasting with burngreg to much, the pedantry is wearing off :)

21:16 OlegYch: isn't sonatype repo mirroring central?

21:23 talios: nope - given central feeds from oss.sonatype that would circular.

21:28 one work around for the SSL issue would be including SHA1 hashes for each dep to check against. I know buck does that, but there's no way in Maven to (currently) do that. And its quite anal, and prone to breaking if you use version ranges - unless a plugin/mojo used a separate SHA1 verification service (via https ) to build a local index

21:58 arrdem: or you could just use Namecoin or some equivalent scheme for solving the public key distribution and verification problem then just digitally sign all artifacts rendering this moot... see technomancy's comment on the HN thread about why lein enforces signatures.

21:59 talios: do you have a link to the HN thread?

21:59 arrdem: https://news.ycombinator.com/item?id=8099713

21:59 talios: got it :)

21:59 arrdem: lolfrontpage

21:59 talios: top story :)

21:59 arrdem: tech is the third comment :P

22:01 talios: yep - oss.sonatype.org requires all artifacts to be gpg signed already before syncing. but thats more about who uploaded the artifact, and tracing that.

22:01 doesn't prevent someone uploading infected artifacts which are -also- signed.

22:02 but would go to prevent man in the middles

22:02 I should raise this on this weeks Maven Dev Hangout.

22:03 they do have one major problem that clojars doesn't tho. clojars is a tiny tiny repository. central is.... a behemoth. old artifacts remain without signage, and with security holes.

22:04 arrdem: talios: ur blag iz down

22:04 talios: poop - is twitter still refering to talios.com? try http://www.theoryinpractice.net/

22:04 arrdem: talios: your github still links there too

22:04 talios: I should put a redirect

22:04 doh

22:04 arrdem: also welcome to my bbdb of Clojure users

22:05 * talios updates

22:06 talios: to be honest I've not actually touched real clojure code in a long time. starting again, mostly since I forked clojure and put an OSGi'ified version in central.

22:08 arrdem: what does having a bundled version of core buy you?

22:08 the ability to inject a REPL with good JVM interop/introspection?

22:09 justin_smith: arrdem: I would assume the desire to have OSGi compatible classloader control

22:09 talios: more its an core with OSGi exports, and a support library for looking up/registering services. I just adopted the long abandoned project and brought it up to date with 1.6

22:10 I need to find some time to blog about it.

22:10 arrdem: this is way more heavyweight Java architecture than I've worked with before so I'll just nod my head...

22:11 talios: ideally you'd just have a super lite clojure app, but our core main system is all OSGi, and replacing the whole thing would be.... difficult.

22:11 justin_smith: talios: so is it true that via OSGi you could have separate classloaders with separate (otherwise conflicting) versions of classes?

22:11 talios: yep

22:12 my bundle embeds all the clojure libs, and nothing outside of it can see those classes, they might even have their own version.

22:12 justin_smith: so you could have a standing naked jvm+clojure left running, and then via some utility have it load the deps in your project.clj for short startup time...

22:13 talios: so what would you use this invisible set of clojure libs for?

22:14 talios: they're invisible to the "outside world", not to the bundle using them. so, theres an http service from OSGi that I can hook into to register a servlet, using clojure and clojure libs, but no one else can see any of that.

22:14 gives isolation.

22:14 improved release cadence, modularity.

22:14 justin_smith: ahh

22:14 right

22:15 so within one jvm running OSGi, you could have multiple clojure projects running, potentially each having their own version of clojure

22:17 talios: in theory yes.

22:18 I probably wouldn't go that route just for that tho.

22:19 justin_smith: yeah, seems like a good way to find jvm / osgi bugs

22:19 and you could just have a vm per project for better isolation

22:53 jeremyheiler: ,{}

22:53 clojurebot: {}

22:53 jeremyheiler: ,(let [a {}])

22:53 clojurebot: nil

22:53 jeremyheiler: ,(def a {})

22:53 clojurebot: #'sandbox/a

22:53 jeremyheiler: ,a

22:53 clojurebot: {}

22:57 literater: (-> 1 + + +) = 1, but (apply -> [1 + + +]) is a compilerexception. any way to do what i want? (thread a list of functions?)

22:58 gws: ,((comp + + +) 1)

22:58 clojurebot: 1

22:58 gws: like that?

22:59 literater: ,((apply comp [+ + +]) 1)

22:59 clojurebot: 1

22:59 literater: yes, exactly! thanks (:

22:59 clojurebot: No entiendo

22:59 gws: yeah!

23:00 jeremyheiler: i have this huge map of clojure data, and when i try to def it with out quoting it, i get this compiler error... what causes this?

23:00 CompilerException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentHashMap

23:00 gws: literater: hard to see in those examples because the fns are the same, but comp applies the fns right-to-left

23:00 ,(doc comp)

23:00 clojurebot: "([] [f] [f g] [f g h] [f1 f2 f3 & fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc."

23:05 gws: ,(def fail ({:foo "bar"}))

23:05 clojurebot: #<CompilerException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentHashMap, compiling:(NO_SOURCE_FILE:0:0)>

23:05 gws: jeremyheiler: could you be doing something like that? ^

23:05 jeremyheiler: ah, yes, that is likely.

23:06 the message seems a bit misleading

23:06 but i get it

23:06 TEttinger: jeremyheiler, also very large collections can't be constructed as primitives by the JVM

23:07 I generated this from a spreadsheet and it won't load, or at least won't AOT compile: https://dl.dropboxusercontent.com/u/11914692/weapons-map-too-large.clj

23:07 jeremyheiler: as primitives?

23:07 what do you mean

23:07 TEttinger: err, literals

23:07 sorry

23:07 jeremyheiler: thanks gws

23:07 TEttinger: as in with {}

23:08 that same map was successfully compiled with...

23:08 https://dl.dropboxusercontent.com/u/11914692/weapons-map.clj

23:08 jeremyheiler: TEttinger: ah, haha. do you know the max ?

23:09 TEttinger: instead of one def with about 7200 items, I did 100 defs with 72 items, then one more def that defined a hashmap of each of the previous defs to a key

23:09 justin_smith: TEttinger: I am glad yoyo is a key in that map

23:09 TEttinger: yes.

23:09 gws: jeremyheiler: np. i wasn't aware of the large collection limitation either.. The More You Know (tm)

23:11 justin_smith: TEttinger: http://www.vikingsword.com/vb/attachment.php?attachmentid=264&stc=1

23:12 arrdem: I mean... it's not large collections it's large literals

23:12 TEttinger: what is that, justin_smith??

23:12 lazybot: TEttinger: Uh, no. Why would you even ask?

23:12 justin_smith: TEttinger: a yoyo for hunting with (from the phillipines)

23:12 jeremyheiler: arrdem: right. so im guessing it's the number of method paramers that is the limitation?

23:12 methid/constructor

23:13 TEttinger: gws, yeah, the final collection was actually larger than the first one. the issue was not params but the size of the JVM instruction

23:13 gws: interesting. thanks

23:14 TEttinger: you know how in Java you declare hashmaps element-by-element? myHash.put("key", "value"); or whatever?

23:14 in clojure it tries to put the whole literal as one statement in the assembled code

23:15 arrdem: which likely blows either single method size or locals count limitations.

23:15 TEttinger: I had 100 params in one literal with bwtween 70 and 90 literals in each of those, and it encountered a hard limit

23:15 it works in the repl though

23:15 (IIRC, this was a while ago)

23:15 hiredman: it won't work in the repl with more complex expressions

23:16 the repl takes some short cuts in some places that avoids generated bytecode

23:16 but any path that results in generating bytecode that ends up having to the embed the literal map in the generated bytecode

23:22 when/if clj-701 is fixed it should be possible to split large literal construction across multiple methods easily, at which point we'll be limited by any class file size limits or method count limits instead of method size limits

23:22 technomancy: well it sounds like something side-effecty

23:22 so let's go with when

23:22 hiredman: of course if you just stick you large literal in a file and read it using the reader instead of trying to send it through the compiler it will work fine already

23:23 which is really what you should be doing anyway

23:23 technomancy: hwa

23:24 ^- the above fact is why no one who fiddles with the compiler cares much and it is unlikely to be fixed anytime soon

23:25 technomancy: it was a joke

23:25 arrdem: could probably fix it right quick in TEJVM if one so cared, just change -emit-const, but why

23:29 talios: *yay* SSL will come to central - http://maven-dev.markmail.org/thread/2gtqlgfi4uh6m6wy

23:30 or more - come to maven./

23:30 and also central

23:30 technomancy: talios: great news; thanks!

23:31 TEttinger: great talios!

23:32 talios: I never actually considered that SSL wasn't cheap/free until rather recently.

23:32 also, you needed a physical IP for the host as well to bind to from memory

23:33 oh how the interweb has changed

23:33 technomancy: talios: that's been mitigated in the past few years

23:33 https://en.wikipedia.org/wiki/Server_Name_Indication

23:35 talios: technomancy - yes. as Brian mentioned in that email, the CDN situation back in 2012 was quite different tho. and large infrastructure projects take awhile to change

23:36 technomancy: definitely; it's a much bigger job, and I don't envy them

23:36 talios: tho I would have thought something like that should have been upgradable

23:46 technomancy - and now I get pointed to http://docs.codehaus.org/display/MAVEN/Repository+Security - design ideas for improving repository security, but sadly the prototype code didn't go anywhere at the time. Now we have life back in Maven hopefully this may see more movement.

Logging service provided by n01se.net