#clojure log - Jan 17 2016

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

1:25 zeebrah: lein repl shows i'm using nREPL 0.2.10 but i'd like to be at 0.2.12. I've just done a lein upgrade and in my ~/.lein/profile.clj i've put the tools.nrepl dependency as 0.2.12. Any ideas?

2:41 is there a prettier way to write this: user> (map #(inc (int (- (int %) (int \A)))) "ABCDE")

2:41 (1 2 3 4 5)

3:31 favetelinguis: ,(let [r (ref {:id []})] (dosync (alter r assoc :g 2)) @r)

3:31 clojurebot: {:id [], :g 2}

3:32 favetelinguis: How can i conj a value into the vector?

3:34 zeebrah: ,(conj [1 2 3] 5)

3:34 clojurebot: [1 2 3 5]

3:36 scottj: favetelinguis: (let [r (ref {:id []})] (dosync (alter r update-in [:id] conj 2)) @r

3:41 zeebrah: if i have a vector of characters, is there a way to check if a certain character is contained in the vector?

3:41 favetelinguis: scottj: thanks

3:46 scottj: zeebrah: (some #{character} characters)

3:53 ridcully: zeebrah: just shorter: ,(map #(- (int %) (int \A) -1) "ABCDE")

3:57 zeebrah: thanks scottj and ridcully. i cant get the some form to work. i think im not very good at clojure haha

3:59 scottj: zeebrah: reading a book helps. feel free to paste a small example of what you have

4:01 zeebrah: scottj: think I got it. there was a problem with cider saying "error in process filter: Wrong type argument: characterp, nil". Startd a fresh instance and it works

4:02 seems to be a bug in cider

4:28 justin_smith: yeah, that's a classic "your elisp code is broken" message from emacs

4:37 zeebrah: can trigger it fairly easy again and again.. so weird

4:37 just by evaluating that some form

4:50 justin_smith: zeebrah: if you want to figure out what is wrong, emacs has a great step debugger

4:50 or you can just accept it's a cider bug and move on

4:55 zeebrah: i figurd it was to do with escaping eg, \A confuses emacs somehow, sometimes

4:55 justin_smith: emacs can handle \A fine, it's cider that gets confused

5:09 zeebrah: ah you're probably right

6:55 John[Lisbeth]: I'm using tryclj.com

6:56 and I believe I am trying to (defn square [x] (* x x))(square 10)

6:58 ridcully: put it in two lines

6:58 John[Lisbeth]: I get this error goo.gl/RjilZv . I did indeed put it in two lines.

7:05 taspat: hi, after "lein new chestnut something" I added cljs-ajax "0.5.3." dependency. Then in core.cljs I've added [ajax.core :refer [GET POST]] and it breaks the core.cljs. What is wrong there?

7:08 ridcully: taspat: has it worked before? can you share the error and maybe the project.clj somewhere?

7:08 John[Lisbeth]: for me this url gives a 404

7:09 taspat: clojure.lang.ExceptionInfo: failed compiling file:src/cljs/something/core.cljs


7:10 ridcully: taspat: there for sure is more than this?

7:10 taspat: project.clj is the default generated by chestnut plus this line: [cljs-ajax "0.5.3"]

7:11 ridcully: then maybe some error in your core.cljs?

7:12 taspat: https://gist.github.com/anonymous/d02295060030d17fdca5

7:16 ridcully: also this template uses rather old cljs and friends. there where lots of changes - not saying that this is the problem, but clj-ajax is on 1.7, so i'd be suspicious

7:17 taspat: ridcully: what template would you suggest?

7:19 John[Lisbeth]: www.hastebin.com/raw/wulodiwevi

8:10 justin_smith: John[Lisbeth]: tryclj automatically clears the sandbox on a schedule

8:10 just rerun the code

8:10 John[Lisbeth]: it isn't exactly 15 minutes after your definition that it is cleared - just exactly once every 15 minutes or so, all definitions go

8:10 John[Lisbeth]: I found another web clojure repl to use

8:10 called himera

8:10 justin_smith: so this can happen any time

8:10 OK

8:11 ridcully: funny thing is, if you do it all on one line that error won't happen

8:40 John[Lisbeth]: when I am running java -cp clojure.<version>.jar clojure.main, what java package do I need for that initial java command?

8:41 quigonjinn: John[Lisbeth]: distro?

8:42 justin_smith: John[Lisbeth]: any java newer than 1.5

8:42 John[Lisbeth]: 1.8 works great. You don't need a jdk, a jre suffices.

8:45 quigonjinn: John[Lisbeth]: I'm using jdk8-openjdk in parabola . And yes jre8-openjdk suffices

8:47 justin_smith: John[Lisbeth]: also, it's great to start out with just java and clojure.jar, but if you get to the point of using the wonderful libs our community provides, you'll find it much easier to use a build tool - it will let you pick the clojure version and the libraries used on a project by project basis and do all the messy classpath and jar building things for you. lein is the most popular, but boot looks pretty cool too as a newer option.

10:15 TimMc: ridcully: Philosophers have been asking this question since time immemorial

10:15 ugh, was in scrollback

10:15 "07:10 < ridcully> taspat: there for sure is more than this?" for reference

10:19 kwladyka: Do you know site with good examples when use async or agent?

10:42 M-martinklepsch: Hello from vector.im :)

11:01 luxbock: M-martinklepsch: what is vector.im?

11:21 rogeralsing: Complete noob on Clojure here.. but when using Leiningen and Cursive in IntelliJ. what is the difference between leiningen tasks and normal run configs? and what defines what tasks there are?

11:38 ridcully: rogeralsing: the tasks for lein are from leiningen and the installed plugins. the run-configs are basically what clojure.main provides with the classpath setup properly. all the other might (or might not) be idea stuff

11:42 rogeralsing: ridcully: if I reference e.g. core-async in the project.clj, I can see that it is fetched and used when I use the "test" task in Leiningen.. but if I set up a run config using Leiningen, it will fail at runtime with filenot found exception when referencing core async.. what am I missing?

11:42 ridcully: reload the config

11:43 open that right hand side window with the vertical "leiningen"

11:43 there is a list of tasks and on the top is one button, that allows to refresh the deps

11:44 if you dont see vertical tabs at the right hand side, you might need to click that small square on the lower left side of your window, which shows them all

11:49 rogeralsing: ridcully: thanks, that did the trick!

11:51 visof: hi guys

11:51 ,(= 1 1)

11:51 clojurebot: true

11:51 visof: ,(== 1 1)

11:51 clojurebot: true

11:51 visof: ,(= nil nil)

11:51 clojurebot: true

11:51 visof: ,(== nil nil)

11:51 clojurebot: #error {\n :cause nil\n :via\n [{:type java.lang.NullPointerException\n :message nil\n :at [clojure.lang.Numbers ops "Numbers.java" 1013]}]\n :trace\n [[clojure.lang.Numbers ops "Numbers.java" 1013]\n [clojure.lang.Numbers equiv "Numbers.java" 212]\n [sandbox$eval97 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval97 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" ...

11:51 visof: why this error occur?

11:51 what == is exactly?

11:53 hi there?

11:54 lambda-11235: visof: == only compares numbers, it cannot be used for any other object.

11:55 visof: ah ok

11:55 lambda-11235: so = is another replacement?

11:55 ,(== "hello" "hello")

11:55 clojurebot: #error {\n :cause "java.lang.String cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers equiv "Numbers.java" 208]}]\n :trace\n [[clojure.lang.Numbers equiv "Numbers.java" 208]\n [sandbox$eval121 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval121 invoke "NO_SOURCE_FILE" ...

11:57 visof: ,( "hello" "hello")

11:57 clojurebot: #error {\n :cause "java.lang.String cannot be cast to clojure.lang.IFn"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to clojure.lang.IFn"\n :at [sandbox$eval145 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval145 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval145 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java...

11:57 visof: ,(= "hello" "hello")

11:57 clojurebot: true

11:59 lambda-11235: visof: (= foo boo) is kinda like foo.equals(boo) in java.

12:04 visof: lambda-11235: i don't know java

13:24 shazzlow: how do I open simple vim buffer with fireplace to evaluate expressions in the current context?

13:32 ridcully: shazzlow: open temp.clj, start lein repl, do `:Connect <url lein tells you>`. cpp/:Eval away

14:24 beaky: hello

14:24 how do i batch sql in clojure.jdbc

14:25 https://ideone.com/fZ2p6S so i can batch the insert! and the db-do-prepared-return-keys

14:35 seako: you can do (apply db/insert! db-spec table-name column-names column-values) or (apply db/insert! db-spec table-name maps-of-key-value-data)

14:36 by default the insert will run in a transaction

14:40 beaky: ah

14:41 thanks

14:52 seako: np

14:56 favetelinguis: if i close! a subscription channel will that be ok or do i have to first use unsub and then close! that channel?

16:09 justin_smith: favetelinguis: I made a gist showing it is safe to close! without unsub (bench.jar is just a clojure.jar uberjarred together with core.async and some other deps) https://gist.github.com/noisesmith/bb9bb3b658924bed334c

16:10 favetelinguis: so :a only consumes 2 values before close!, then :b consumes 3, etc. etc. and all the others still run

16:10 then when 0-9 have all been sent out, it exits

16:31 novak`: I would like to use some functions from Leiningen's leiningen.new.templates namespace in my project which is not a lein template. Is it possible to add it as a dependency somehow?

16:31 justin_smith: yes, you could add the apropriate lein namespace to your dependencies

16:32 novak`: one thing to keep in mind is that some leiningen code was designed to run once and exit, and may have problems in a longer running program

16:35 novak`: justin_smith: I wold like to use name-to-path,year,sanitize,sanitize-ns,project-name... It looks like this functions are safe from that danger.

16:35 justin_smith: novak`: good chance, yeah

16:40 lsyoyom: go free

16:40 novak`: justin_smith: So, what should I try to provide as group-id, artifact-id and version to get leiningen.new.templates?

16:42 justin_smith: novak`: why not make some junk up and fix it later if it breaks the output? I'm really not sure.

16:44 novak`: justin_smith: leiningen-core is only jar available on Clojars, unfortunately, it doesn't provide leiningen.new.templates

16:45 justin_smith: novak`: leiningen itself is on clojars

16:45 https://clojars.org/leiningen

16:45 if you put that in your deps, you should find leiningen.new.templates

16:52 novak`: justin_smith: Hm... It's actually the whole Leiningen packed as a dependency for just few functions. But, thank you anyway. :)

16:53 justin_smith: novak`: yeah, I don't think they provide anything factored smaller

16:53 it's that or make your own fork and jar

16:58 novak`: justin_smith: I found that leiningen.new.templates came to leiningen main repository from https://github.com/Raynes/lein-newnew and it's now deprecated. That is one more option - to retain on a deprecated library.

16:59 ... maybe the worst option

17:01 justin_smith: novak`: just because leiningen.jar is on your classpath doesn't mean the whole thing goes in your heap - namespaces that are required are loaded from it individually

17:05 novak`: justin_smith: I know but still, less jars smaller distribution

17:06 justin_smith: when it goes out as a uberjar of course

17:06 justin_smith: right

17:06 novak`: sounds like it's time to make the lein unterjar plugin

17:07 uberjar pulls in your code plus all your deps, unterjar makes a new smaller jar with only the parts you use...

17:08 TMA: isn't that intractable? (because of eval at least)

17:09 justin_smith: TMA: "lein unterjar is incompatible with code that uses eval at runtime" - done!

17:10 TMA: in sane code, your required namespaces should all be in your ns forms, and static analysis can build the whole tree. Any exceptions that load new namespaces at runtime can be enumerated by hand.

17:10 TMA: justin_smith: I am afraid that even for stating the restriction there might not be a computable function

17:10 justin_smith: TMA: who cares - code broke because you did a thing that the library does not support

17:10 doesn't matter if a program can prove it or not

17:10 TMA: justin_smith: oh, I meant pruning the namespaces for unused vars

17:11 justin_smith: I meant pruning project for unused namespaces

17:11 that's different, yeah

17:12 TMA: novak`'s case was that he wanted to use some namespace that's in leiningen, but not the rest of the project. Namespace granularity seems reasonable to me.

17:12 TMA: on the ns level with the "no dynamic ns" restriction it should be fine

17:12 justin_smith: yeah, I wonder how hard this would be to build...

17:13 TMA: except for the cases of poorly written libraries that implicitly depend on other namespaces [not explicitly depended on] being present in the same jar

17:14 justin_smith: TMA: cool, now they would have an incentive to be better written

17:42 melladric: Hello guys, I am new to clojure and have been looking at Zippers. Can someone say if it is a good (or bad) idea to have MANY zippers (one for each node) for a single "tree"?

17:43 I mean supose each node has a zipper, and I want to add a child to node X. So I can simply append-child to it and I am done. Does that make sense?

17:43 justin_smith: melladric: depends if you are doing any of the modification operations

17:43 melladric: Yes, appending children is my goal

17:44 justin_smith: melladric: this won't affect any of the other zippers though

17:44 melladric: clojure data is immutable, the append is only seen in that zipper, and the resulting seq-zip if any.

17:45 melladric: You are right, I considering to use atom to hold the zipper, but I guess this wont work for this many zippers

17:45 justin_smith: melladric: you don't need an atom, you can just do each of the actions in series

17:45 melladric: Hmmm, the problem I am trying to solve is to append children to a tree in a fast way

17:45 justin_smith: all in one zipper that is

17:46 melladric: hm, If i have one zipper, and a receive a list of "edges" like 1 -> 2 I should search for the node 1 in the zipper and then append?

17:46 justin_smith: ,(update-in [[[[][]]]] [0 0 1] conj :a)

17:47 clojurebot: [[[[] [:a]]]]

17:47 justin_smith: you don't need zippers

17:47 I mean sure you could do that

17:47 melladric: So a hash-map is enough?

17:47 justin_smith: what hash map?

17:48 melladric: The other way, without zippers, would be somehitn like this: {:1 :2}

17:48 is the same as 1 -> 2

17:48 if I would append 1 -> 3 it would be {:1 [:2 :3]}

17:48 justin_smith: wat

17:48 :1 is a terrible keyword, just use the number

17:49 but why does it even need to be a hash-map?

17:49 melladric: What else could I use?

17:49 (sorry for my lack of knowledge)

17:49 justin_smith: ,{1 [2 3]}

17:49 clojurebot: {1 [2 3]}

17:50 justin_smith: in this data structure, what is "1" meant to represent? what are [2 3] meant to represent?

17:50 melladric: 1 is the node label and [2 3] are the children list

17:50 justin_smith: OK so this is an adjacency list

17:51 beaky: i love adjacency lists

17:51 melladric: Yes, since i am dealing with trees i could do node -> to its parent too

17:52 Hmmm, I asked about zippers , because this is the first time I am using clojure and I am trying to solve a problem that needs to build a tree.

17:52 And i need to expose this built tree in a web service. (So my idea was to have a map or zipper in an atom and read from it when asked)

17:53 justin_smith: a zipper on an atom makes no sense

17:53 an atom holding a zipper might be feasible

17:53 above I was just trying to show that nested updates are possible without zippers (and often much easier without them)

17:54 melladric: hmm, i see

17:54 justin_smith: the key, with immutable data, is that you can't just make separate updates uncoordinated from one another, because the input data never changed

17:54 melladric: In your opinion, when is a good idea to use a zipper then?

17:54 justin_smith: so you could have an atom with a zipper, and then use swap! to move and append inside that atom

17:55 or you could use a recursive function or loop, then you don't need an atom

17:55 melladric: In my case I probably need an atom because a web endpoint append nodes and the other "prints" the tree. (or am I wrong again?)

17:56 justin_smith: you could wrap all the request handling in one loop but that would be ugly

17:56 yes, you could do your updates to the zipper for each request, and then have another endpoint that turns the current state of the atom's zipper back into a seq

17:57 melladric: Also, is there a efficient way to append the nodes? I mean, the whole idea of lots of zippers, would be to avoid the worst case input like "1 2; 2 3; 3 4; 1 999"

17:57 Let me explain: 1 points to 2 , then 2 points to 3 and so on

17:58 justin_smith: multiple zippers only makes sense if you want parallel values that would be merged later, or do not need to be coordinated or merged

17:58 melladric: If i used a zipper this means zip/down followed by zip/append-child

17:58 So after the input I would be way tooo deep in the tree

17:58 I would have to go way up to append again

17:59 If I used one zipper, that is.

17:59 justin_smith: if you had two zippers, how would they stay in sync?

17:59 how would one see the changes made in the other?

17:59 melladric: Yeah, you made me realized this wasnt a feasible idea..

18:00 justin_smith: melladric: you could save all the operations, and then sort them in an order that can all be applied efficiently... maybe? I don't know if this would actually be helpful or not

18:01 melladric: also note that there is "root" that directly takes you to the top node http://conj.io/store/v1/org.clojure/clojure/1.7.0/clj/clojure.zip/root/

18:01 melladric: Ah yes, I am aware. That was a example.

18:01 Finding an optimal order is good

18:02 unfortunately from a point onward the input is dynamic/unknow (call to the append web endpoint)

18:02 justin_smith: Thank you for the help :)

18:02 justin_smith: if all you are doing is appending at specific places, update-in or assoc-in might be a lot easier than zippers

18:02 melladric: Yes, I will try that way

18:03 Zippers would be cool because latter I have to operate on the tree

18:03 (i.e doing some tree algorithms) but I'll get by

18:03 Ah

18:03 one more question

18:03 justin_smith: ,(-> [] (update-in [0] conj [:a]) (update-in [0 0] conj :b) (update-in [0] conj [:c]))

18:03 clojurebot: #error {\n :cause "clojure.lang.PersistentList cannot be cast to clojure.lang.Associative"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList cannot be cast to clojure.lang.Associative"\n :at [clojure.lang.RT assoc "RT.java" 792]}]\n :trace\n [[clojure.lang.RT assoc "RT.java" 792]\n [clojure.core$assoc__4365 invokeStatic "core.clj" 191]\n [clojure.core$upda...

18:03 justin_smith: ergh

18:03 melladric: haha

18:04 Nah , the question was silly. Not asking anymore. I still gotta think about the problem

18:05 Thank you for the help, justin_smith

18:06 papphammar: Now when there is talk about trees, recursive loops... and such, maybe I can throw in a question also? :-)

18:06 justin_smith: ,(-> [] (assoc-in [0] [:a]) (assoc-in [0 1] :b) (assoc-in [0 2] [:c]) (assoc-in [0 2 1] :d))

18:06 clojurebot: [[:a :b [:c :d]]]

18:06 papphammar: But I have to show a couple lines of JS-code, can I do that here, or will clojurebot destroy me? ;-)

18:07 melladric: justin_smith: [[:a :b [:c :d]]] represents?

18:07 justin_smith: papphammar: for multiple lines use a paste site

18:07 melladric: it's a tree built up by the individual modifications each specified as a chain of coordinates followed by a value

18:08 well a kind of a tree at least

18:09 papphammar: I'm trying to translate the JS-code to CLJS, but I'm stuck...

18:09 here are the code: fmAixmtTv6Buv3ftjwzVPu

18:09 oops

18:09 paste.ofcode.org/fmAixmtTv6Buv3ftjwzVPu

18:09 melladric: Ok, I'll try without using zippers after all, actually I'll compare both ways and see the better one (using my worst case input). Thank you agian for the guidance.

18:10 justin_smith: papphammar: that can't be a proper tail recursive function since it branches out to the children

18:12 papphammar: I have tried loop/recur and... seq

18:12 justin_smith: papphammar: but it could be something like (fn measure [item, size] (if-let [s (:size item)] (apply + s (map measure (:children item))) size))

18:13 pretty straightforward translation I'd say

18:15 , ((fn measure [item, size] (if-let [s (:size item)] (apply + s (map #(measure % 0) (:children item))) size)) {:size 4 :children [{:size 2 :children [{:size 5}]}]} 0)

18:15 clojurebot: 11

18:15 justin_smith: papphammar: that's correct, no?

18:16 papphammar: I'm not that familiar I'm not that familiar with clj yet, but would that code example take into account multi levels of children?

18:16 justin_smith: papphammar: I used your input

18:16 {:size 4 :children [{:size 2 :children [{:size 5}]}]} is the clojure version of {size:4, children: [{size: 2, children:[{size: 5}]}]}

18:17 papphammar: the items in ":children" vectors can also have children... and so on.

18:17 justin_smith: papphammar: they do!

18:18 right there in the call I sent to clojurebot, I used your example input

18:19 {:size 4 :children [{:size 2 :children [{:size 5}]}]} is the clojure version of {size:4, children: [{size: 2, children:[{size: 5 :children [{:size 42} {:size 666}]}]}]} ; even more nesting

18:19 errr

18:20 , ((fn measure [item, size] (if-let [s (:size item)] (apply + s (map #(measure % 0) (:children item))) size)) {:size 4 :children [{:size 2 :children [{:size 5 :children [{:size 42} {:size 666}]}]}]} 0) ; even more nesting, I mean

18:20 clojurebot: 719

18:21 papphammar: oh wait... I think I forgot somehting in the code...

18:22 justin_smith: oh?

18:26 papphammar: simplified it

18:26 ,(defn measure [item] (apply + (:size item) (map measure (:children item))))

18:27 clojurebot: #'sandbox/measure

18:27 justin_smith: ,(measure {:size 4 :children [{:size 2 :children [{:size 5 :children [{:size 42} {:size 666}]}]}]})

18:27 clojurebot: 719

18:27 justin_smith: the size arg is never actually needed

18:29 papphammar: wow, that was a beautiful line of code. And it seems to work just my js-example.

18:29 justin_smith: it's pretty close!

18:29 clojure can be elegant

18:29 papphammar: I like clj/lisp more and more...

18:49 justin_smith: Got time for one more small question? I'm playing around with your code and trying to print the size (incl. descendants) for each item...

18:56 justin_smith: papphammar: you could either use let bindings or use doto

18:58 papphammar: I'll try that... thanks!

19:01 justin_smith: ,(inc (doto 2 println))

19:01 clojurebot: 2\n3

19:07 gojiberry: How can I transform a seq of strings (e.g. ["a" "b"]) into an InputStream?

19:08 justin_smith: gojiberry: would reading that InputStream get you "ab" ?

19:08 gojiberry: justin_smith: yup!

19:09 justin_smith: ,(slurp (java.io.ByteArrayInputStream. (.getBytes (apply str ["a" "b" "foo"]))))

19:09 clojurebot: "abfoo"

19:09 justin_smith: so yeah, ByteArrayInputStream / getBytes

19:09 gojiberry: justin_smith: but what if (apply str ...) won't fit in memory?

19:09 justin_smith: hmm...

19:10 you could do something with a loop and reify I guess...

19:10 much trickier, unless there's a trick I don't know here

19:15 amalloy: into a stream? not a reader?

19:16 anyway https://github.com/ninjudd/io/blob/develop/src/flatland/io/core.clj#L30 concats streams

19:17 so just turn each string into a stream,and then construct the concatenation of those strings

19:17 streams

19:17 justin_smith: amalloy: woah, one step ahead of me, I was just playing with SequenceInputStream and was about to ask if anyone knew how to make an Enumeration out of a lazy-seq

19:18 which is exactly what that code does, of course

19:18 amalloy: yeah

19:18 turns out it's not hard

19:19 justin_smith: I'm gonna have to remember clojure.lang.SeqEnumeration

19:19 amalloy: flatland.io also has the rather nice, imo, flatland.io.core.InputStream, an implementation of java.io.InputStream that you can reify instead of proxy

19:20 justin_smith: ,(slurp (java.io.SequenceInputStream. (clojure.lang.SeqEnumeration. (map #(java.io.ByteArrayInputStream. (.getBytes %)) ["a" "b" "c" "foo"]))))

19:20 clojurebot: "abcfoo"

19:24 Somelauw: I don't think there is a debian version of leiningen as they say here https://github.com/technomancy/leiningen/wiki/Packaging

19:25 justin_smith: Somelauw: even if there is on, don't use it

19:26 Somelauw: the only global install leiningen needs is the jvm, and it works out better for lein to be a per-user install not system wide, in ~/bin/

19:26 Somelauw: okay, then how do I keep the leiningen script up to date?

19:27 justin_smith: "lein update"

19:27 it's a dependency managing tool, it's good at updating its own version

19:27 noncom|2: pomegranate?

19:28 Somelauw: nice

19:29 noncom|2: is there a core function to get into an ns *only* if the ns exists?

19:30 justin_smith: #(when (find-ns %) (in-ns %))

19:31 ,(clojure.repl/apropos #"ns$")

19:31 clojurebot: (clojure.core/all-ns clojure.core/booleans clojure.core/chunk-cons clojure.core/cons clojure.core/create-ns ...)

19:33 justin_smith: noncom|2: it might be handy to do (fn [n] (require 'n) (when (find-ns n) (in-ns n))) - I'd assume you would always want to load it if possible

19:33 oops, extranious ' in there, of course

19:33 noncom|2: ah, i see

19:33 were you talking about pomegranate that it can update itself?

19:33 just interesting

19:34 justin_smith: noncom|2: well, leiningen does use pomegranate for deps and such

19:34 and yeah, I think it uses pomegranate to update itself

19:34 noncom|2: yeah, i know but just interesting if i ever use this functionality (and i might) - that'd be good to know

19:35 justin_smith: pallet/alembic is a handy way to use pomegranate - let's you use a syntax like lein

19:35 noncom|2: wow

19:36 justin_smith: also it lets you load a dep (and all that deps deps) into a repl for experimentation

19:43 gojiberry: justin_smith amalloy thanks a lot, guys! That one was tricky

20:15 Somelauw: does emacs cider mode have an alternative for m-tab, because this maps to alt+tab for me?

20:16 justin_smith: Somelauw: sure, if nothing else you can use Escape, tab

20:16 Somelauw: I use a plugin that captures escape :-(

20:16 justin_smith: Windows+tab or command+tab can be made to work too

20:17 Somelauw: I have control + tab would be okay.

20:59 neoncontrails: I keep hitting a wall while trying to debug my Postgresql app. I know that I need to somehow wrap the queries in a (.try (sql/insert! <myquery>) (.catch e)) block format

20:59 otherwise there is no error message, only "BatchUpdateException Batch entry 0 CREATE TABLE testing (data text) was aborted. Call getNextException to see the cause. org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError (AbstractJdbc2Statement.java:2762)"

21:00 I'm not sure how to pass those methods to Java, though. In what format does it expect them?

21:14 noncom|2: neoncontrails: (try ... (catch Exception e ...)) ?

21:15 can someone remind me, how do i tunnel nrepl through ssh ?

21:15 neoncontrails: noncom|2: do the args not have to be prepended with a dot?

21:16 *prefixed oh god I've started making up words

21:16 noncom|2: neoncontrails: no, like (try (println "i may throw up!") (println "meee toooo") (catch Exception e (println "someone threw it up! " (.getMessage e)))))

21:23 neoncontrails: noncom|2: thank you thank you it never occurred to me the dot in (.getNextException e) was passing the method to the *exception* object

21:24 noncom|2: neoncontrails: yah, don't forget that in all oop languages, like java, every non-static method implicitly takes "this" as its [first] argument

21:24 here we see this.

21:53 justin_smith: noncom|2: tell nrepl to use a specific port, and then use the -R argument to ssh to map that port from the remote host to your own machine

21:54 noncom|2: simplest version is -R 4444: but you can change the port it maps to on your own side (the righthand 4444)

21:54 noncom|2: cool! thanks!

21:55 justin_smith: noncom|2: if you don't tell nrepl to start on a specific port, then you have to start a connection after the nrepl process starts, and make sure you map the port it used

21:55 noncom|2: yeah right

21:59 gonna save this instruction somewhere this time

22:00 justin_smith: noncom|2: ssh with -R can also be used to access a db that is only accessible from another host (even if it's not running on that host) by changing the arg to the host you want to hop to

22:02 noncom|2: heh, useful things :) leaning over time..

23:07 amalloy: justin_smith: -R seems like the much harder way to do that than -L

23:08 justin_smith: oh did I flip those again

23:08 my bad

23:09 amalloy: -L [bind_address:]port:host:hostport Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side.

23:10 -R [bind_address:]port:host:hostport Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side.

23:10 when I look at those two, -R sounds like the right one

23:21 I'm probably reading "forwarded to" backward

23:25 I know this isn't a politics channel, but someone made a topical joke mentioning clojure about the debate tonight https://twitter.com/ra/status/688932984888659969

23:50 rhg135: yeah, -R would be for a server that's running on the box with the client

Logging service provided by n01se.net