#clojure log - May 11 2015

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

0:51 bucketh3ad: Is there any way to step through a call to reduce so I can see the intermediate values and figure out where my function is going awry?

0:52 Bronsa: ,(reductions + '(0 1 2 3 4))

0:52 clojurebot: (0 1 3 6 10)

0:53 bucketh3ad: That might be helpful, but the reduce call is within a recursive loop, so the results will get thrown away before it returns the final value.

0:57 I could use that if I had a way to pause execution before the call to recur.

1:00 mavbozo: bucketh3ad, is logging the reductions result not possible?

1:05 bucketh3ad: That's what I ended up doing mavbozo. I also found this answer on stack overflow which is a pretty useful one-liner macro"

1:05 http://stackoverflow.com/a/2352280

3:45 sm0ke: if in lein i have a composite profile [:provided-pom-scope :test-pom-scope :shared] would the pom scopes be still preserved?

4:48 mnngfltg: I just came up with this way of applying operations conditionally in the thread-first macro: https://gist.github.com/pesterhazy/e191d0157b6f5cfe2ed8

4:49 Is that useful? Am I reinventing something that already exists?

4:52 mpenet: ,(doc cond->)

4:52 clojurebot: "([expr & clauses]); Takes an expression and a set of test/form pairs. Threads expr (via ->) through each form for which the corresponding test expression is true. Note that, unlike cond branching, cond-> threading does not short circuit after the first true test expression."

4:53 mnngfltg: Huh

4:53 mpenet, true, but I'll have to specify a condition (true?) for every expression I'm threading

4:56 thanks for the pointer though, that seems like what I'm looking for

4:56 mpenet: not necessarly

4:57 ,(-> {} (cond-> true (assoc :bar 1)))

4:57 clojurebot: {:bar 1}

4:57 mpenet: (-> {} (cond-> (true? true) (assoc :bar 1)))

4:57 ,(-> {} (cond-> (true? true) (assoc :bar 1)))

4:57 clojurebot: {:bar 1}

4:58 mpenet: it's more or less a macro version of what you wrote

4:58 mnngfltg: right, or I could use :alwaws

4:58 mpenet: (source cond->)

4:58 ,(source cond->)

4:58 clojurebot: Source not found\n

4:58 mpenet: ,(clojure.repl/source cond->)

4:58 clojurebot: Source not found\n

4:58 mpenet: well

4:58 mnngfltg: I'll find the source :)

4:59 mpenet: (require 'clojure.repl)

4:59 ,(require 'clojure.repl)

4:59 clojurebot: nil

4:59 mpenet: ,(clojure.repl/source cond->)

4:59 clojurebot: Source not found\n

4:59 mpenet: giving up :]

5:38 crazydiamond: Hi. Can anyone suggest way to create/delete Datomic DB synchronously?

5:43 ordnungswidrig: crazydiamond: create/delete a fact?

5:44 crazydiamond: ordnungswidrig, I get answer on #datomic now. The problem was that it's deleted and created in async way

5:44 and I can't make a loop with schema changes

5:44 ordnungswidrig: crazydiamond: :-)

5:45 crazydiamond: but solution is always create new DB

5:45 also, I'll probably use mem storage. so thanks for answering! :)

5:49 michaelr`: anyone knows of a cool compnay names generator?

5:49 juxt is take ;)

5:49 taken

5:51 ordnungswidrig: michaelr`: the swing demo application had a panel creating those.

5:51 wink: hmm, I only wrote a WoW guild name generator and a product name generator for our company :P

5:55 michaelr`: ordnungswidrig: which one?

5:55 ordnungswidrig: michaelr`: the swingset, I think

5:55 michaelr`: wink: can you generate a few names for me ;)

5:56 ordnungswidrig: michaelr`: I don't know if this is in jdk8 anymore

5:59 wink: michaelr`: you could just try creating a new github repo, it generates random names

5:59 also, https://www.google.de/search?q=random+company+name ;)

6:01 michaelr`: yes, lot's of generators online but they don't give cool names by default

6:01 you'd need to give them some ideas for words to combine but I have none :)

6:01 wink: well yeah

6:02 unless you want to name a company "The Epic Pirate Unicorns of Darkness" then my guild name generator wont help you either

6:03 michaelr`: but feel free to be inspired, https://github.com/winks/GuildNameGenerator/blob/master/GNGText.luahttps://github.com/winks/GuildNameGenerator/blob/master/GNGText.lua

6:04 michaelr`: haha

6:33 borkdude: why is there no dissoc-in? :)

6:34 hyPiRion: borkdude: I think the problem was that it wasn't evident whether (dissoc-in {:foo {:bar {}}} [:foo :bar]) would return {:foo {}} or {}

6:36 bcn-flor: Hi ! I have a map with a tree of nodes, each node has a :children item with the child nodes, eg. {:title "Hi" :children {:title "Child1" :children {:title "Child1-1"}}}... I want to recursively remove (dissoc) some keys from all the nodes in tree. Can anyone point me towads the light ?

6:38 hyPiRion: bcn-flor: Children or just a single child? You example shows only a single map (presumably the child), not a sequence of children

6:40 bcn-flor: You're right, actually it's like this: {:title "a" :children [:child1 child2] :child1 {:title "a" :children [:child3 child4] :child3 {...} :child4 {...}}}

6:41 hyPiRion: ah

6:42 Bronsa: bcn-flor: look at clojure.walk/postwalk

6:45 bcn-flor: Bronsa: will do, thanks..

6:45 hyPiRion: I find it usually easier to just implement a recursive function. It would probably look something like (defn tree-dissoc [root key] (-> (reduce (fn [root' child] (update-in root' [child] tree-dissoc key)) root (:children root)) (dissoc key)))

6:48 bcn-flor: hyPiRion: yeah, I've been trying to build the two-liner for 3 hours.. but haven't tried with reduce

6:50 hyPiRion: was trying to (merge (dissoc mymap :bad-key) mapped_children) , where mapped children is a recusrive map over the child nodes, converted back to {}. Doesn't work though

6:53 hyPiRion: bcn-flor: that should also work, but you have to use (apply merge ...) or (reduce merge)

6:54 ,(apply merge {:foo :z} [{:bar :a} {:baz :g}])

6:54 clojurebot: {:foo :z, :bar :a, :baz :g}

7:05 joelkuiper: I'm not sure if it's against the rules ... but there's a stackoverflow question that's been bothering me https://stackoverflow.com/questions/30081260/enumerate-namespaces-and-dynamically-load-them-in-clojurescript

7:25 borkdude: joelkuiper you can try something in combination with a macro or cljc?

7:25 joelkuiper so the vars also are created in clojure/jvm

7:25 joelkuiper and you can enumerate them from there and use that output in clojurescript

7:31 joelkuiper: borkdude: yeah, I guess something like that would work. It's a bit contrived though, since I'll be relying on the cljc compiler

7:32 borkdude: In plain clj I would've probable tried to get the reified vars by name, but that's not an option in cljs

7:32 borkdude: joelkuiper you could write a macro that registers the var to a collection inside an atom when you define a component

7:33 joelkuiper or just do it manually when you define a component

7:33 joelkuiper: borkdude: yeah that was my other thought ... I tried a similar approach without macro's but that lead to some circular dependencies in some edge cases

7:34 borkdude: I could fix those cases probably, and indeed just call some (register component) fn that writes to an atom. Still have to list all the namespaces though

7:34 but that's inevitable I guess

9:58 escherize: When I'm using emacs inside a clojure file, what's the best way to jump to or create its test file counter part??

9:58 lazybot: escherize: What are you, crazy? Of course not!

9:58 escherize: :(

9:59 timvisher: is there a library that makes the output of :pre and :post conditions a little more humane?

9:59 like maybe printing the offending value and the expression that produced it?

9:59 hyPiRion: Raynes: I think lazybot's responses just cause confusion right now. People assume it's a serious reply

10:00 isn't that true lazybot???

10:00 lazybot: hyPiRion: Oh, absolutely.

10:00 timvisher: i'll second hyPiRion here :)

10:00 wink: timvisher: if your values offend you and you need humane output, maybe try a badword censoring? ;)

10:01 escherize: I've been told pre and post conditions are a code smell.

10:02 bensu: escherize: what's the reasoning behind that?

10:06 escherize: If it's not clear enough with out them your functions need refactoring

10:06 Is what I was told

10:06 I dont actually use them either, though.

10:06 wink: it shouldn't be about clarity, imo

10:07 escherize: That's a good point. I usually use prismatic.schema/defn if I want to be explicit about preconditions. And havn't thought terribly hard about post conditions.

10:07 wink: invariants aren't bad, they're just not very commonly used. in any language

10:07 escherize: I use invariants a bit

10:07 wink: most people just seem to write tests instead :P

10:08 escherize: yeah I need to be writing more tests.

10:08 BTW: When I'm using emacs inside a clojure file, what's the best way to jump to or create its test file counter part??

10:08 lazybot: escherize: Definitely not.

10:08 escherize: Thanks lazybot

10:08 wink: stop using ?? then ;)

10:10 escherize: why??

10:10 lazybot: escherize: Uh, no. Why would you even ask?

10:11 escherize: lazy bot why must u harrass me??

10:11 lazybot: escherize: What are you, crazy? Of course not!

10:16 joelkuiper: hehe??

10:16 lazybot: joelkuiper: What are you, crazy? Of course not!

10:16 joelkuiper: nice

10:20 justin_smith: escherize: I know there is a function in cider to derive the recommended test file location given a namespace, so if there isn't a "jump to test file" already, it seems like it would be easy to write

10:23 bensu: justin_smith escherize: cider-test-infer-test-ns

10:24 justin_smith: bensu: thanks

10:24 (inc bensu)

10:24 lazybot: ⇒ 1

10:24 bensu: justin_smith: you are right, ideally you would just (comp jump-to cider-test-infer-test-ns)

10:24 :)

10:24 justin_smith: bensu: I knew it was there, but not being a cider user myself it would be tricky to find :)

10:25 bensu: justin_smith: well, I remember because I customized it. It used to be: append "-test" to the ns

10:25 but I use preppend "test." to the namespace

10:26 justin_smith: oh, there would be an extra step, if it gives you the ns - you would also have to turn the ns into a path under test/

10:27 bensu: justin_smith: that's right!

10:28 escherize: (inc bensu)

10:28 lazybot: ⇒ 2

10:29 escherize: I learned you can also projectile-find-test-file (in prelude C-c p T)

10:31 justin_smith: at my workplace, we tried to do a workshop on Friday to change colorization in cljs and cljc files via elisp. We hit some weird speed bumps.

10:39 escherize: like what justin_smith?

10:42 wasamasa: font-lock in emacs is generally weird

10:43 justin_smith: escherize: trying to override highlighting locally is weird. At first we just tried to apply a buffer-specific color scheme, but this just didn't seem to work (thought the docs seemed to claim it would).

10:43 root problem is probably just that we were a bunch of amateur elispers (despite being professional clojure devs) and should not have expected results in the first two hours of work.

10:44 escherize: sounds pretty scary to me

10:44 I'm getting back into learning about emacs - i just made an anki deck for prelude

10:46 also stuff like C-u C-u C-u C-n

10:47 wasamasa: justin_smith: I did for instance have to use M-x font-lock-fontify-buffer to reapply it interactively

10:47 justin_smith: escherize: alternately, M-4 C-n

10:47 wasamasa: justin_smith: doing so for a C buffer however... is slow as heck

10:48 justin_smith: wasamasa: ahh, maybe we got it right, but had to explicitly ask for refontification

10:48 wasamasa: justin_smith: it isn't necessary if you've just started writing a document though as it seems to do lazy contextual updates

10:48 escherize: justin_smith: C-u C-u C-u C-n moves down 64 lines

10:48 wasamasa: justin_smith: and many more weirdness :P

10:49 justin_smith: escherize: oh, I thought it went up by powers of 2

10:49 escherize: it's powers of 4 i guess, but even so M-4 C-n moves me 4 spots

10:50 justin_smith: escherize: C-u 64 C-n is still arguably better if I am avoiding chords, though it's not easier to type of course

10:50 escherize: I really should learn mark better.

10:51 yeah I don't use chords either

10:51 I think i might use helm till i die though

10:51 justin_smith: escherize: I actually switched to evil mode because I have some residual memory of vi, and wanted to cut back drastically on chord usage

10:52 escherize: with spacemacs?

10:53 justin_smith: no, I don't do canned configs, I just turned evil mode on

10:53 wasamasa: death to canned configs

10:53 * wasamasa isn't sure what to think of spacemacs soon including one of his packages

10:55 broquaint: Quick straw poll - any one do mainly Java dev but use Clojure for poking about etc? (yes that's quite a hand-wavey question)

10:55 escherize: I didn't do much Java before I picked up Clojure

10:57 kaiyin: How do you create a byte in clojure?

10:58 broquaint: escherize: Me either, but I'm about to do a whole lot of Java :)

11:00 patrickgombert: kaiyin: https://clojuredocs.org/clojure.core/byte

11:01 kaiyin: patrickgombert: thanks. I am wondering what these two functions are for, they don't seem to do anything: https://github.com/smee/binary/blob/master/src/org/clojars/smee/binary/core.clj#L29-L35

11:01 or maybe i still don't quite understand the difference between byte and unsigned byte.

11:03 patrickgombert: kaiyin: Java doesn't have unsigned types afaik

11:03 escherize: looks like they swap between 2s compliment unsigned notations

11:04 byte being signed?

11:05 kaiyin: escherize: that only matters when you convert it to an int, right?

11:05 hyPiRion: or from an int to a byte

11:05 ,(unchecked-byte 255)

11:05 clojurebot: -1

11:10 kaiyin: hyPiRion: yeah.

11:10 how exactly does this convert a byte into a unsigned byte? (defn byte->ubyte [b] (int (bit-and b 255)))

11:12 hyPiRion: ,(bit-and (byte -20) 255)

11:12 clojurebot: 236

11:12 hyPiRion: the int wrapper just ensures it's an integer instead of a long, I guess

11:13 ,(bit-and (byte -20) (unchecked-byte 255)) ;; => -20

11:13 clojurebot: -20

11:15 kaiyin: hyPiRion: ok, this means (int ...) turns -20 into 236?

11:16 hyPiRion: I probably confused you with the byte calls. Better example:

11:16 ,(bit-and -20 255)

11:16 clojurebot: 236

11:17 hyPiRion: -20, which presumably is a byte, is converted into a long, which is then bit-anded with 255 (lowest 8 bits). Finally it's cast to an int.

11:19 kaiyin: well, why should bit-and do anything to -20 in this case? 255 is just 11111111.

11:19 why is it converted to a long first?

11:20 hyPiRion: kaiyin: because 255 is a long

11:20 kaiyin: ah, ok.

11:21 hyPiRion: I'm pretty sure the behaviour is equal in Java, actually. (byte)-20 & (long)255 should yield 236 as a long.

11:21 kaiyin: but still, why doesn't (bit-and -20 255) return -20?

11:23 ,(Integer/toString -20 2)

11:23 clojurebot: "-10100"

11:25 hyPiRion: yeah, that's a stupid way of representing it.

11:25 Or well, it's not stupid, but it's confusing.

11:25 ,(defn bitify [n] (apply str (for [b (range 32 -1 -1)] (bit-and 1 (bit-shift-right n b)))))

11:25 clojurebot: #'sandbox/bitify

11:25 hyPiRion: ,(bitify -20)

11:25 clojurebot: "111111111111111111111111111101100"

11:25 hyPiRion: ,(bitify 255)

11:25 clojurebot: "000000000000000000000000011111111"

11:26 hyPiRion: ,(bitify (bit-and -20 255))

11:26 clojurebot: "000000000000000000000000011101100"

11:26 hyPiRion: kaiyin: Does it make more sense now, or is it still black magic?

11:27 mikerod: Does anyone have a good way to type hint the return value of an anonymous function?

11:27 I found this to be surprisingly difficult/impossible?

11:28 I don't mean to type hint it when you call it.

11:31 bensu: I remember a google group discussion about this

11:31 mikerod: ^

11:32 mikerod_: Hmm, I guess I'll start searching then

11:32 bensu: https://groups.google.com/forum/#!topic/clojure/2DyGQ6fH1ZU

11:32 not sure if it leads somewhere

11:33 mikerod_: some initial searching has left me empty of ideas. I could just read some compiler and see probably.

11:33 puredanger: mikerod_: there is a ticket related to that that was fixed in 1.7

11:33 mikerod_: puredanger: oh, interesting

11:33 puredanger: http://dev.clojure.org/jira/browse/CLJ-1378

11:34 bensu: mikerod_: who needs google when you have puredanger? :)

11:34 puredanger: some day I will reclaim my memory of thousands of JIRA tickets and be able to remember other general knowledge

11:35 mikerod_: (inc puredanger)

11:35 lazybot: ⇒ 49

11:35 mikerod_: puredanger: that was some amazingly fast Jira link response time

11:35 I've actually read this Jira before myself - and forgot about it...

11:35 thanks!

11:35 puredanger: I have a lot of them memorized unfortunately

11:36 hyPiRion: there is also http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#toBinaryString(int) for binary string conversion btw

11:36 kaiyin: hyPiRion: that's cool. totally makes sense.

11:36 puredanger: (Integer/toBinaryString -20)

11:37 ,(Integer/toBinaryString -20)

11:37 clojurebot: "11111111111111111111111111101100"

11:37 hyPiRion: puredanger: That's convenient, didn't know about that one.

11:37 puredanger: also toHexString, etc

11:37 Bronsa: (inc puredanger)

11:37 lazybot: ⇒ 50

11:37 hyPiRion: (inc puredanger)

11:37 lazybot: ⇒ 51

11:43 escherize: (inc puredanger)

11:43 lazybot: ⇒ 52

11:44 escherize: does this oracle end of lifing java have any effect on me a humble clojure dev?

11:45 TimMc: escherize: You mean EOL'ing Java 7?

11:45 Unless I've missed some pretty big news.

11:46 escherize: Yes thats what i meant

11:49 puredanger: it means you won't get security updates on Java 7 unless you pay oracle

11:49 other than that, no

11:49 escherize: (inc puredanger)

11:49 lazybot: ⇒ 53

11:50 puredanger: I expect we will remove java 6 support from Clojure in the next release or two

11:50 TimMc: puredanger: I read that as "add java 6 support to Clojure" :-D

11:52 escherize: It means you should feel a little more free to use features introduced in Java 8 and should probably not have Java 7 the default on your own computers.

11:52 escherize: I havent written any java in like 3 years

11:53 TimMc: escherize: You use the Java libraries and JVM features from Clojure so that's neither here nor there.

11:54 escherize: But I dont breathe any style into them

11:57 puredanger: "next release" not including Clojure 1.7 that is

12:18 marcoslamuria: Hi folks, I have a question about types and protocols

12:20 is anyone here?

12:21 Bronsa: marcoslamuria: ask your question and you might get an answer

12:21 marcoslamuria: is it possible to have a type that extends another type and implements a protocol?

12:22 Bronsa: no. deftype doesn't support type inheritance

12:23 marcoslamuria: humm

12:24 ok thanks

12:24 patrickgombert: marcoslamuria: it can happen with some macro magic (eg https://github.com/sdegutis/oops)

12:26 marcoslamuria: humm

12:26 let me see

12:27 Bronsa: patrickgombert: he asked about extending a type to another type. that's not possible no matter how many layers of macros you use, deftype simply doesn't allow it

12:28 patrickgombert: yeah, you're right... it might be possible to do something similar though

12:29 Bronsa: i might be wrong but the way he phrased the question, it sounded like he wanted concrete type inheritance, not mixins

12:29 marcoslamuria: yeh a want concrete type

12:30 ok, no problem.. I'll find another way to do what I need

13:13 clojer: Is there a significant difference between reloading a Clojure web app (eg. Luminus) already loaded into a REPL and reloading a Scala/Play2 app compiled inside InteliJ? I'm trying to understand how Clojure REPL editing differs from Scala/SBT reloading.

13:18 wasamasa: I'd describe it for lisp generally as "additive"

13:18 where a few dialects like clojure or racket offer the option to flush out everything and replace it with a clean slate

13:19 clojer: wasamasa: Does this mean with Clojure you're not actually recompiling after an edit but in Scala/Java it's always a full recompile?

13:20 wasamasa: clojer: you recompile selectively

13:20 clojer: or compile a new addition

13:20 clojer: I didn't try out scala, but I can confirm that for java you need a full recompile, yes

13:21 clojer: wasamasa: So as your codebase increases that could make a big difference in your edit/reload cycle?

13:21 wasamasa: clojer: yes

13:21 clojer: it also makes for fun bugs you only encounter while developing :P

13:21 clojer: so there's that

13:22 clojer: wasamasa: Are you saying you find these bugs better with Clojure?

13:22 wasamasa: clojer: no, I mean that if you for instance evaluate version A of a function, decide to change it to version B *and* rename it

13:23 clojer: code still using the old name will keep using the old definition

13:23 clojer: so you won't run into an error telling you the function isn't defined because you're additively accumulating state

13:23 justin_smith: see also redefinition of defrecord

13:23 (related but different error)

13:24 wasamasa: clojer: and only cleaning up the namespace (be it with advanced trickery or a REPL restart) will make that obvious

13:24 clojer: what I'm trying to convey is that it's a mixed bag for me, on the one hand very useful because it makes for a faster workflow, on the other hand messier

13:26 clojer: wasamasa: Does clojure.tools.namespace.repl cover all these bases safely?

13:27 wasamasa: clojer: C-c C-x does that namespace cleanup here, I don't appear to have the necessary middleware installed for it though

13:29 justin_smith: clojer: clojure.tools.namespace.repl/refresh works well, though you need to code your app so that it won't break (by using defonce for things that carry state for example)

13:29 clojer: Thanks. Have to dash.

13:35 goracio: hi, are there any monger users ?

13:36 i got something like that {:_id #<ObjectId 554e4552162a0207b425a903>, :title "First article"} how i can transform _id key to just int ?

13:53 jlegler: You don't have much of a say in that unless you yourself will be generating the ids.

13:53 You can ignore them and put int your own int ids if you want to use ints.

13:54 The _int paradigm is a mongo thing, not a monger thing.

13:58 the _id thing I mean. Mongo doesn't use ints for ids.

14:12 djames: I'm wondering about pub-sub options in Clojure ... perhaps over nrepl or ZeroMQ. Any suggestions on what to look at?

14:12 Also interested in how lightweight one could make a JVM process to serve as an nrepl server

14:22 * TimMc starts designing an nREPL FPGA

14:29 wasamasa: lol

14:31 justin_smith: djames: grench exists as a lightweight nrepl client (written in ocaml)

14:31 djames: justin_smith: thanks, will look

14:31 I think I'll look closer at Netty too

14:44 goracio: hey there ) given [{:a 1} {:b 2}] how to change :a value with string 1-> "1" in each map in vec

14:44 and return [{:a "1"} {:b 2}]

14:50 justin_smith: ,(map #(reduce-kv (fn [m k v] (assoc m k (if (= k :a) (str v) v))) {} %) [{:a 1} {:b 2}])

14:50 clojurebot: ({:a "1"} {:b 2})

14:56 goracio: justin_smith: this is crazy )

14:56 (map #(update-in % [:_id] str) ( [{:a 1} {:b 2}]))

14:57 ,(map #(update-in % [:a] str) ( [{:a 1} {:b 2}]))

14:57 clojurebot: #error{:cause "Wrong number of args (0) passed to: PersistentVector", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (0) passed to: PersistentVector", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.AFn invoke "AFn.java" 28] [sandbox$eval55 invoke "NO_SOURCE_FILE" 0] [clojure.lang.Compiler eval "Compil...

14:57 goracio: ,(map #(update-in % [:a] str) [{:a 1} {:b 2}])

14:57 clojurebot: ({:a "1"} {:b 2, :a ""})

14:59 goracio: ah sorry [{:a 1} {:a 2}] this is the case )

14:59 ,(map #(update-in % [:a] str) [{:a 1} {:a 2}])

14:59 clojurebot: ({:a "1"} {:a "2"})

15:20 justin_smith: goracio: if you always expect an :a key, yes update-in is simpler. But the reduce-kv (or something equivalent) is needed if the :a key may not be present

15:21 goracio: ок

15:21 justin_smith: also you can use update instead of update-in for this case

15:21 ,(map #(update % :a str) [{:a 0} {:a 1}])

15:21 clojurebot: ({:a "0"} {:a "1"})

15:22 justin_smith: with newer clojure versions

15:22 amalloy: ,*clojure-version*

15:22 clojurebot: {:major 1, :minor 7, :incremental 0, :qualifier "master", :interim true}

15:23 amalloy: justin_smith: 1.7 isn't even out yet, right? so you have to be running an alpha to use update

15:23 justin_smith: or a beta, yeah

16:03 amalloy: cfleming: intellij keeps giving me warning messages like "The directory /Users/.../myproj/ is under Git, but is not registered in the Settings". do you know what the deal is with that? the best i could find online was a 2-year-old SO question with the answer "you can't do anything about it"

16:04 cfleming: amalloy: You should be able to fix that - go to Settings->Version Control and set up the directory as a git root

16:05 amalloy: cfleming: that's fine, but it does this for every project

16:05 why do i need to keep adding them as git roots?

16:05 cfleming: amalloy: But once you've configured it for a particular project it stops, right?

16:05 amalloy: i think so

16:06 cfleming: ok

16:06 So you just want to turn that warning off?

16:06 goracio: is there are any way to run server and figwheel in one process ? or in one repl ?

16:06 amalloy: i don't know. i want to know why that warning exists, so i know what i should do about it, which might be turning off the warning

16:08 cfleming: amalloy: So IntelliJ has to have that configured so that its VCS integration works. In multi-module projects these setups can get pretty complex (i.e. multiple VCSes or multiple roots for a single IntelliJ project)

16:08 amalloy: can i uh...turn off VCS integration?

16:08 cfleming: amalloy: So generally in those settings you configure this. Since people might not realise that they have to do that, IntelliJ warns you when it hasn't been done.

16:09 amalloy: Sure - if you only ever use Git on the command line, Settings->Plugins and remove Git

16:09 amalloy: aha

16:09 thanks

16:13 cfleming: amalloy: While you're there, it's generally a good idea to remove any other plugins you're not using too

16:13 amalloy: yeah, i did

16:18 goracio: so ?

16:25 cfleming: goracio: Try asking in #clojurescript

16:25 goracio: brucehauman (the Figwheel author) hangs out in there

16:26 goracio: ok

17:15 hyPiRion: Is the common pattern when you have a protocol definition and want to provide a default implementation for one of the protocol methods to split it into two protocols?

17:27 the-kenny: hypirion: I think so, yes.

17:28 hyPiRion: thanks

17:59 kaiyin: ,(aset ^ints int-array 4 5) why do we need the ^ints here, since it's obviously an int-array?

18:00 clojurebot: #error{:cause "clojure.core$int_array cannot be cast to [I", :via [{:type java.lang.ClassCastException, :message "clojure.core$int_array cannot be cast to [I", :at [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]}], :trace [[sandbox$eval25 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6792] [clojure.lang.Compiler eval "Compiler.java" 6755] [clojure.core$eval invoke "core.clj" ...

18:00 kaiyin: ,(aset ^ints int-array 4 5)

18:00 clojurebot: #error{:cause "clojure.core$int_array cannot be cast to [I", :via [{:type java.lang.ClassCastException, :message "clojure.core$int_array cannot be cast to [I", :at [sandbox$eval49 invoke "NO_SOURCE_FILE" -1]}], :trace [[sandbox$eval49 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6792] [clojure.lang.Compiler eval "Compiler.java" 6755] [clojure.core$eval invoke "core.clj" ...

18:01 kaiyin: sorry, my bad.

18:01 ,(def i (int-array [0 1 2 3 4 5 6]))

18:01 clojurebot: #'sandbox/i

18:02 kaiyin: ,(aset ^ints i 4 5)

18:02 clojurebot: 5

18:04 amalloy: kaiyin: why is it obviously an int-array?

18:04 kaiyin: well, it's generated by int-array.

18:06 TimMc: kaiyin: Clojure's compiler doesn't do very much type inference.

18:06 amalloy: kaiyin: once you def it to something, it's just a var with an unknown value. that's the downside of dynamic typing

18:06 TimMc: Also, that ... yeah, what he said.

18:06 amalloy: of course you don't *need* the ^ints hint - it still works fine without it, but it's faster if you hint it

18:08 kaiyin: ok, got it.

19:58 escherize: Good news! I merged a cljs project into a clojure project! (I started them seperately for some reason.)

19:58 What's the best approach for deployment? I guess it doesn't matter

19:59 my previous workflow is a script that ssh's in, git pulls a tag, and restarts the app

19:59 but with the cljsbuild step, should I actually commit my advanced compiled javascript files in the repo?

20:02 justin_smith: escherize: git and lein on prod is a bad idea anyway

20:03 create your js while generating an uberjar

20:04 escherize: oh really, justin_smith? Lein I can understand, but why is git a bad idea on prod? I worked at a sizable clojure shop for a while and never encountered this line of thought

20:04 also you're On the Money with the uberjar idea

20:05 justin_smith: escherize: git on prod means an intruder gets to not only your server instance, but your repository.

20:05 which means they can backdoor not just a machine, but your infrastructure

20:06 and also uberjars are just simpler - you just deploy one artifact, and maybe a couple of scripts

20:08 escherize: thanks man

20:08 I wonder if I still have git access.. over there.. :)

20:09 justin_smith: haha

20:09 escherize: so totally unrelated.. what's a good way to ransom a set of servers.. or sell trade secrets on the black market?

20:16 cfleming: Does proxy propagate type hints to the parameters of method implementations?

20:18 amalloy: cfleming: reify certainly does. i'm not sure about proxy; the code for that is pretty complicated

20:19 cfleming: amalloy: Yeah deftype/defrecord do as well

20:19 amalloy: right, those are basically the same code

20:19 cfleming: amalloy: Looks like it doesn't

20:20 ,(binding [*warn-on-reflection* true] (proxy [MouseAdapter] [] (mousePressed [event] (.getButton event))))

20:20 clojurebot: #error{:cause "Can't resolve: MouseAdapter", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.Exception: Can't resolve: MouseAdapter, compiling:(NO_SOURCE_FILE:0:0)", :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6644]} {:type java.lang.Exception, :message "Can't resolve: MouseAdapter", :at [clojure.core$proxy$fn__5707 invoke "core_proxy.clj" 329]}], :trace [[clo...

20:20 cfleming: ,(binding [*warn-on-reflection* true] (proxy [java.awt.event.MouseAdapter] [] (mousePressed [event] (.getButton event))))

20:20 clojurebot: #object[sandbox.proxy$java.awt.event.MouseAdapter$ff19274a 0xfe6ce0c "sandbox.proxy$java.awt.event.MouseAdapter$ff19274a@fe6ce0c"]

20:21 amalloy: cfleming: binding doesn't work there

20:21 cfleming: Hmm, I guess clojurebot doesn't show the warnings, but I get one in my REPL here

20:21 amalloy: because the binding applies to runtime, but you want to set it at compile time

20:21 cfleming: It doesn't?

20:21 Actually I .... right

20:21 amalloy: cfleming: you shouldn't, if you were actually using binding and not set!

20:22 cfleming: amalloy: I used set! here

20:22 (set! *warn-on-reflection* true)

20:22 ,(set! *warn-on-reflection* true)

20:22 clojurebot: #error{:cause "Can't change/establish root binding of: *warn-on-reflection* with set", :via [{:type java.lang.IllegalStateException, :message "Can't change/establish root binding of: *warn-on-reflection* with set", :at [clojure.lang.Var set "Var.java" 221]}], :trace [[clojure.lang.Var set "Var.java" 221] [sandbox$eval75 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6792] ...

20:22 cfleming: Meh

20:22 Anyway, I get a warning, so I guess hints are not propagated for proxy

20:23 amalloy: yeah. i was trying to read through the source for proxy to find out, but your way is better

20:23 cfleming: Yeah, often the code is just too complicated to figure out reliably

20:24 I'm adding type inference for Java interop, should be pretty nice - type aware autocompletion etc

20:24 escherize: nice

20:25 amalloy: cfleming: how do you plan for it to work when the target object isn't known yet? eg in (.foo bar), how can you help me with typing foo?

20:26 cfleming: amalloy: You'll be able to type (bar .fo<caret>), when you autocomplete I'll convert that to (.foo bar <caret>)

20:27 amalloy: In cases where the type is already present that won't be necessary, like if you wrap an existing form and then start typing (so the second form is already there)

20:27 amalloy: The second form is also implicitly already there in threading forms etc

20:28 amalloy: interesting. what about not even requiring the parens or the space, so it looks like i'm typing a java method invocation? bar.foo<tab> -> (.foo bar)

20:29 cfleming: I thought about that, it's a little trickier since bar.foo is normally resolved as a single symbol - I might be able to make that work though. The form with the space is more consistent when the first form is e.g. a list

20:29 i.e. ((.method object).otherMethod<caret>)

20:31 crack_user: hello guys

20:31 amalloy: oh sure, i forgot foo.bar already looks like a classname

20:31 crack_user: someone knows what can cause this error? java.lang.IllegalArgumentException: No implementation of method: :success? of protocol: #'buddy.auth.accessrules/IRuleHandlerResponse found for class: buddy.auth.accessrules$success

20:32 cfleming: amalloy: In cases where it's really unknown I can also be smarter now by walking all available local symbols, looking at their types, and offering methods available on those types

20:32 amalloy: crack_user: you probably reloaded the namespace containing a protocol definition, while leaving around instances of the old protocol

20:33 cfleming: amalloy: right, I can special case that though, so if foo.bar looks like a classname but doesn't actually resolve to a class I can then do a secondary search

20:59 escherize: anyone seen java.lang.NoClassDefFoundError: clojure/tools/logging/impl/LoggerFactory before?

21:04 justin_smith: escherize: with clojure.tools.logging you can provide an implementation (sl4j or log4j are the main ones iirc) - it can't depend on either, but one of them has to be present

21:05 escherize: Ahh thank you

21:06 amalloy: cfleming: i had a clojure file with some usages of class Foo in it, which were correctly flagged by cursive as errors, because i hadn't added an import for Foo. then in emacs, i added an import for Foo. now cursive still thinks the usages of Foo are unresolved *and* i have an unused import of Foo in my ns form

21:10 cfleming: i think it's because i also added the dependency to my project.clj, but cursive hadn't reloaded/synced it. a bit weird that it thought the imports were unused as well as being unresolvable, but i guess as long as it flags them as unresolvable it's not a huge deal that it also flags them as unused

21:12 escherize: how do I put the log4j jar on the classpath, like it says to do in https://github.com/clojure/tools.logging

21:13 justin_smith: escherize: add log4j as a dep in project.clj

21:13 escherize: I downloaded apache-log4j-2.2-bin.tar.gz and it unzips into a folder with a lot of jars in it.

21:13 derp

21:17 so then, the vector I added to :dependencies is [org.apache.logging.log4j/log4j-core "1.2.17"]

21:18 but that is wrong :)

21:18 http://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core

21:18 lein could not find the artifact in maven or clojars (probably it will be in maven?)

21:19 oh yeah i got it.

21:19 [org.apache.logging.log4j/log4j-core "2.2"] worked. Thanks again justin_smith

21:19 (inc justin_smith)

21:19 lazybot: ⇒ 252

21:46 escherize: well, I'm still getting the same problem. It looks like I'm using the wrong neo4j? the clojure.tools.logging wants the one listed here https://github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging/impl.clj#L145 , but The only two I can find are [org.apache.logging.log4j/log4j-core "2.2"] and [log4j/log4j "1.2.17"]

21:47 so I'm pretty confused about how to pull "org.apache.log4j.Logger" into my project.

21:48 justin_smith: wait, that's a version?

21:48 log4j-core 2.2 shoudl provide org.apache.log4j.Logger

21:49 escherize: I'm using [org.apache.logging.log4j/log4j-core "2.2"]

21:50 so I'm thinking (Class/forName "org.apache.log4j.Logger") should just work?

21:50 justin_smith: that's what I thought...

21:50 it is definitely provided by log4j 1.2 https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Logger.html

21:50 perhaps it is missing from 2.x

21:50 escherize: is there a special place to put the log4j.properties file?

21:51 justin_smith: it just needs to be on classpath

21:51 escherize: so, I've tried: [log4j/log4j "1.2.17"]

21:53 it's in ./resources so that should be ok

21:55 cool, so (Class/forName "org.apache.log4j.Logger") works from the repl. but lein uberjar is throwing the same error.

21:55 justin_smith: try lein do clean, uberjar

21:59 amalloy: lein do clean, clean, clean, uberjar just in case

21:59 justin_smith: haha

21:59 escherize: ikr

21:59 I bet my uberjar task is fudged.

21:59 justin_smith: in all seriousness, I have had situations where I changed my deps and uberjar went wrong until I did an explicit clean

22:00 cfleming: amalloy: Right, if Cursive can't resolve the class correctly it can't know that the import and the class usage are the same class

22:01 amalloy: Well, anything is possible, obviously, but that's all built around class resolution now

22:43 escherize: ouch, my brain. So my main file won't compile because no logging factory. Then I import the logging factory in the same repl: https://gist.github.com/f2143af6deb55923676b

22:52 justin_smith: escherize: I don't know what's going on there

22:53 escherize: do you have to tell it to use a particular impl?

23:10 loke: I have a long list of things, and I want to apply a transformation on the first element that matches a certain criteria. Right now I've implemented it as such: (map (fn [v] (if (criteria v) (dosomething v) v) some-list). However, this has two problems: 1) It applies the function on every single element when it would be efficient to stop after the first one that matches criteria and 2) if I really want to prevent processing of subsequent matches, I need a stat

23:10 e variable to track that. Is there a better solution?

23:13 justin_smith: ,(loop [acc [] [e & r] [2 4 6 7 8 10]] (if (odd? e) (into (conj acc (inc e)) r) (recur (conj acc e) r)))

23:13 clojurebot: [2 4 6 8 8 ...]

23:13 justin_smith: that's one way to do it at least

23:14 loke: justin_smith: Thanks

23:15 justin_smith: Another solution I was thinking of was to first get the index of the first match and then use a single conj on that element. Would that be more efficient?

23:17 justin_smith: I wanted to use reduce / reduced, but it needs to use the remains of the coll

23:17 could be, if the input is a vector

23:17 loke: The input is indeed a vector

23:18 I was surprised to notice that standard clojure doesn't seem to have an equivalent of CL's POSITION function. Or did I miss something?

23:19 justin_smith: loke: many functions aren't implemented in clojure if they don't have a fast solution (not sure if that's why position is missing though)

23:24 eg. that's definitely why we have hashtables but no alists

23:24 loke: Interesting

23:25 Alists are faster than hashtables though, up to some value of n.

23:25 I have no idea what n is, which might be the reason why it's not supported.

23:25 justin_smith: that's true, but clojure opts not to implement them (it's biased toward fancy data structures)

23:26 loke: small hashtables may be something close to that, but they autopromote

23:26 ,(type {:a 0})

23:26 clojurebot: clojure.lang.PersistentArrayMap

23:26 loke: justin_smith: Yes. It's clearly a very different application. The application I'm working on has the server written in Common Lisp, but the client side were recently rewritten in clojurescript, which is why I'm here askign questions. :-)

23:27 justin_smith: ,(type (reduce conj {:a 0} (repeat 100 [1 2])))

23:27 clojurebot: clojure.lang.PersistentArrayMap

23:27 justin_smith: hmm... I think I did that wrong

23:28 oh, of course, lol

23:29 ,(type (into {:a 0} (map vector (range 1000) (range)))

23:29 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

23:29 justin_smith: ,(type (into {:a 0} (map vector (range 1000) (range))))

23:29 clojurebot: clojure.lang.PersistentHashMap

23:29 justin_smith: there we go

23:29 repeating the key won't force the switch :)

23:30 more info http://clojure.org/data_structures#Data%20Structures-ArrayMaps

23:30 puredanger: of course that may all change post 1.7 with unrolled small collections :)

23:30 justin_smith: puredanger: what difference would you expect to see?

23:31 puredanger: array maps will basically be replaced a family of N-pair map implementations

23:31 justin_smith: ahh

23:31 puredanger: up to some TBD N

23:31 justin_smith: so the same kind of unrolling we see for arities in clojure.core

23:31 puredanger: yeah, code generated

23:32 given the typical distribution for map sizes, it might be a significant bump in perf

23:33 I can't remember what Zach measured in his impl but it was bigger than I expected

23:35 creation time was 5x faster than PAM

Logging service provided by n01se.net