#clojure log - Oct 05 2014

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

0:02 dbasch: amalloy: still, with an array long-to-hash only becomes 10% faster

0:07 amalloy: actually it becomes significantly faster, encode overall still takes 4x as long as the java version

0:07 amalloy: sure, but you're getting there

0:07 you should be able to get it to at most 1.5x

0:08 if you're inclined to keep pushing

0:11 dbasch: amalloy: well, I could rewrite the entire thing in java from clojure :)

0:12 the initial question was, what was the point of writing a clojure implementation of something for which there is a very performant java library

0:26 alexyz: is there a way to get from a Java array to a Clojure seq?

0:31 dbasch: alexyz: (seq the-array)

0:34 btw, if you change the-array, the seq changes so don’t do it

0:35 (the sequence is backed by the array directly)

0:36 alexyz: dbasch thanks

0:37 meanwhile I have found a "native" Clojure function so no need to convert

0:38 still reading about multimethods... if the dispatch function returns a sequence how should I define a defmethod? I've tried '("text" "html") and it doesn't seem to match --- everything going to :default

0:39 http://pastie.org/9621536

0:51 dbasch: alexyz: why do you need a multimethod there? it seems like you just want a case

0:52 amalloy: alexyz: multimethods are sneaky buggers, greatly opposed to being redefined. i bet if you (def my-multi nil) and then re-run that code it works fine

0:53 dbasch: I still think that’s an unnecessary usage of a multimethod though

0:54 alexyz: dbasch I asked earlier and was told about multimethod which seems to fit pretty well. I didn't know about case though

0:55 amalloy unfortunately I'm not following you. I have found a bug in that code though and now it seems to work fine

0:56 dbasch: or not even a case, a map would do just fine

0:57 alexyz: dbasch in what sense a map?

0:57 dbasch: alexyz: you have a mapping of mime types to titles, right?

0:58 alexyz: dbasch nope... for each mime type I plan to apply a different approach for finding out the real title

0:58 so basically it's a mapping from mime types to functions

0:58 dbasch: alexyz: ok, in that case a case

0:58 alexyz: that's why multimethods sounded like exactly what I needed

0:59 dbasch: multimethods are more useful when you have things of different types, and you don’t want to be figuring out what something is

0:59 but in your case you always have two strings

1:00 alexyz: but the processing is rather different... and this sounds a lot like polymorphism

1:01 I mean I'm pretty sure I can achieve the same results with either multimethods or a case so the real question here is more about what's the idiomatic way

1:01 dbasch: alexyz: in this situation it’s a matter of taste I guess. If you like it that way, why not

1:01 alexyz: I'll actually give it a try to both to learn how each of them feels

1:03 dbasch: I guess the other reason for multimethods is when you don’t know all your cases in advance and you want to be able to add dispatch methods without touching the existing logic

1:04 alexyz: dbasch in this particular case I thought that having the :default matcher around could prove quite useful

1:05 dbasch: alexyz: see also cond

2:13 sineer: Anyone knows how to use use .appendChild with Om dom/div ?

3:03 borkdude: bbloom what's the difference between union and sum types?

3:05 julienmarie: Hello all. I'm quite of a newbie here. I got troubles to swap! a nested atom. I feel a bit lost about it for now ( first week on clojure / clojurescript ) http://pastebin.com/bwSqBLxW .Been scratching my head for a day on that now…

3:16 borkdude: julienmarie I suggest you add a println to set-active to see what you are calling it with

3:16 julienmarie: @borkdude I'll do that

3:19 @borkdude this is what I'm getting [:menu [{:name Dashboard, :path /, :icon dashboard} {:name Analytics, :path /analytics, :icon analytics}]]

3:19 but I need to iterate under the :menu symbol

3:19 borkdude: julienmarie I suggest you now look at the update-in function

3:20 julienmarie: instead of assoc ?

3:20 borkdude: julienmarie or assoc-in

3:20 just take a look at those functions

3:23 julienmarie: @borkdude thanks!

3:24 borkdude: np

3:31 question about core.typed: when I define a function in namespace a and also have the annotation there, and this function is called from namespace b incorrectly typewise, lein typecheck a b doesn't find it

3:31 question is: what am I doing wrong

3:34 cfleming renaming via filename refactors namespaces name, but not the other way around

3:37 hmm, lein typed says: "Not checking ringapp.other (tagged :collect-only in ns metadata)"

3:37 while I called it with lein typed ringapp.api ringapp.other

4:14 H4ns: i'm using http-kit+ring+compojure and my static resources are not found. i've looked at the system class loader (java.lang.ClassLoader/getSystemClassLoader) path and found that it contains the right directories. it seems, though, that a different class loader is used.

4:14 any ideas how i could debug this further?

4:16 in fact, the context class loader path seems to not contain anything

4:23 apparently, a restart of my application helped with this.

5:14 cfleming: borkdude: Yeah, there's a few cases I need to fix there - the namespace code is old and crufty unfortunately

5:15 borkdude: How's the core.typed support in Cursive BTW? It's pretty new and I haven't used it in anger yet.

5:15 borkdude: I'd like to start using core.typed for some of the Cursive code but I haven't yet.

5:54 SagiCZ1: is there any way to take a string and compile it as a C code in java?

5:55 martinklepsch: I just wrote a bit of code that feels complicated, would be happy if someone could take a look: https://gist.github.com/mklappstuhl/60b061d749f0c0c12275

5:59 dysfun: Hi. what interface do i have to implement to support conj?

6:00 SagiCZ1: dysfun: Sequential?

6:00 dysfun: tuy

6:36 is there a nice clojurescript dom library that might work under clojure with a webkit open?

6:37 the api is basically the same

6:42 dommy looks interesting. i'm not sure if i approve or disapprove of the gross abuse of macros in that way

6:48 mbac: how do i make a plot of a sequence of [x y] appear on my screen with minimum effort

6:48 (clojure.magic/plot data) isn't working :P

6:49 is it loom?

6:50 borkdude: cfleming I have the following issue with core.typed in general now: https://www.refheap.com/91197

6:50 cfleming it's not entirely clear what happens when you just check 1 ns... what happens if the annotations are in another namespace? or when annotations are in "this" namespace, but calls in another?

6:51 cfleming: borkdude: Hmm, interesting - I'm not sure, I must admit. I implemented the Cursive support modelling it on the calls that the Emacs/Vim support makes, but like I say I still haven't used it myself other than to test it.

6:52 borkdude: So I'm still not sure about a lot of the core.typed details.

6:52 borkdude: cfleming me neither. I started using it because it was present in the REPL menu :)

6:52 cfleming: borkdude: Haha - so you'll try all the libraries I add support for?

6:52 borkdude: cfleming maybe

6:53 cfleming if I get a free license :P

6:53 cfleming: borkdude: I'll run it by my CFO

6:54 borkdude: cfleming how big is your team/company?

6:54 cfleming I thought you were the only one

6:54 cfleming: borkdude: It's just me.

6:54 borkdude: hehe ok

6:54 cfleming: borkdude: My CFO is either me, or my wife

6:54 borkdude: cfleming lol ok.

6:57 cfleming I actually had a use case for core.type to find possible null pointers in some code which uses bigints extensively, but until I can work this namespace problem out, it won't be of much use

6:57 cfleming it's more a core.typed thing than cursive

6:57 cfleming: borkdude: Try the core.typed mailing list, ambrosebs is very responsive on there

6:57 borkdude: When he's not around here, that is.

6:58 borkdude: cfleming I already pinged him on twitter, so I think he'll respond soon

6:58 cfleming: borkdude: Ok cool

7:00 borkdude: Speaking of null pointers, check this out: http://t.co/qTbnjiXwpg

7:01 borkdude: cfleming yeah, I saw it via your twitter

7:01 cfleming: borkdude: I have a total geek crush on jetbrains

7:02 dysfun: that is pretty cool

7:02 shame i hate IDEs

7:02 cfleming: dysfun: That is a shame :-)

7:03 borkdude: cfleming do I understand correctly you would have to add annotations in order for it to detect possible NPEs?

7:03 it's still cool though

7:04 cfleming: borkdude: No, they've had that for ages. This infers what and where the annotations should be.

7:04 borkdude: Depending on how well it works, it might completely eliminate NPEs in Java

7:06 borkdude: cfleming so you have a program in java with possible NPEs, intellij warns that you should add annotations?

7:09 mbac: oh wait maybe it's incanter

7:09 borkdude: cfleming "infer annotations" means you wouldn't have to add them, so why speak of annotations - isn't that more of an implementation detail?

7:09 mbac: wait maybe i should just write text to a file and use gnuplot

7:11 cfleming: borkdude: Right, that's a little confusing, I think they're talking about what their algorithm actually infers. As I understand it it'll infer what those annotations should be in SDK/library code.

7:11 borkdude: I'm assuming it can also tell you where they should go in your own code.

7:12 borkdude: I'm guessing this analysis is independent of the actual NPE checking

7:13 borkdude: But if it can use the inferred ones, you're right, the annotations themselves become a little redundant except as documentation.

7:21 mbac: i find myself doing (map (fn [i x] [i x]) (range (count xs)) xs) a lot

7:21 is there something more idiomatic

7:21 Bronsa: ,(map-indexed vector '[a b c])

7:22 clojurebot: ([0 a] [1 b] [2 c])

7:22 Bronsa: mbac: ^

7:23 mbac: thank you!

8:03 clj-learner: whats the difference between (resolve 'first) and #'first

8:18 dysfun: oh excellent, i made java segfault

8:21 rweir: gold star!

8:21 unless it involved JNI

8:25 dysfun: well, only JNI written by oracle

8:25 (javafx)

8:25 rweir: silver star then ;p

8:25 dysfun: javafx is certainly interesting

8:26 i had no idea an api could be made this infuriating

8:26 rweir: worse than jdbc?

8:26 dysfun: but i think being able to crash a browser by loading a webpage with a simple javascript loop is quite special

8:44 gfredericks: ,`````````x

8:44 clojurebot: #<StackOverflowError java.lang.StackOverflowError>

9:36 hyPiRion: oh, you.

9:46 noncom: how do i in clojure better find the constructor for a class that I need and pass the required parameters to it? i cannot make (.getConstructors) with (.newInstance) to work with it..

9:51 gfredericks: noncom: you're asking about how to find documentation on java classes, or just call a constructor, or something else?

9:51 ,(BigInteger. "42") ;; calling a constructor

9:51 clojurebot: 42

9:53 gfredericks: ,(.newInstance BigInteger "42")

9:53 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: newInstance for class java.lang.Class>

9:53 justin_smith: dysfun: SagiCZ1: hash-maps and sets support conj but are not sequential

9:53 gfredericks: ,(.newInstance BigInteger)

9:53 clojurebot: #<InstantiationException java.lang.InstantiationException: java.math.BigInteger>

9:53 dysfun: *sigh* i wonder what we could achieve with something similar to html but with an immutable DOM

9:55 gfredericks: noncom: the docs for newInstance state that it won't work if the class doesn't have a zero-arg constructor

10:09 rubberduck: anyone familiar with core.async.impl.protocols ? in particular what's the procedure for implementing ReadPort in clojure ?

10:09 from what I can tell you get passed a handler and you must lock it then check if it's active and call commit with the value

10:10 ManyToManyChannel implementation isn't very straightforward :(

10:12 kungi: Can I somehow create a globally unique symbol?

10:13 justin_smith: ,(symbol (java.util.UUID/randomUUID))

10:13 clojurebot: #<ClassCastException java.lang.ClassCastException: java.util.UUID cannot be cast to java.lang.String>

10:13 justin_smith: err

10:13 ,(symbol (str (java.util.UUID/randomUUID)))

10:13 clojurebot: 906eafe8-36c2-4cb7-b035-65d39983413c

10:13 kungi: justin_smith: Hmm ok this is possible.

10:14 justin_smith: globally unique (or at least pretty damned close to it)

10:14 kungi: justin_smith: thanks

10:21 noncom: gfrederics: say i have a class with 2 constructors - 1) parameterless, 2) with some params. i want to be able to call the parametrized one, passing the parans

10:22 gfredericks: sorry, misspelled the nick :)

10:25 gfredericks: actually, my ultimate goal is to be able to find a class by its name, so that i use (Class/forName) and then call a parametrized constructor on it to get the instance... what would be the best approach for that ?

10:26 gfredericks: ,(.getConstructors BigInteger)

10:26 clojurebot: #<Constructor[] [Ljava.lang.reflect.Constructor;@1b91ad7>

10:26 noncom: ,(.getConstructors (Class/forName "BigInteger"))

10:26 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: BigInteger>

10:27 gfredericks: ,(map #(seq (.getParamaterTypes %)) (.getConstructors BigInteger))

10:27 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: getParamaterTypes for class java.lang.reflect.Constructor>

10:27 gfredericks: ,(map #(seq (.getParameterTypes %)) (.getConstructors BigInteger))

10:27 clojurebot: (([B) (int [B) (java.lang.String int) (java.lang.String) (int java.util.Random) ...)

10:27 noncom: hmmm... thats giving some signatures !

10:27 gfredericks: ,(def my-string-constructor (->> BigInteger (.getConstructors) (filter #(= [String] (seq (.getParameterTypes %)))) (first)))

10:27 clojurebot: #'sandbox/my-string-constructor

10:28 gfredericks: ,(.newInstance my-string-constructor (into-array ["42"])

10:28 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

10:28 gfredericks: ,(.newInstance my-string-constructor (into-array ["42"]))

10:28 clojurebot: 42

10:28 gfredericks: so that does it I think

10:28 you might also find a helper in the clojure.lang.Reflector class

10:28 or something to that effect

10:29 noncom: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Reflector.java#L150

10:29 ,(clojure.lang.Reflector/invokeConstructor BigInteger (into-array ["42"]))

10:29 clojurebot: 42

10:29 gfredericks: rather easier

10:32 noncom: gfredericks: wow!

10:32 gfredericks: that's it, thanks! :)

10:32 gfredericks: np

11:49 john________: Can ask a datomic question here?

11:50 AeroNotix_: john________: don't ask to ask, ask.

11:52 john________: I hope it is not unpolite to paste in serveral lines of a datomic query code:

11:52 [:find ?e ?name

11:52 :where

11:52 [?e :item/name ?name]

11:52 [?e :item/values ?ref]

11:52 justin_smith: use a pastebin

11:52 john________: [?ref :value/attribute ?a]

11:52 [?a :attribute/ident “12009”]

11:52 ]

11:52 justin_smith: use refheap.com next time

11:52 john________: allright thanxs I do that from now on!

11:53 justin_smith: I'm guessing you are fairly new to IRC

11:54 john________: yes! quite just used it so far only a couple of times for short questions

11:54 https://www.refheap.com/91206

11:55 justin_smith: thanks

12:04 bbloom: borkdude: i explained it to gfredericks

12:14 viktar: (+ 2 2)

12:14 clojurebot: 4

12:15 mbac: so, it's kind of a drag that for toplevel scopes you need to use def but inside of defs you need to use let

12:17 gfredericks: mbac: they're pretty different

12:19 it's not just about positioning

12:20 mbac: what's different about them?

12:20 or, rather, why would you want them to be different?

12:20 gfredericks: def is for things that can be referenced from anywhere, and they are also mutable (e.g., for code reloading)

12:20 AeroNotix_: mbac: let is scoped

12:20 gfredericks: so there's more indirection involved

12:20 mbac: can't you just think of the top-level scope as the body of function that wraps the module

12:21 AeroNotix_: mbac: def can be accessed from outside the namespace it's being defined as well

12:21 gfredericks: mbac: that kind of hand-waves around how code reloading works

12:21 mbac: oh. hmm.

12:21 justin_smith: mbac: you can't, because the body of a function is immutable, and global bindings are not

12:22 mbac: wait so (def x 0) (def y (based-on x)) (def x 1) is a thing?

12:23 justin_smith: it's terrible, but it's a thing

12:23 mbac: :'(

12:23 i guess that's super useful sometimes...

12:24 justin_smith: mostly for development workflows, but yeah, I get pretty damn suspicious when I see it being done in code

12:26 borkdude: bbloom I'll have to dig up the logs then

12:29 justin_smith: ,(name "name")

12:29 clojurebot: "name"

12:30 justin_smith: it's handy, but it surprised me

12:32 bbloom: yeah, especially because ##(keyword :keyword) doesn't work, nor does ##(symbol 'symbol)

12:32 lazybot: (keyword :keyword) ⇒ :keyword

12:32 (symbol (quote symbol)) ⇒ symbol

12:32 bbloom: oh wow, maybe it does

12:32 nevermind

12:33 &*clojure-version*

12:33 lazybot: ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}

12:33 bbloom: huh

12:35 justin_smith: ,(keyword :keyword)

12:35 clojurebot: :keyword

12:35 justin_smith: ,(symbol 'symbol)

12:35 clojurebot: symbol

12:36 justin_smith: yeah, these facts just simplified some of my code immensely

12:36 bbloom: justin_smith: oh, i remember now:

12:36 ,(symbol 'namespace 'name)

12:36 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.String>

12:36 bbloom: yeah

12:36 :-/

12:36 justin_smith: ahh

12:36 bbloom: ,(keyword 'ns 'n)

12:36 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.String>

12:36 bbloom: ,(keyword 'ns "n")

12:36 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.String>

12:36 bbloom: no good

12:37 justin_smith: luckily I don't need that version for my code

12:47 bbloom: hmm so core.async gos get GC-ed if they are waiting on channels for which nobody holds the other end... but what about threads created with clojure.core.async/thread ?

12:47 dysfun: is there anywhere i can read about things planned for future versions of clojure?

12:48 bbloom: dysfun: http://dev.clojure.org/display/design/Home

12:48 dysfun: thanks

12:56 allenj12: how does this work if conj never gets a coll? (def foo [x] (when (> x 0) (conj (foo (dec x)) x))) => (foo 5) -> (5 4 3 2 1)

12:57 gfredericks: ,(defn foo [x] (when (> x 0) (conj (foo (dec x)) x)))

12:57 clojurebot: #'sandbox/foo

12:57 gfredericks: ,(foo 5)

12:57 clojurebot: (5 4 3 2 1)

12:58 gfredericks: ,(conj nil 1)

12:58 clojurebot: (1)

12:58 gfredericks: allenj12: ^^ nil is treated as an empty collection sometimes

12:59 allenj12: gfredericks: why do i feel like thats a bad thing?

12:59 kinda goes against the philosophy nothing is nothing, an empty list is something

12:59 bbloom: allenj12: industry wide brainwashing?

13:00 i kid though, i go back and forth on my feelings about nil :-P

13:00 dysfun: because you'd like it to not error out and a lot of things that return sequences may also return nil

13:00 allenj12: eh i have mixed feelings about this aswell

13:01 bbloom: in general, clojure handles nil reasonably sanely

13:02 justin_smith: allenj12: things silently returning nil are pretty pervasive in clojure

13:02 ,(+ nil)

13:02 clojurebot: nil

13:02 justin_smith: ,(+ :a)

13:02 clojurebot: #<ClassCastException java.lang.ClassCastException: Cannot cast clojure.lang.Keyword to java.lang.Number>

13:03 bbloom: justin_smith: (+ nil) is just garbage in garbage out

13:03 + is defined for numbers only

13:03 allenj12: huh

13:03 justin_smith: sure, but notice that it catches it with :keword

13:03 but not with nil, that was my point

13:04 bbloom: justin_smith: that's b/c nil can be a Number

13:04 justin_smith: sure, the pervasiveness of nils is related to the underlying jvm

13:04 not accusing clojure here, just describing

13:04 allenj12: i see

13:06 bbloom: yeah, that's a good point: null is pervasive on the jvm already, so shouldn't fight it

13:07 justin_smith: for comparison, we can look at how scala handels it http://blog.sanaulla.info/2009/07/12/nothingness/

13:07 which to me reads like a language designed by Heidegger or something

13:09 aaelony: justin_smith: (and "being" t

13:09 justin_smith: (and "being" "time")

13:10 justin_smith: hehe

13:10 aaelony: hehe ;)

13:17 justin_smith: john_______: did you ever get any help with your datomic question

13:18 or, more to the point, did you ever actually ask it?

13:19 john_______: @justin_smith: yes but nobody answered. I asked why this query https://www.refheap.com/91206 performs so bad. I also posted a question to the datomic user group

13:20 but as always I think I just have to read and learn more about how datomic handles queries

13:46 dpathakj: ,(and “being” “time”)

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

13:46 justin_smith: dpathakj: inc clojure, smart-quotes aren't quotes

13:46 ,(and "being" "time")

13:46 clojurebot: "time"

13:47 dpathakj: Yeah. Looks like I just found out that my irc client is smart-quoting on me.

13:47 justin_smith: *in clojure

13:47 borkdude: cfleming namespaces that don't require core.typed won't be type checked

13:47 cfleming sais ambrose

13:48 john_______: justin_smith Somebody helped me on the datomic IRC thanxs alot

13:49 justin_smith: borkdude: I can see how that would be useful actually.

13:49 borkdude: justin_smith tell me

13:50 viktar: exit

13:50 justin_smith: borkdude: if I am adapting a codebase to use core.typed, that means I can work throught it one ns at a time.

13:51 borkdude: justin_smith then what is the point of calling lein typed with specific namespaces

13:51 justin_smith: borkdude: and if I have a feature that turns into a terrible rabbit hole when I try to strictly type it, I can still typecheck all the other namespaces, even if that one would never survive the check.

13:51 borkdude: sorry, I know nothing about "lein typed"

14:23 michaelr524: hey

14:24 pellis: hi all

14:24 is this the proper place for clojurescript q's?

14:24 michaelr524: here is an excersize, how would you split a constant length string to 5 parts of a given length

14:24 pellis: yeah, why not

14:25 pellis: well i just tried deep diving into om and clojurescript

14:25 given around 1 month experience with clojure (but i do learn fast)

14:25 my last clojure code was around a year ago

14:26 michaelr524: [8, 4, 4, 4, 12] <- these lengths

14:26 pellis: i came to the conclusion that i can't really do something complex - I need some background in clojurescript first.

14:26 so my question is - what would be a good place to slowly introduce clojurescript into existing javascript projects?

14:26 is that even wise?

14:27 for example - a clojurescript coffeescript hybrid ? or clojurescript on node.js?

14:28 michaelr524: pellis: i think the best way to start would be to build a clojurescript only project

14:28 justin_smith: ,,(reduce (fn [[acc s] n] [(conj acc (subs s 0 n)) (subs s n)]) [[] "this is the input string, is it long enough?"] [8 4 4 4 12])

14:28 michaelr524: pellis: why mix in javascript?

14:28 clojurebot: [["this is " "the " "inpu" "t st" "ring, is it "] "long enough?"]

14:28 justin_smith: michaelr524: see above

14:28 pellis: michaelr524: what if i feel too insecure there? should i go back to square one and invest time in learning first?

14:28 michaelr524: justin_smith: one sec, let me parse that

14:28 justin_smith: exercise for the reader: error checking for when the string runs out

14:29 michaelr524: pellis: just build one simple project in clojurescript - this should cure your problems :)

14:29 pellis: michaelr524: i can't build anything simple enough :(

14:32 michaelr524: pellis: why not?

14:33 justin_smith: cool, i like your solution

14:33 justin_smith: thanks

14:33 pellis: michaelr524: i guess i can't think simple enough. i've been doing complex problems for too long, that i consider everything trivial

14:33 justin_smith: it errors out if the input string is too short

14:33 michaelr524: justin_smith: i was thinking in the same direction actually.. but maybe there is a way to make it more efficient?

14:33 i wonder

14:34 justin_smith: more efficient? yeah, use a transient

14:34 michaelr524: justin_smith: the string will always be the same size. it's an rfc compliant uuid without the '-'s

14:34 justin_smith: error checking? maybe assert that the length of the string is longer than the sum of all the sizes, and if not, bail

14:34 michaelr524: justin_smith: i want to bring the '-' back

14:35 justin_smith: oh, never mind that part then :)

14:36 seangrove: Any way to destructure the last item in a seq?

14:36 michaelr524: justin_smith: it's kinda surprised me actually, i've never seen the acc in (reduce) abused in such a nice way :)

14:37 Bronsa: seangrove: nope

14:37 seangrove: Bronsa: Didn't think so, but thought it might be worth it to ask - thanks

14:40 justin_smith: ,(map identity (second (reduce (fn [[index acc s] n] (aset acc index (subs s 0 n)) [(inc index) acc (subs s n)]) [0 (make-array String 5) (str (java.util.UUID/randomUUID))] [9 5 5 5 12])))

14:40 clojurebot: ("d1d7a603-" "e9c3-" "4c5a-" "8b27-" "65aef1b44629")

14:41 justin_smith: the map identity is because arrays don't print very readably :)

14:41 Bronsa: seq?

14:41 takemikazuchi: Hi guys, is this a good place to ask some basic questions? I'm a little confused about string equality in Clojure.

14:41 justin_smith: Bronsa: ahh, of course :)

14:41 takemikazuchi: go for it

14:42 hiredman: yes

14:42 takemikazuchi: justin_smith: Thanks. Here's the gist: https://gist.github.com/Takemikazuchi/04d2db23a0d6437296c9

14:42 michaelr524: justin_smith: nice.. but think further about it, i think i'll just maybe go for the crazy stupid solution and concat the result of 5 (subs) :)

14:43 takemikazuchi: I mean this works like I expect: ,(= "E" (clojure.string/capitalize "E"))

14:43 But the behavior changes when I'm iterating over a string, I suppose?

14:44 justin_smith: michaelr524: or even construct it directly from 5 calls to subs, since it's always five elements :)

14:44 takemikazuchi: when you iterate on a string you get characters, not strings

14:44 clojurebot: Excuse me?

14:44 hiredman: takemikazuchi: you are comparing characters to strings

14:44 takemikazuchi: Thanks makes sense.

14:45 so capitalize is returning a string

14:45 hiredman: I suspect so

14:45 takemikazuchi: Yup that was it!

14:45 justin_smith: ,(clojure.string/capitalize \e)

14:45 clojurebot: "E"

14:45 justin_smith: yup

14:46 takemikazuchi: Just needed to add (str x)

14:46 justin_smith: ,(first (clojure.string/capitalize \e)) ; second option

14:46 clojurebot: \E

14:47 michaelr524: justin_smith: exactly, that's what I was trying to communicate in my last sentence hehe

14:47 justin_smith: michaelr524: ahh, OK. We have a concat function so it was ambiguous

14:48 though in context concat would not actually make any sense...

14:48 cfleming: borkdude: ok, so for external annotations you'd type check the ns containing the annotations, not the actual code? Makes sense.

14:49 borkdude: I should really test that!

14:49 borkdude: cfleming well, that wasn't what I meant. say I have a call in a namespace "other" to function f that is called with the wrong type

14:50 justin_smith: michaelr524: bonus, the version with five calls of subs in a collection will be more readable too

14:50 borkdude: even when I have an annotation in namespace "other2" and typecheck "other2", it won't detect the wrong call in "other" if it didn't require core.typed

14:51 cfleming If I would add the require to "other" and type check other, it will detect

14:51 cfleming so that's all you have to do I think

14:51 cfleming checking "current ns" doesn't work if you haven't got the require, that's what it boils down to

14:53 takemikazuchi: justin_smith, hired_man, thanks guys.

14:54 cfleming: borkdude: But if other doesn't have the require, then it can't be annotated, right?

14:54 takemikazuchi: Got to question 30 of 4Clojure

14:54 borkdude: cfleming the annotation can be in a different namespace

14:56 cfleming: I see. And this restriction is from core.typed itself, right?

14:56 borkdude: cfleming for example, this works with the require, not without: https://www.refheap.com/91211

14:56 cfleming yes

14:57 cfleming "works" -> "type checks"

14:59 cfleming you could add a warning when someone calls "type check current namespace" when the require isn't present

15:00 michaelr524: justin_smith: https://www.refheap.com/91212

15:00 justin_smith: could have used a vector of the calls + join of course

15:01 justin_smith: but maybe this is more efficient :)

15:01 justin_smith: michaelr524: ahh - why not a StringBuilder?

15:01 StringBuilder would be more efficient by far, I didn't realize what you were doing

15:01 michaelr524: justin_smith: well, there is a roumor that java automatically creates a StringBuilder when you try something like that

15:01 rubberduck: anyone here familiar with clojure.core.async.impl.protocols ? I'm having trouble figuring out the required semantics for ReadPort implementation since it's not documented

15:02 and the only implementation (chan) is cluttered with buffer stuff which is hard to follow

15:02 justin_smith: michaelr524: I had no idea, but really using a StringBuilder directly would not be that much more complex

15:02 borkdude: doesn't clojure have transient strings for that? ;P

15:02 michaelr524: justin_smith: I think that's the latest recommendation from the java people, instead of using a StringBuilder just concatenate your strings aways with that + operator

15:03 justin_smith: if java does it (as in the compiler), that doesn't help at all

15:03 clojure does not use the java compiler except when building the clojure jar

15:03 michaelr524: justin_smith: there is a point in what you are saying here

15:03 hmm

15:04 hyPiRion: ,(time (do (reduce str "" (range 100000)) nil))

15:04 michaelr524: then probabaly a StringBuilder would be better

15:04 clojurebot: eval service is offline

15:04 hyPiRion: oh, uh

15:04 michaelr524: eval service went out of bussiness

15:04 justin_smith: hyPiRion: but that's not using concat calls

15:04 borkdude: insert coin

15:04 hyPiRion: justin_smith: oh, so it's concat vs. stringbuilder?

15:05 justin_smith: yeah, that's what we are comparing

15:06 hyPiRion: &(let [s (mapv str (range 10000))] (time (do (reduce #(.concat %1 %2) "" s) nil)))

15:06 lazybot: Execution Timed Out!

15:06 hyPiRion: oh whoah, you shouldn't timeout on that

15:07 lazy bugger

15:07 &(let [s (mapv str (range 10000))] (time (do (apply str "" s) nil)))

15:07 lazybot: ⇒ "Elapsed time: 8.555949 msecs" nil

15:07 hyPiRion: str is using stringbuilder internally

15:07 mbac: (defn save-sexp [d f] (with-open [w (clojure.java.io/writer f)] (.write w (binding [*print-dup* true] (prn d)))))

15:08 is that no longer the right way to serialize stuff?

15:09 justin_smith: hyPiRion: oh, cool

15:11 michaelr524: ok then

15:11 I've updated the paste

15:11 https://www.refheap.com/91212

15:11 dbasch: amalloy justin_smith I got that geohash code to be “only” 1.8x as slow as the java version

15:11 justin_smith: dbasch: awesome, what did it take?

15:12 dbasch: turns out bit-flip and bit-test are pretty inefficient

15:12 justin_smith: wow, I had no idea

15:14 dbasch: justin_smith: in my benchmark (bit-flip x n) takes twice as long as (bit-xor x (bit-shift-left 1 n))

15:41 justin_smith: plus there was some random sillines, e.g. (+ lo (/ (- hi lo) 2)) instead of (/ 2 (+ hi lo))

15:41 silliness

15:43 this is what I have so far https://www.refheap.com/91217

15:44 it has room for improvement

16:10 arrdem: dbasch: isn't locate [double double double long] -> long?

16:10 clojure.lang.IFn$DDDLL exists

16:10 could be worth something

16:11 dbasch: I’ll try

16:13 not sure if that type hint makes a difference, it seems to get lost in the noise

16:14 arrdem: dbasch: yeah looking at that it should get lost in the noise.

16:14 dbasch: hinting the return type would only help if it were called in a tight loop, and it isn't.

16:15 dbasch: as it is it takes about 700ns on my machine, compared to 11us for the original function and 400ns for the java version

16:17 the one thing I don’t understand is why bit-flip seems so slow compared to the hand-rolled alternative.

16:18 Bronsa: dbasch: it's not inlined so it always gets compiled to flipBit(Object,Object)

16:19 dbasch: replacing (bit-flip x n) with (clojure.lang.Numbers/flipBit x n) should make it fast

16:20 dbasch: Bronsa: I’ll try that, it would make that code more clear

16:20 but that’s the kind of function that should be inlined

16:20 Bronsa: it's unfortunate that not all the stdlib has :inline metadata where it would make a difference

16:20 yeah

16:21 dbasch: (inc Bronsa)

16:21 lazybot: ⇒ 53

16:21 Bronsa: I have a ticket that adds :inline metadata to most of the predicate functions in core, but I doubt it's ever going to make it in

16:22 arrdem: story of jira...

16:23 Bronsa: arrdem: not as much as jira as the Rich deciding :inline will no longer be used

16:24 arrdem: Alex told me that :inline is deprecated and will no longer be added to functions in core

16:24 deprecated in favour of compiler macros -- which don't exist yet.

16:24 arrdem: sounds about right

16:25 Bronsa: I really don't understand why we can't leverage :inline and replace it later with those, when they'll actually be a thing

16:25 arrdem: what's the word on those. 1.8 ish? not even seeing anything on google or in the logs for em.

16:26 Bronsa: arrdem: they're in the Release.Next page so maybe they'll make it in for 1.7, but who knows

16:27 arrdem: http://dev.clojure.org/display/design/Inlined+code

16:29 arrdem: Bronsa: hum... could probably do that in like... a week for Oxcart/TEJVM

16:31 Bronsa: I would experiment with them if I saw the need for them, but I fail to see the limitation of :inline. I get that definline sucks because it requires eval, but :inline is fine for me. w/e

16:32 arrdem: :inline/definline is a hack IMO due to lack of a real constant folder/partial evaluation engine. It works, but it's just a hacky implementation of a special case that Rich decided was worth caring about.

16:33 Bronsa: actually if I have to be honest :inline kinda sucks too because it requires metadata to be evaluated at analysis time.

16:34 arrdem: 'tbaldridge was ... pursuasive that a partial application engine probably wasn't worthwhile generally but you're right in primitive type cases like this it really can pay off

16:34 idk

16:34 I was planning on doing one and it didn't happen

16:34 down that path lies loop unrolling and inlining heuristics. and madness.

16:36 gfredericks: clojurebote: down that path |lies| loop unrolling and inlining heuristics. and madness.

16:37 hwhoops.

16:37 clojurebot: down that path |lies| loop unrolling and inlining heuristics. and madness.

16:37 clojurebot: Ok.

16:37 cfleming: Bronsa: don't get me started on definline - I still don't understand why there's so much resistance to supporting/using it

16:37 Bronsa: Especially now that there's a fix to the main known problem - many thanks for that!

16:38 Bronsa: cfleming: yeah I really don't get it either

16:39 cfleming: TBH I thought that by fixing that AOT compilation bug clojure/core would reconsider its stance on definline, I was kind of baffled when they didn't change stance on it

16:39 arrdem: Bronsa: hum so CL's DEFINE-COMPILER-MACRO defines/allows a second round of declinable form rewriting before code gen?

16:40 justin_smith: ~down that path

16:40 clojurebot: down that path lies loop unrolling and inlining heuristics. and madness.

16:40 cfleming: Bronsa: Yeah, me too. At least I can use it in my own code now though.

16:40 arrdem: justin_smith: good thing I'm already mad then

16:40 Bronsa: arrdem: yeah something like that

16:40 * arrdem wonders how much of Oxcart could be rewritten in terms of compiler macros

16:41 Bronsa: arrdem: in t.a speak, it's just extending the -analyze multimethod for 'function-name

16:41 ustunozgur: hi there, a java interop question: (new (.getClass "test1") "test2") doesn't work. is there a way to achieve something like this without reflection?

16:41 Bronsa: cfleming: so you're using a patched clojure?

16:41 arrdem: Bronsa: ehrm... yeah because this occurs at the form level not at the analyzed AST level

16:42 gfredericks: ustunozgur: your example seems inherently reflective

16:42 Bronsa: arrdem: yep

16:42 arrdem: Bronsa: which actually makes this less powerful because you aren't exporting all the analysis stuff.

16:42 Bronsa: you can't look at closed overs and soforth

16:42 ustunozgur: yes, gfredericks (assert (= String (.getClass "Test"))) (new String "test") works though.

16:42 Bronsa: arrdem: uh? you get &env and nobody prevents you from calling analyze on &body

16:42 ustunozgur: maybe because it's a special form.

16:43 Bronsa: arrdem: cljs does something like this already

16:43 ustunozgur: not sure where I would need this though, just tinkering.

16:43 gfredericks: ustunozgur: yeah new is a special form; if you don't have the class name at compile time, it's inherently reflective

16:43 Bronsa: arrdem: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj#L260-L276 as an example

16:43 cfleming: Bronsa: Yeah, although I haven't applied that patch yet. I will do as soon as the patch stabilises - I've been running with the patch from http://dev.clojure.org/jira/browse/CLJ-1315 since it came out.

16:43 arrdem: Bronsa: I guess. I'd just lean towards exposing the analyzed AST for user definable transforms because almost anything interesting is gonna try to get tha tinformation anyway.

16:44 ustunozgur: gfredericks: OK, thank you.

16:44 arrdem: cfleming: how's the patched verison of Clojure thing working for you? it's been tempting me for a while now.

16:44 Bronsa: I've done that, it gets old really fast

16:44 commits in clojure master break everything

16:45 gfredericks: what are we patching for?

16:45 cfleming: arrdem: It's working well for me, I'm still running 1.5.1.

16:45 Bronsa: and you're left trying to manually merge everything

16:45 arrdem: gfredericks: rabble rabble rabble

16:45 cfleming: arrdem: Everyone using Cursive is using a patched version.

16:45 Bronsa: cfleming: ssssh they don't need to know

16:45 arrdem: Bronsa: interesting example. thanks.

16:46 gfredericks: ah

16:46 cfleming: Bronsa: Hehe, yes, my lips are sealed.

16:46 arrdem: lol @ ninja patched version

16:46 gfredericks: how do you convince leiningen to use a patched version? do you have to exclude clojure from every dep?

16:46 is there a global exclude feature?

16:46 cfleming: gfredericks: I use Ant. It doesn't take much convincing.

16:46 Bronsa: arrdem: that's a really nice example actually, I've tried moving that transformation to the AST level as a pass, and it's way easier to do it this way

16:46 gfredericks: cfleming: that is the first time anybody has told me that.

16:47 Bronsa: gfredericks: just exclude org.clojure/clojure and include my.clojure/clojure

16:47 gfredericks: Bronsa: so leiningen *does* have a global exclude?

16:47 arrdem: gfredericks: not that I'm seeing. you have to roll it manually.

16:47 gfredericks: I guess a plugin could do the dirty work

16:47 arrdem: this is actually the primary reason why I've never used org.oxlang/clojure for anything...

16:48 Bronsa: gfredericks: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L63-L66

16:48 arrdem: (inc Bronsa)

16:48 lazybot: ⇒ 54

16:48 gfredericks: (inc Bronsa) ;; semiprimes are cool

16:48 lazybot: ⇒ 55

16:48 Bronsa: let them rain

16:49 arrdem: (dec Bronsa) ;; karma/minute rate exceeded

16:49 lazybot: ⇒ 54

16:49 johnwalker: (inc Bronsa)

16:49 lazybot: ⇒ 55

16:49 gfredericks: Bronsa is going to win an award for karma thrashing

16:49 Bronsa: I know how a rubberband feels now

16:50 arrdem: he's got a loooong way to go before catching up with amalloy..

16:50 gfredericks: ~amalloy

16:50 clojurebot: try that; it won't work

16:51 gfredericks: clojurebot: clojurebot is a jukebox for amalloy's greatest hits

16:51 clojurebot: Ik begrijp

16:52 m1dnight_: Dutch \o/

17:00 arrdem: I guess the issue is when if ever does a patched verison of Clojure pay for itself...

17:01 gfredericks: ...when you get the feature you need?

17:01 which is immediately?

17:01 arrdem: no as in what features could not be added as libraries.

17:01 so.. lets say I wanted a library that adds clojure.core/seqable?

17:01 gfredericks: some of them

17:02 probably mods to the compiler mostly?

17:02 arrdem: probably...

17:02 but even then TEJVM is almost good enough, just drag that in and mod it

17:04 gfredericks: $google TEJVM

17:04 lazybot: [CPU count confusion | VMware Communities] https://communities.vmware.com/message/2334874

17:04 arrdem: $google clojure.tools.emitter.jvm

17:04 lazybot: [clojure/tools.emitter.jvm · GitHub] https://github.com/clojure/tools.emitter.jvm

17:05 gfredericks: oh hey right

17:05 arrdem: that thing that Bronsa and I were working on. all summer.

17:05 gfredericks: worked on so hard you needed some seriously optimized acronyms

17:06 arrdem: that's actually the dev.clojure.org/jira name :/

17:06 gfredericks: oh I like those acronyms actually

17:06 I just don't know them all

17:07 I've been working on TCHECK and NREPL lately

17:10 takemikazuchi: Anyone wanna give me some feedback? I'm working through 4clojure problems: Problem: https://4clojure.com/problem/31 My solution: https://www.refheap.com/91221

17:11 justin_smith: takemikazuchi: conj takes varargs, so you don't need to wrap a call to conj in another call to conj

17:11 ,(conj [] :a :b)

17:11 clojurebot: [:a :b]

17:12 gfredericks: ,(conj [] conj conj (conj))

17:12 clojurebot: [#<core$conj clojure.core$conj@d4f698> #<core$conj clojure.core$conj@d4f698> []]

17:12 justin_smith: lol

17:12 gfredericks: actually

17:12 ,(conj (conj) (conj) (conj) (conj))

17:12 clojurebot: [[] [] []]

17:13 arrdem: rofl

17:14 takemikazuchi: justin_smith: in that case I believe I need to as last of x is a collection that I want to insert y into.

17:16 justin_smith: ahh, I misread, you are right

17:17 well, style wise, if you are using pop, then use peek and not last

17:17 peek/pop butlast/last

17:17 (first/rest)

17:18 gfredericks: +/-, *//, concat/deconcat swap!/unswap!

17:19 justin_smith: heh

17:19 we need unswap!

17:19 gfredericks: launch-missiles/return-missiles

17:19 takemikazuchi: justin_smith: That makes sense, peek does seem more natural there.

17:20 justin_smith: gfredericks: deconcat is clearly (rand-nth [partition partition-all partition-by])

17:20 gfredericks: split-at

17:21 split-with

17:21 justin_smith: oh yeah, those too

17:21 gfredericks: (juxt take drop)

17:27 dbasch: deconcat randomly partitions a sequence so that all possible partitions are equally likely

17:28 arrdem: you could actually define a Concat type and a sane deconcat operator...

17:28 gfredericks: ,(defn deconcat [coll] ((juxt take drop) (rand-int (inc (count coll))) coll))

17:28 clojurebot: #'sandbox/deconcat

17:28 gfredericks: ,(deconcat (range 10))

17:28 clojurebot: [(0 1 2 3 4 ...) ()]

17:28 gfredericks: ,(deconcat (range 10))

17:28 clojurebot: [(0 1 2) (3 4 5 6 7 ...)]

17:29 dbasch: gfredericks: that’s all splits, I mean all possible partitions from all n elements to a single collection

17:34 arrdem: so looks like we define concat in terms of a lazy sequence of cons...

17:34 could probably have a Concat type with a seq of subsequences

17:34 then deconcat is trivially the sequence of subsequences

17:38 justin_smith: a version of deconcat https://www.refheap.com/91223

17:38 takemikazuchi: Anyone who knows ruby here, is it safe to say Ruby's foo(*bar) and Clojure's (apply foo bar) are functionally equivalent?

17:40 dbasch: justin_smith: but the empty subsequences…

17:40 amalloy: takemikazuchi: yes, they are the same general idea

17:40 justin_smith: dbasch: they are all valid inputs that return the original sequence if you apply concat

17:41 feel free to change the (rand-int n) to (inc (rand-int (dec n))) of course

17:42 takemikazuchi: amalloy: Thanks. Any significant differences I should keep in mind?

17:43 amalloy: takemikazuchi: not really. some nice stuff like apply is a function, so you can do something silly like ##(map apply [+ -] [[1 2 3] [21 7 2]])

17:43 lazybot: ⇒ (6 12)

17:44 amalloy: i suppose (partial apply +) would be a more common example

17:44 (def sum (partial apply +))

17:47 hiredman: partial apply + 0

17:52 gws: takemikazuchi: can the splat be used on something akin to ##(apply + (range 10))

17:52 lazybot: ⇒ 45

17:53 gws: e.g. a hypothetical sum function that takes a variable number of arguments: sum(*[0..9])

17:53 H4ns: in compojure, is there a way to pass both the body-params and a url param to a handler? apparently, if i use vector syntax, i can only access the url parameters (/bar/:foo), whereas when i use map syntax, i can't access the url parameters.

17:53 (i want to have a PUT handler which has the ID in the url and the updated data in the request body)

17:54 amalloy: gws: yes, that is like the only thing that splat can do

17:55 * H4ns just learned about context in compojure routes. i guess that is what i'll have to use, thanks

17:56 dbasch: justin_smith: check this one out https://www.refheap.com/91226

17:56 gws: amalloy: i don't know ruby that well, but i created a vararg sum function and it works when i pass multiple args but with *[0..9] i get "Range can't be coerced into Fixnum" on ruby 2.1.0, so that's why i asked

17:56 dbasch: lazy, uniform random partition

17:59 justin_smith: interesting, so it has 50% chance of size 1, 25% of size 2, 12.5% of size 3 etc. (modulo the bail out if size is greater than remaining contents)

18:00 whereas mine was even within range of size of coll (with same bailout condition)

18:00 amalloy: gws: that's not the syntax for rangers. it's just a really weird number

18:00 *ranges

18:00 justin_smith: amalloy: time for the ad&d based dsl for sequences

18:00 takemikazuchi: gws: Yeah I mean the analogy starts to break down at that point I supppose

18:00 dbasch: justin_smith: and mine doesn’t even care about the seq size, or if it’s finite

18:01 justin_smith: right

18:01 dbasch: e.g. (take 10 (random-partition (range)))

18:01 takemikazuchi: lol you end up with something like this: lambda{|*x| x.inject(:+) }.call(*(1..9).to_a)

18:01 amalloy: gws: you want (1...9)

18:01 takemikazuchi: eh? you don't need the to_a

18:01 takemikazuchi: amalloy: yeah just noticed that.

18:02 amalloy: def sum(*xs) xs.inject(:+) end; sum(1...9)

18:02 or something like that

18:02 there. def sum(*xs) xs.inject(:+) end; sum(*(1..9))

18:03 dbasch: justin_smith: the 1/2 chance is to guarantee uniformity

18:04 can’t think of a better way off the top of my head

18:04 justin_smith: right, just observing the behavior

18:05 could have as easily been thirds (1/3 chance of size 1, 1/6 of size 2, 1/12 of size 3, etc.)

18:05 dbasch: justin_smith: but then it wouldn’t be uniform

18:06 I wanted all possible partitions to be equally likely

18:09 that would be an awful interview question btw

18:11 I should create a library called useless, in the spirit of amalloy’s useful

18:12 this could go in there

18:13 along with a macro that makes code fail randomly

18:13 actually that’s not useless

18:16 amalloy: dbasch: the classic backwards-mode macro belongs there

18:17 (defmacro backwards [& body] (cons `do (postwalk (fn [x] (if (seq? x) (reverse x) x)) body)))

18:19 gfredericks: without-redefs

18:20 dbasch: with-open-or-dev-null

18:20 maybe-off-by-one-loop

18:21 thread-somewhere

18:21 -???>

18:22 aka as the magical mystery arrow

18:23 also aka as

18:24 justin_smith: dbasch: how is 50% chance of size 1 etc. more uniform than 33% chance of zie 1 etc. ?

18:24 dbasch: justin_smith: because there are 2^n partitions

18:25 so for example the one with all the elements must occur when you get n tails in a row

18:25 technicall 2^(n-1)

18:26 justin_smith: dbasch: clearly there is something I don't yet get about statistics underlying all this

18:26 dbasch: try for example (frequencies (take 10000 (repeatedly #(random-partition (range 4)))))

18:27 e.g. for (0 1 2) you have four possibilities

18:27 you want to choose ((0 1 2)) with 1/4 chance

18:28 cfleming: arrdem: Without running the patch that I'm running, I can't compile my project

18:28 arrdem: So for me the payoff was pretty immediate.

18:29 arrdem: That said, technically I only need my patched version to actually compile, not at runtime.

18:38 gfredericks: ,(partition-by (fn [_] (rand-nth [true false])) '(0 1 2))

18:38 clojurebot: ((0 1) (2))

18:38 gfredericks: ,(partition-by (fn [_] (rand-nth [true false])) '(0 1 2))

18:38 clojurebot: ((0) (1) (2))

18:38 gfredericks: ,(partition-by (fn [_] (rand-nth [true false])) '(0 1 2))

18:38 clojurebot: ((0 1) (2))

18:38 gfredericks: ,(partition-by (fn [_] (rand-nth [true false])) '(0 1 2))

18:38 clojurebot: ((0) (1) (2))

18:38 gfredericks: ,(partition-by (fn [_] (rand-nth [true false])) '(0 1 2))

18:38 clojurebot: ((0 1) (2))

18:38 gfredericks: o_O

18:39 ,(repeatedly 8 (fn [] (partition-by (fn [_] (rand-nth [true false])) '(0 1 2))))

18:39 clojurebot: (((0) (1 2)) ((0 1 2)) ((0 1) (2)) ((0) (1 2)) ((0) (1 2)) ...)

18:39 gfredericks: looks legit

18:40 justin_smith: (inc gfredericks)

18:40 lazybot: ⇒ 91

18:40 justin_smith: that's the one

18:41 tuft: anyone know how to do a "where in" style query in datomic? i.e. get entities where an attribute value is one of several

18:41 dbasch: yes, that’s nicer

18:53 AeroNotix_: does/can timbre rotate log files?

18:57 lodin: Anyone know how to restart an nrepl server so that all defs etc are gone? I tried (do (stop-server s) (start-server)) but that didn't help.

18:58 justin_smith: lodin: defs are not local to the nrepl server

18:58 they are global to the clojure process

18:58 lodin: Oh.

19:02 That actually makes a lot of sense. :-)

19:07 Is there any tool to start/stop isolated clojure processes easily (which I then can access using nrepl)? I think I've read about such a tool.

19:09 justin_smith: http://leiningen.org/grench.html there is grench, I don't know isolated it is

19:10 truebuddi: quick question here at http://pastebin.com/hpFqRFJ7

19:13 jkj: working with clojure and sampling large data objects, i'd be happy if i had a ide and a repl that wouldn't choke on a few kilobytes of text

19:14 wonder if there is a middleware to protect emacs from accidentally printint something that takes all the cpu for couple of minutes

19:15 justin_smith: jkj: iirc the issue is that it applies regexes per line, so lack of line breaks make it freak out

19:15 jkj: ok

19:16 justin_smith: good to know

19:18 hmm. maybe the trick would be to redirect all the output to something that can take it. web browser maybe

19:19 justin_smith: jkj: you could set debug-on-signal, and then send a signal to emacs via kill in a command line

19:20 jkj: then in the debugger you can see what the hell it was doing

19:20 jkj: justin_smith: thx

19:20 justin_smith: sending problematic output to a text file and opening it in emacs in auto-tail-mode is another option

19:20 it will scroll down as new content is created, but not do the CPU heavy shit it does in the repl buffer

19:21 sorry it's called auto-revert-tail-mode

19:21 or something like that - it is like tail -f but in an emacs buffer

19:21 watches the file and reloads every time it sees a change

19:22 you could use proper logging, and then open the log file using auto-rever-tail-mode

19:22 alexbaranosky_: bbloom :snapshot sounds like a good idea

19:23 lodin: justin_smith: I found https://github.com/projectodd/shimdandy. Unfortunately I can't use it via clojure itself. :-)

19:23 jkj: oops. HUP was a bad idea :D

19:23 justin_smith: jkj: oops

19:28 bbloom: alexbaranosky_: it certainly is :-) works out nice too if your variable is a map, which is a good idea anyway so you can assoc/update-in on each recur, rather than muck with positional arguments

19:28 jkj: i'm not quite sure if printing huge amounts of data slowly or lagging when handling big buffers is really a problem or just trying to misuse emacs

19:29 justin_smith: jkj: it's a problem with the repl buffer, that won't come up in a buffer in plain text mode

19:29 jkj: justin_smith: ok

19:29 justin_smith: do you mean it is lagging for big non-repl buffers?

19:29 tuft: any ideas on testing set membership for an attribute value in datomic? searched all over with no luck

19:30 justin_smith: jkj: if so, in clojure mode or in general?

19:30 cfleming: jkj: if you're an IDE sort of person, Cursive handles lots of output pretty well.

19:31 jkj: cfleming: haven't tried that.

19:33 arrdem: cfleming: fair

19:34 cfleming: arrdem: I had a hideous Rube Goldberg machine hooked up just to be able to compile until I applied that patch.

19:35 jkj: Debugger entered--Lisp error: (wrong-type-argument symbolp [object ede-project-autoload ....

19:35 quite strange place where it hits after signilng

19:36 arrdem: cfleming: what patch did you need that badly?

19:36 cfleming: I have a list of bugbears with Clojure, but nothing that actually stops me getting work done

19:36 jkj: it seems to finish the print and then give backtrace of something else

19:36 so doing what is does does not stop on signal

19:36 cfleming: arrdem: http://dev.clojure.org/jira/browse/CLJ-1315

19:37 arrdem: cfleming: gotcha

19:37 cfleming: arrdem: Without that patch, I had to bring up the IntelliJ test infrastructure (~45 secs) and compile inside it.

19:38 jkj: now i have stuff in repl buffer and pushin any key takes about 1,5 sek for the character to appear

19:38 arrdem: cfleming: lol

19:38 cfleming: arrdem: And then shower afterwards, which also takes time.

19:38 jkj: any ideas on seeing what it does?

19:38 truebuddi: sorry if already replied .. disconnected earlier but was asking about splitting (-> .... ) into multiple forms.. http://pastebin.com/hpFqRFJ7

19:39 bobpoekert: What are people using for single-machine k-means clustering these days?

19:39 Still Weka?

19:39 cfleming: arrdem: What's the status of TEJVM these days?

19:40 arrdem: Is it realistic to use it to compile?

19:40 arrdem: truebuddi: you need to be threading that request. right now you ignore it. line 19

19:40 truebuddi: in future please use refheap, because Raynes made it, it's awesome and it doesn't have ads.

19:41 * Raynes quickly inserts ads for porn sites.

19:41 truebuddi: googling refheap

19:41 * arrdem poker face

19:41 arrdem: cfleming: TEJVM totally works, Oxcart is sketchy at best however

19:41 truebuddi: arrdem: thank you will do

19:42 arrdem: cfleming: the main restrictions with TEJVM are either actual bugs in core (incorrect annotations) or just performance. Bronsa has gotten it down to ~15x clojure.core/compile from ~25x but it's still slow.

19:43 cfleming: I never had issues when building Oxcart that weren't of my own doing.

19:43 cfleming: arrdem: That's probably ok for a production build if it makes a different though.

19:43 s/different/difference/

19:43 arrdem: cfleming: oh. TEJVM can't do AOT yet. Oxcart can, but I never backported the infrastructure for Bronsa

19:43 cfleming: arrdem: Ah.

19:43 arrdem: cfleming: that's another killer

19:44 bobpoekert: Searching around for clustering implementations there's a bunch of stuff that hasn't been updated in years and isn't in maven, adn Weka

19:44 and stuff like MALLET which is NLP-specific

19:44 arrdem: one of these days I'll have free time and PR it... but not today

19:44 cfleming: arrdem: Did you look at skummet at all? It looked interesting as well and sounds like it was quite successful.

19:44 truebuddi: arrdem: I changed it to https://www.refheap.com/91230 but still getting cemerick.friend$authenticate$fn__379 cannot be cast to java.util.Map

19:45 arrdem: truebuddi: you have a type error somewhere. you are passing a function where it expects a map. more than that I cannot trivially surmise.

19:46 kenrestivo: ~tejvm

19:46 clojurebot: It's greek to me.

19:46 kenrestivo: me too

19:46 arrdem: truebuddi: I would guess line 12

19:46 truebuddi: check your arguments order with ->

19:46 cfleming: meh totally not biased in this or anything but I think that skummet is a hack/wrong approach

19:47 cfleming: have you seen my end of summer blag post?

19:47 cfleming: arrdem: Sure, but it's one that might produce decent gains with relatively little work.

19:47 arrdem: No, got a link?

19:48 arrdem: cfleming: http://arrdem.com/2014/08/05/of_oxen,_carts_and_ordering/

19:48 cfleming: https://groups.google.com/forum/#!topic/clojure-dev/dSPUNKSaV94

19:48 cfleming: those two pretty well capture my takeaway from this summer

19:49 cfleming: arrdem: Ah, I lie, I did see the mailing list post. I think the proposal to split out core sounds good.

19:50 arrdem: no way it's gonna happen.. but it would be nice

19:50 ^ one line summary of my summer :/

19:51 cfleming: arrdem: I didn't realise that one of the main benefits of Oxcart was to remove var indirection - nice.

19:53 truebuddi: arrdem: converting the defn to a def worked ... https://www.refheap.com/91230 thanks!

19:54 arrdem: cfleming: as I argued in the clj-dev post, skummet and "lazy loading" can only approximate an actual tree shaking compiler, and do so at the cost of creating a difficult to maintain fork of Clojure.

19:55 cfleming: if the world were flat and I had my way, we'd do lib-clojure and then Mikera and I would be free to build crazy clojure-like fast languages

19:55 but it isn't

19:55 cfleming: arrdem: Yeah, no doubt. I'd love to be able to make a totally static production build of Cursive for deployment though.

19:55 arrdem: I guess there's nothing stopping you doing it except time and money, right? :-)

19:56 justin_smith: jkj: not sure actually, if just seeing where it was when you interrupted did not help

19:56 jkj: #emacs could have some ideas

19:57 arrdem: cfleming: basically. mainly money as it can buy time... if someone wanted to foot the bill for this I'd be delighted to say fuckit, maintain my lib-clojure fork and keep working on Oxcart but GSoC is over

19:57 cfleming: that and I think if you're gonna statically compile Clojure may as well take the time to clean up some warts

19:58 I have a project that's my sketch of doing so, but it doesn't work and I'm not sure it'll ever exist so I'll refrain from advertising it here.

20:00 cfleming: arrdem: I'd be interested in hearing about it - are you going to the conj?

20:01 arrdem: cfleming: I probably will but I don't have plans yet.

20:01 cfleming: arrdem: Ok, I'll buy you a beer if you make it and you can tell me about it.

20:01 arrdem: cfleming: haha you're on

20:02 after seeing all the cool stuff from strangeloop I'd be crazy to miss the conj... but classes and stuff

20:03 cfleming: arrdem: Yeah, I have to make it to strangeloop one of these days, it looks amazing.

20:04 arrdem: Almost more interesting than the conj actually, more eclectic

20:04 arrdem: cfleming: yeah it was really interesting to see all the hot stuff from different languages and communities. I've been looking at the conj schedule and due to having a single track there's something for everone

20:17 bobpoekert: I found a library that was updated this year! The documentation is all in japanese.

20:18 oh, and it only works on 2d vectors :(

20:18 TEttinger: (inc Japanese)

20:18 lazybot: ⇒ 1

20:19 TEttinger: what are you looking for, bobpoekert? something in core.matrix?

20:19 bobpoekert: something that can take 27-dimensional

20:19 vectors of reals

20:19 and turn them into a k-means tree

20:19 whether it's in core.matrix or not I don't really care

20:21 justin_smith: (inc 日本の)

20:21 lazybot: ⇒ 1

20:22 TEttinger: I saw a japanese version of https://github.com/joshuaeckroth/clj-ml

20:23 justin_smith: bobpoekert: this looks a little dated, but it does look like what you are looking for http://www.informatik.uni-ulm.de/ni/staff/HKestler/parallelkmeans/

20:24 it's not really idiomatic as a clojure project, but it is doing k-means and has source code you can start with

20:24 bobpoekert: TEttinger: I was referring to https://github.com/satoh-disk/k-means

20:29 TEttinger: there seem to be a bunch of leads. https://github.com/elben/k-means

20:30 bobpoekert: that's 2d

20:30 justin_smith's suggestion might work

20:30 TEttinger: I am not familiar with k-means at all, so I'd go with justin_smith's then. I also found https://github.com/codyrioux/kmeans-clj

20:31 bobpoekert: numeric processing with core.async???

20:31 lazybot: bobpoekert: Oh, absolutely.

20:34 bobpoekert: it should really be more common knowledge that (apply min-key …) is argmin

20:34 took me a long time before I found that out

20:34 min-key and max-key are really confusingly names

20:34 named

20:37 justin_smith: yeah, I wonder what the origin of the current names is?

20:49 gfredericks: min-by and max-by would be less surprising I guess?

20:54 justin_smith: or argmin and argmax, which is what they are called in math

20:54 hodlr: in order to pull in java libs into my project what do i need to enter into project.clj from the pom.xml ?

20:54 justin_smith: hodlr: [group/project "version.id"]

20:55 err, that was sloppy

20:55 [groupId/artifactID "version"]

20:56 hodlr: justin_smith: thanks :)

20:56 gfredericks: justin_smith: I'm kind of surprised I never noticed those names in math

20:56 * gfredericks would like to think he has mathed a little bit

20:57 justin_smith: gfredericks: http://en.wikipedia.org/wiki/Arg_max

20:58 it's the only standard name for the function I know of

20:58 I guess technically arg-min and arg-max could be like min-key / max-key but take collections and return sets

20:59 (the set of all items returning the minimum value)

20:59 (or maximum)

20:59 gfredericks: HUH.

20:59 (inc justin_smith)

20:59 lazybot: ⇒ 85

21:00 justin_smith: actually planet math is usually a better source than wikipedia http://planetmath.org/argminandargmax

21:02 actually, to be most mathematically correct, we could (intern 'clojure.core (symbol "arg max") #(hash-set (apply max-key %)))

21:02 but it would be a pain in the ass to use something with a name like that in actual code

21:03 ,(intern *ns* (symbol "arg max") #(apply max-key %&))

21:03 clojurebot: #'sandbox/arg max

21:04 gfredericks: somebody at work was asking about the behavior of ##(keyword "foo bar") and why it doesn't throw

21:04 lazybot: ⇒ :foo bar

21:04 gfredericks: does anybody know if the answer is A) only backwards compatibility, B) speed (from not checking), C) something else?

21:04 justin_smith: we've had similar discussions around here

21:05 TEttinger: ,((keyword "Oh yeah: I heard the best news!") {(keyword "Oh yeah: I heard the best news!") "Oh really?"})

21:05 clojurebot: "Oh really?"

21:05 TEttinger: they certainly are valid

21:06 justin_smith: ,(intern *ns* (symbol "arg max") (fn [key sq] (apply max-key key sq)))

21:06 clojurebot: #'sandbox/arg max

21:06 justin_smith: ,((resolve (symbol "arg max")) #(* % %) [-10 1 2 3 4])

21:06 clojurebot: -10

21:06 gfredericks: sure but there are uses where they don't

21:07 e.g., if you like to just blindly parse your json into keywords, that might work okay most of the time, but as soon as you start using cascalog or storm things break

21:07 since they're serializing things behind the scenes

21:07 justin_smith: right. and the blindly parsing json into keywords thing may just be the source of the permissive behavior?

21:08 gfredericks: "source of"?

21:08 justin_smith: maybe "a justification for"

21:08 sloppy wording

21:09 gfredericks: well it certainly sets up the "changing this would break lots of code" argument

21:10 which I figured is a good enough explanation for not expecting anything to change at this point; but I wasn't sure if it was universally regretted or not.

21:13 justin_smith: tangentially, I wonder if something related to this (any string becoming a symbol / keyword) couldn't have been exploited to make gensyms a bit stronger (eg. rendering them unreadable)

21:13 I think I meant ie.

21:17 gfredericks: haha that's clever

21:17 so they're guaranteed to not clash

21:17 could make some fringe uses more difficult though

21:18 justin_smith: yeah

21:18 bbloom: gfredericks: it's speed / not bothering to do error checking b/c it's hard

21:18 and of course can't change now b/c ppl depend on broken behavior

21:18 but keywordizing strings when parsing json is a universally bad idea without a known schema

21:19 and a marginally bad idea with a schema too :-P

21:22 gfredericks: bbloom: error checking isn't hard in this case, is it? just arm thyself with a decent regex?

21:22 bbloom: gfredericks: problem isn't "this case" it's universally

21:23 if you make a promise to check your arguments for validity, you get in to the whole type systems, contracts, schemas, etc etc etc forever

21:23 seems the line for clojure was drawn: "only check arguments when there's a high likelihood that somebody will fuck up AND it doesn't slow the whole thing down"

21:24 "but mostly only when a macro will eat the line numbers of your stack trace"

21:24 :-P

21:30 Wild_Cat: while we're on that topic, I'm curious, why was the decision taken to keywordize strings?

21:31 gfredericks: bbloom: coolthx

21:31 Wild_Cat: in what case?

21:32 Wild_Cat: gfredericks: JSON deserialization.

21:32 justin_smith: that's optional

21:32 always has been

21:32 Wild_Cat: wait, it is?

21:32 bbloom: there's a keywordize? argument

21:32 Wild_Cat: hrmm. I'm misremembering. Disregard my question and carry on, then.

21:33 it's been too long since I got the occasion to write actual Clojure code.

21:33 bbloom: the argument is discussed in the api docs

21:33 but not the readme

21:33 but it should be :-P

21:36 gfredericks: bbloom: I'm looking for such an argument in the cheshire docstrings but can't find it; is that where you were referring to?

21:37 bbloom: core.data.json

21:37 i assumed that's what Wild_Cat was referring to

21:37 sorry

21:37 Wild_Cat: bbloom: it was.

21:37 bbloom: oh then NOT sorry :-)

21:41 * gfredericks is not seeing anything interesting at http://clojure.github.io/data.json/

21:41 bbloom: gfredericks: the read-json function

21:44 gfredericks: bbloom: oh dear I think I misinterpreted the word "argument"

21:44 bbloom: gfredericks: ha! seems you need some sleep my friend

21:44 gfredericks: this morning I slept in till 6:30

21:44 hugoduncan: in cheshire you can pass in an arbitrary function to apply to keys

21:50 justin_smith: hugod: which could as easily be a validator as a keywordizer :)

Logging service provided by n01se.net