#clojure log - Apr 11 2015

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

0:15 TimMc: Lewix: "Speed" is not a well-defined measure for programming languages.

0:21 scottj: Lewix: there's https://www.techempower.com/benchmarks/ but don't take them too seriously, who wrote each test, what libraries they use, etc can all make a huge difference.

0:21 Lewix: is it still valid http://martinsprogrammingblog.blogspot.ca/2012/02/why-is-clojure-so-slow.html

2:20 Shayanjm: What's the easiest way to debug & figure out why lein uberjar is hanging?

2:21 adu: Shayanjm: some kind of jvm profiler?

2:25 amalloy: Shayanjm: it's almost certainly hanging because you are doing something side-effectful at the top level of a namespace, such as starting up a webserver

2:26 Shayanjm: amalloy: it's hanging on a file which only serves as a place where functions that interface with outside APIs are defined

2:26 i.e: "get-twitter-data"

2:42 netroby: Can you try strace -f -v -t -p 6565 ? strace will dump the syscall for any running program, it will show some very detail calling.

3:25 sveri: Hi, I have a dependency declared in :plugins of the leiningen build. Now, my dependency needs some other dependency in the classpath ([com.h2database/h2 "1.4.185"]), which I have also declared in the :dependency section. But now, when I run lein my-plugin doit it's telling me it misses [com.h2database/h2 "1.4.185"]. Does plugin execution recognize :dependency declarations?

3:29 TEttinger: sveri, you may need a :dev-dependency

3:29 but if that plugin has a dep, it should download it as a transitive dependency, you don't specify it

3:30 I'm not sure quite how the problem is happening

3:32 sveri: TEttinger it's a bit hard to explain. Plugin A provides some database thingy and as usual I don't want to include all database drivers like h2, mysql and whatnot, but instead, the application B that uses plugin A should provide the dependency. So I put the h2 into the :dependency section of application B and the reference to the plugin A into :plugins section

3:39 Adding h2 to the dev-dependencies section of application B does not work either

3:45 TEttinger: sveri, I think the problem is Plugin A can't see what dependencies Application B has declared, so if the plugin itself needs a dependency that isn't being satisfied by what Plugin A can see with its own project.clj, it will encounter an error. I haven't worked much with plugins though

3:45 Plugin A is something you're writing?

4:19 sveri: TEttinger, yea, I have both in my hands

6:19 arav93: How does clojure.repl/demunge work? I read the doc, but I did not really understand much.

6:21 Bronsa: ,(clojure.repl/demunge "foo$bar_baz")

6:21 clojurebot: "foo/bar-baz"

6:22 arav93: OK, thanks! :) Bronsa

8:03 sobel: so...which emacs for os x?

8:04 there are so damn many

8:07 justin_smith: sobel: this is the one I used when I used osx - http://emacsformacosx.com/

8:07 "No Extras! No Nonsense!"

8:08 I remember the other ones being terrible

8:08 because they used OSX conventions instead of default emacs behaviors

8:38 fakedrake: hello

8:38 netroby: Install homebrew first, then brew install emacs

8:39 sobel: netroby: why is that better than emacsformacosx' distribution?

8:39 fakedrake: I am trying to install cider/cider-nrepl, I put the line the docs tell m in ~/.lein/project.clj and then I go to a random project and `lein repl` I just get a repl. Nothing seems to get installed.

8:40 justin_smith: fakedrake: it's profiles.clj

8:41 fakedrake: and to get the cider experience you would connect via cider-jack-in from emacs

8:41 fakedrake: justin_smith: oooh right, thanx!

8:42 justin_smith: how come jack-in is not done automatically like jedi does in python?

8:43 justin_smith: I guess because clojure processes don't come cheap like python ones do

8:44 fakedrake: ok

8:45 sobel: there's more to it than just perf, but that's fair too

8:46 justin_smith: sobel: I don't mean perf, I mean, like the amount of ram each repl uses, startup time, etc.

8:48 sobel: true, true, but even more broadly those are all runtime performance characteristics aren't they? :)

8:50 i like repls because of interactivity. like, i'm mulling adding cider to a java project just so i can hop in the running app and prototype at runtime

8:55 hm, emacs seems to be having a hard time updating packages :(

9:03 justin_smith: sobel: as in, things break?

9:09 fakedrake: hmm, it's a bit strange that an empty string evaluates to true, especially for a lisp

9:12 ticking_: fakedrake: how so? empty string is not nil or false

9:12 everything else is true

9:12 even empty list

9:12 ,(boolean '())

9:12 clojurebot: true

9:12 fakedrake: ticking_: well I assumed an empty list would be nil

9:13 ticking_: fakedrake: yeah it's a bit confusing when comming from another lisp)

9:13 :)

9:13 fakedrake: ticking_: like in elisp and i IIRC scheme

9:14 ticking_: fakedrake: yeah, it's probably because clojure doesn't really revolve all around cons cells

9:15 but it actually makes some if checks easier :)

9:15 fakedrake: oh well.. I ll get used to it I guess

9:18 ticking_: fakedrake: thats the spirit ;)

9:20 vpm: fakedrake: anyway the empty string isn't nil in elisp nor in common lisp

9:21 fakedrake: vpm: hmm... (eq '() nil) => t

9:21 vpm: fakedrake: sure. But you were talking about string earlier :-)

9:22 fakedrake: vpm: ah indeed my brain got stuck

9:23 sorry

9:57 I am trying to run a standalone clojure file with 'clj file.clj < input' and I am getting "cannot open <namespace< as an InputStream" (I use (slurp *in*) if it has anything to do with anything)

10:45 justin_smith: fakedrake: can you give a paste of the actual command line and the actual output in the shell?

10:49 fakedrake: justin_smith: sorry i was typing *ns* instead of *in*

10:52 justin_smith: oh yeah, that would do that

10:52 haha

11:20 sobel: justin_smith: when it tries to update, it never returns from 'contacting host: elpa.gnu.org:80'

11:20 justin_smith: maybe it was down? I see elpa right now

11:23 sobel: i see it too but emacs won't

11:31 or it returns and doesn't clear its display

11:31 can't install cider though :/

12:09 noncom|2: are clojurebot and lazybot simply two different bots with 2 distinct areas of interest?

12:14 Shayanjm: justin_smith: how do you debug why lein uberjar is hanging?

12:14 it seems to be hanging on a file that I use to define functions to get data from APIs

12:14 but that file also doesn't def anything that requires immediate eval

12:15 so not sure what's going on

12:25 noncom|2: Shayanjm: in such cases i usually put many things like (println "[A]") then (println "[B]") into the file between statements, so that i get the exact picture on where exactly does lein hang

12:26 you know, A, B, C, D... and so on

12:26 Shayanjm: Right

12:26 noncom|2: and then you see, did it finish reading the file, or did it stuck. if it finished the file - then there is something else somewhere

12:28 hmmm, i wonder, is it possible to write a macro, that takes the whole file body except the ns clause and interleaves it with such statements..

12:30 razum2um: do I need to close! explicit all go-loop created channels here: https://gist.github.com/razum2um/d3255595a481ceae5745

12:36 Danbell: ,(+ 1 1)

12:36 clojurebot: 2

12:51 justin_smith: noncom|2: a bisect macro even

12:53 noncom|2: wow

12:53 i have a question on lazybot btw

12:53 i am testing my own instance

12:53 justin_smith: noncom|2: OK

12:54 noncom|2: and when i ask "seen" it says "seen quitting" but instead of date and time, it says "Read error: Connection reset by peer 1 minute and 27 seconds ago."

12:54 and the time is counting up

12:54 idk what's that

12:54 justin_smith: $seen rhickey

12:54 lazybot: rhickey was last seen quittingQuit: rhickey 4 weeks and 4 days ago.

12:55 noncom|2: wow this man even comes here

12:55 justin_smith: noncom|2: that looks normal to me - "connection reset by peer" is a normal disconnect reason

12:56 noncom|2: ok but why does not it show time

12:56 or is that time - the time?

12:56 ah

13:22 engblom: With Android 5.x and the move away from Dalvik, how is the performance of Clojure on Android?

13:24 xphillyx: Hi all. Two questions. I'm relatively new to clojure and find myself using a lot of lets and letfns, often together. Is it more idiomatic to only use lets in this scenario and define the value as (fn [whatever] (…)) ? Secondly, are there any good resources for learning to write more idiomatic clojure?

13:24 mfikes: engblom: Not an answer to your question, but an alternative to consider in the future is React Native on Android, using ClojureScript.

13:26 noncom|2: xphillyx: personally i would avoid doing much

13:26 * doung much letfns

13:26 i mean, defns are better

13:27 xphillyx: I'm working on 4clojure problems at the moment, so defn isn't an option in this particular case, but that's good to know for the future.

13:28 nicferrier: my clojure workflow seems to prevent me making lots of files in a module.

13:28 because each one needs a new repl.

13:28 there must be a better way to do that.

13:28 justin_smith: why a repl per file?

13:29 nicferrier: justin_smith: because it's annoying switching a repl between namespaces

13:29 xphillyx: noncom|2: would a good rule of thumb be to make things a defn by default? Even if the functionality is only needed in the particular function it is located in?

13:29 justin_smith: nicferrier: (in-ns 'some-other-ns)

13:29 nicferrier: what I'd really like is if I could have multiple repl buffers but connected to the one clojure instance.

13:30 justin_smith: nicferrier: but usually I just use require with a short alias

13:30 nicferrier: yes, that's possible easily with nrepl

13:30 nicferrier: justin_smith: I know... but don't you find even that tedious.

13:30 noncom|2: xphillyx: i think that except for simple predicates - yes.

13:30 nicferrier: justin_smith: I'm not using nrepl.

13:30 justin_smith: nicferrier: I actually don't switch out of user usually

13:30 noncom|2: but again, that's my personal opinion

13:31 justin_smith: nicferrier: I require my namespaces with an alias

13:31 nicferrier: justin_smith: ok. fair point.

13:32 justin_smith: nicferrier: oh now I remember, you don't use nrepl for security reasons. But why not use lein repl locally? it doesn't need to be a project dep.

13:32 noncom|2: xphillyx: to avoid exposition of ns-private functions, you can just postfix them with "-"

13:32 like private-fn-

13:32 nicferrier: justin_smith: that's not why I don't use nrepl. I just found nrepl to be a bit tedious.

13:33 xphillyx: noncom|2: Oh that's neat. I like that.

13:33 nicferrier: justin_smith: I just start a repl and have emacs manage the process better.

13:34 oakwise: dnolen: Does cljs.test not have a way to get the report summary map anymore? CLJS-988 appears to have removed that functionality and (run-tests) and (run-all-tests) always return nil now?

13:34 nicferrier: justin_smith: but yeah. I think not selecting a namespace is actually quite a good idea.

13:34 justin_smith: when you eval from a source buffer how do you do that?

13:35 justin_smith: nicferrier: I either use (require 'some.ns :reload) or I copy paste some small snippet for testing it out

13:39 nicferrier: justin_smith: so let me understand this... with :reload... you have a buffer, you save it and then you require :reload in your repl and you get the new defn. you don't C-x C-e it?

13:39 justin_smith: right

13:39 I mean C-x C-e might work? I don't use it.

13:39 nicferrier: justin_smith: it does with cider and with my lein stuff.

13:40 justin_smith: nicferrier: yeah, I ditched cider

13:40 nicferrier: it's trivial to implement, you just send the code to the process.

13:40 clojurebot: Titim gan éirí ort.

13:40 justin_smith: nicferrier: if you are using cider you are using nrepl

13:40 btw

13:40 nicferrier: justin_smith: I'm not.

13:40 justin_smith: I just told you what I did :-)

13:40 either way though... C-x C-e is simple to implement.

13:41 but it kinda requires that you have a "current" namespace

13:41 justin_smith: there's always a current namespace

13:41 nicferrier: I guess I could associate a namespace with a buffer.

13:41 justin_smith: I just keep user

13:41 nicferrier: justin_smith: sure. but other than user I mean.

13:42 cider seems to promote the same thing as I do... which is to switch the ns.

13:42 justin_smith: last I checked that's what cider did, it had some elisp code to find and parse the ns form

13:42 it doesn't change the ns of your repl, it just makes sure code from that buffer is loaded with that ns current

13:42 nicferrier: it can do that... it doesn't do that for C-x C-e.

13:43 justin_smith: ah, really? I hadn't noticed that.

13:43 I could easily do that. but I quite like the idea of your reload.

13:44 justin_smith: nicferrier: easy enough to attach the reload to a smart elisp binding I bet

13:44 nicferrier: when I reload an ns presumably that reload causes all the other ns' importing that ns to see the new one?

13:44 justin_smith: a key combo that does a save / reload of current buffer

13:44 nicferrier: exactly

13:45 nicferrier: justin_smith: or even on change. check for sexp-correctness or something.

13:45 that would promote a sort of error noticing flow.

13:45 justin_smith: sure, that could easily be an option

13:45 nicferrier: like a flymake

13:45 justin_smith: right

13:45 nicferrier: hmmm. good ideas. thanks mate. I'm going to go and get some milk and have a think.

13:49 xphillyx: Btw that whole conversation you all just had totally reaffirms my decision to learn a lisp, that's so powerful to be able to just modify your editor to work for your particular workflow in the language you're doing.

13:50 justin_smith: xphillyx: the drawback is that it is just easy enough to have a perfect workflow that I spend time that could be productive time perfecting my workflow instead :)

13:51 xphillyx: justin_smith: Just have to be careful to only scratch itches to when you can't bear them anymore. Not like that line is extremely blurry or anything...

14:05 noncom|2: how to make lazybot remember and recall facts?

14:06 justin_smith: noncom|2: addtopic

14:06 noncom|2: requires permissions by default

14:07 well addtopic to add the fact, and help to recall it

14:08 noncom|2: how to authorize with lazybot? (my local one)

14:08 justin_smith: it's /msg bot-name login your-password

14:08 the password is setup in the config file

14:09 noncom|2: also, why does it answer my "google" request in private, but does not answer in a public chat?

14:09 justin_smith: sounds like a bug?

14:09 $google lazybot google

14:09 lazybot: [LazyBot - Android Apps on Google Play] https://play.google.com/store/apps/developer?id=LazyBot&hl=en

14:23 constl: Hello, when you define a high-order function that takes one arguement and it has inside an inner function which also takes one arguement. How do you pass the argument for the inside fn ?

14:24 justin_smith: constl: ##((fn [f x] (f x x)) list 42)

14:24 lazybot: ⇒ (42 42)

14:24 justin_smith: ,((fn [f x] (f x x)) + 42)

14:24 clojurebot: 84

14:25 amalloy: constl: you don't (indeed can't) use #() for both of them

14:26 justin_smith: amalloy: oh yeah, that's likely what they meant

14:26 constl: Can i paste a link to the code I'm having trouble putting my head around ?

14:26 justin_smith: sure, just no multi line pastes into this channel itself of course

14:26 constl: https://www.refheap.com/62d20d45b8b29609e99261c79

14:27 justin_smith: that looks cromulent

14:28 though the definitions of "username" and "balance" could be replaced by :username and :balance

14:28 constl: It's a snippet from "Clojure in action"

14:28 justin_smith: OK

14:28 constl: I don't get the sorter-using function

14:28 I see it takes one argument

14:28 justin_smith: right

14:28 and what does it return?

14:28 constl: and its inside function also takes an argument

14:28 justin_smith: indeed it does

14:29 but what does it do with that inside function?

14:29 it doesn't call it

14:29 it returns it

14:30 ,(defn adder [x] (fn [y] (+ x y)))

14:30 clojurebot: #'sandbox/adder

14:30 constl: justin_smith: You are a wizard! Got it

14:30 justin_smith: ,(def f (adder 42))

14:30 clojurebot: #'sandbox/f

14:30 justin_smith: ,(f 12)

14:30 clojurebot: 54

14:30 justin_smith: constl: this is a common functional programming idiom

14:31 to make a function whose purpose is to create a new function that you would assumedly use more than once

14:34 constl: ,(doc adder)

14:34 clojurebot: It's greek to me.

14:34 justin_smith: constl: for doc to work I would have needed to add a doc string

14:35 constl: or did you not notice I defined it just now?

14:35 constl: missed yeah

14:37 ,((adder 12) 12)

14:37 clojurebot: #error{:cause "Unable to resolve symbol: adder in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: adder in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: adder in this context", :at [clo...

14:37 justin_smith: constl: it clears definitions regularly

14:38 ,(defn adder [x] (fn [y] (+ x y)))

14:38 clojurebot: #'sandbox/adder

14:38 justin_smith: now try

14:38 constl: ,((adder 12) 12)

14:38 clojurebot: 24

14:38 justin_smith: constl: we have a special function for this, call "partial"

14:38 benjyz1: hello - simple question. I'm trying to write a macro which contains "with-open"

14:38 justin_smith: ,(def adder' (partial +))

14:38 clojurebot: #'sandbox/adder'

14:39 justin_smith: ,((adder' 21) 21)

14:39 clojurebot: #error{:cause "java.lang.Long cannot be cast to clojure.lang.IFn", :via [{:type java.lang.ClassCastException, :message "java.lang.Long cannot be cast to clojure.lang.IFn", :at [sandbox$eval143 invoke "NO_SOURCE_FILE" -1]}], :trace [[sandbox$eval143 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784] [clojure.lang.Compiler eval "Compiler.java" 6747] [clojure.core$eval invo...

14:39 justin_smith: oops!

14:39 haha, of course, it would not work in this case

14:39 ,(defn adder' [x] (partial + x))

14:39 clojurebot: #'sandbox/adder'

14:39 justin_smith: ,((adder' 21) 21)

14:39 clojurebot: 42

14:40 benjyz1: (with-open [x (opencontext)]

14:40 ...

14:40 justin_smith: benjyz1: is it complaining about that x inside ` and binding namespaced symbols?

14:41 benjyz1: sth like that, yes. I'm new to macros, so struggling a bit

14:41 justin_smith: benjyz1: ` always fully qualifies symbols

14:41 benjyz1: I know something should be quoted

14:41 constl: Thanks justin_smith, it's clear to me

14:41 justin_smith: benjyz1: to create bindings, add # to the end of the binding name

14:42 so replace all instances of x in your macro with x#

14:42 what creates a special generated symbol

14:42 a "gensym" if you will

14:42 benjyz1: >> Unable to resolve symbol: ctx in this context

14:42 justin_smith: benjyz1: can you paste your code?

14:42 to refheap.com I mean

14:43 benjyz1: (defmacro srv [exp]

14:43 (with-open [ctx# (zmq/context 1)]

14:43 exp))

14:43 justin_smith: oh, yeah, you need `

14:43 I thought you were using that already

14:44 also, please don't paste multi-lines here, use refheap.com

14:44 benjyz1: ok, thx

14:44 now I get Can't let qualified name

14:45 justin_smith: ctx# should have fixed that

14:45 but exp will need to be ~exp

14:46 benjyz1: trying. I also read that is something like gensym

14:47 justin_smith: yes, it is actually exactly that

14:47 benjyz1: https://www.refheap.com/99511

14:48 justin_smith: but if you expect exp to refer to ctx, 1) that's usually a bad idea to write code that way, and 2) it will actually require weird quoting

14:48 benjyz1: I see. I basically want to avoid needing with-open everywhere

14:48 justin_smith: benjyz1: for that code to work, exp needs to become ~exp, and ctx# needs to be ~'ctx

14:53 benjyz1: no luck. I guess I have to read through more examples to understand what is going on

14:53 thx

14:53 justin_smith: benjyz1: you can see what ` does from the repl, outside a macro

14:55 ,(let [exp '(mainreq ctx)] `(with-open [~'ctx (zmq/context 1)] ~exp))

14:55 clojurebot: (clojure.core/with-open [ctx (zmq/context 1)] (mainreq ctx))

14:55 justin_smith: benjyz1: ^ as you can see, that expands to exactly the form you want

14:57 benjyz1: very cool

15:00 justin_smith: there's also macro-expand, but I find the "convert the macro to a let block" trick is often useful for quick experimentation

15:00 you just fix the contents until the output is the code you want to run

15:01 which not coincidentally works nicely with how macros are designed

15:04 benjyz1: thx again. I don't understand ~'ctx is this not unquote and quote at the same time?

15:04 justin_smith: the trick is that it gives you back ctx as a symbol

15:05 and not what ` would create

15:05 `(ctx)

15:05 ,`(ctx)

15:05 clojurebot: (sandbox/ctx)

15:05 justin_smith: see what it does there?

15:05 ,`(~'ctx)

15:05 clojurebot: (ctx)

15:06 justin_smith: what we're doing with the weird quote / unquote is disabling the sanity mechanism of `

15:06 Lewix: doesnt netflix use clojure in their backend

15:06 justin_smith: benjyz1: which is why I was saying above that this wasn't actually a good idea usually. The problem is that you can end up with code where thanks to weird macros you have no idea where the bindings you refer to are coming from.

15:07 it's really bad for referential transperency

15:07 benjyz1: ok, I see. in this case context is strongly tied to a namespace

15:07 justin_smith: benjyz1: for example, if you had a bigger code base and I saw (mainreq ctx) I would be like "what the hell, what is ctx and where did it come from?"

15:07 right

15:07 but that's the general danger

15:08 when abused systematically it can lead to really hard to understand code

15:08 so the default is to namespace qualify things

15:08 benjyz1: ok. I will have to experiment quite a bit. clojure is pretty awesome even without macros

15:08 xphillyx: Lewix: Netflix has a very microservice-ey architecture and so they let teams pick their own languages for various projects to fit the problem domain. Some teams use clojure and Netflix has some clojure open source libraries published to their GitHub page.

15:13 Lewix: xphillyx: i thought 90% of their back end and most their services were in clojure

15:15 xphillyx: I read an article where they were moving all their java sercices to clojure

15:15 xphillyx: I don't work for them and so I can't comment on numbers, but I do know they have a lot of Java in their open source offerings, much less clojure. That may or may not be indicative of anything.

15:16 My understanding of their engineering culture though is that language mandates wouldn't fly.

15:32 nicferrier: justin_smith: I never really have a problem balancing my tooling from my making.

15:32 at least, I dont think so.

15:46 sobel: gah.. i wanna love nginx-clojure but the latest release expects me to slide back to jvm1.6 and clojure 1.5.1

15:47 i had it running with 1.8 / 1.6 on an older version of nginx-clojure. this new release makes negative sense.

15:52 justin_smith: http://www.developermemes.com/wp-content/uploads/2014/09/Web-Developer-With-A-Job-Web-Developer-Without-A-Job-Meme.jpg

16:03 programisto: jjvia google i'm not finding exactly what i'm looking for

16:03 is there a clojure library which runs a function upon file changes?

16:03 as in moinotring a direcotry for changes and running when that happens?

16:04 justin_smith: yeah, theres a lib for that, one moment I contributed to it but I forgot the name

16:04 programisto: https://github.com/ToBeReplaced/nio.file

16:05 programisto: justin_smith: perfect, thanks

16:13 oddcully: programisto: i interoped to commons FileAlterationMonitor

16:20 arohner: are there any libraries for dealing with outstanding futures?

16:21 I have a Component that I'm starting & stopping during each test, and the test code uses futures that depend on the component. For test reliability, I'd like to deref all futures before the component stops

16:26 justin_smith: arohner: how does dereffing a future affect reliability?

16:26 arohner: justin_smith: because then the component won't stop while the future is in-progress

16:27 justin_smith: aha, you don't want to restart the component if a future isn't done yet, so you want to wait on your futures

16:27 makes sense

16:53 not-much-io: There is nothing in the clojure style guide about aligning indentatons of lets. To me it seems this would help readability. Is there a reason to not do it? example: https://gist.github.com/not-much-io/f62b4cab7239c7a67ae4

16:56 justin_smith: not-much-io: the style guide I am thinking of actually does mention that, and suggests not doing it

16:58 not-much-io: oh, I must be misremembering, or it was changed

17:02 not-much-io: justin_smith: I would think this should have been mentioned. I'll search the commits. But any idea why this would be discouraged? Due to less room for longer lines probably? Unless using a mix of indenting and not, which is probably not good.

17:06 justin_smith: Here is the discussion https://github.com/bbatsov/clojure-style-guide/issues/10

17:11 justin_smith: ahh, so I was remembering correctly, at least partly so

17:11 cfleming: not-much-io: Diff noise is the main argument against that. That said, Cursive supports it (and aligning map values), and most people like it. I'm not sure it should be made a canonical recommendation though.

17:14 not-much-io: cfleming: Yes I see now, as discussed in the issue thread. I'll keep that in mind, while I use it.

17:15 cfleming: not-much-io: As someone pointed out, a decent diff tool should allow you to hide the whitespace-only changes. You'll still get changed lines in git reports etc though.

17:17 not-much-io: cfleming: Noted. :)

18:12 nicferrier: I am writing a program that needs to talk to an artifact repository.

18:12 can I reuse code from lein that does the auth and stuff?

18:15 I guess boot would be ideal here.

18:40 __chris: hello

18:40 i am in my first 20 minutes of clojure

18:41 Im struggling with how I would do a rand-int within a range.

18:41 Im guessing I can do (pseudo code) while < 1 rand-int 7

18:42 can someone help me with this?

18:45 Shayanjm: justin_smith: I think you mentioned using ssh -L to connect to a remote REPL which gets spun up inside of -main

18:45 For some reason, if I try running the jar file, I can't connect to the tunnel

18:45 I can only connect if I run it with lein run (therefore can't nohup and persist outside of session)

18:45 dnolen`: ,(rand-nth (range 1 7))

18:46 clojurebot: 4

18:46 Shayanjm: If I try connecting when running the jar, I get "channel 4: open failed: connect failed: Connection refused". Any ideas?

18:49 Glenjamin: sounds like your repl isn't actually listening

18:49 Shayanjm: Glenjamin: but I can connect when it's run via lein run

18:49 ticking_: dnolen`: say, is there a reason behind core.match not handling multiple inputs simply as a vector match?

18:50 Shayanjm: Am I supposed to do something special in my -main other than (defonce server (start-server :port 7888))?

18:50 dnolen`: ticking_: I don't know what you're asking

18:50 ticking_: dnolen`: I'd be interested in fixing it and making the behaviour more consistent but wonder if its intentionally

18:52 sorry, (match [1 2] _ "hi") will fail with "Pattern rows must be wrapped in []", while (let [x [1 2]] (match x _ "hi")) returns "hi"

18:53 dnolen`: I wonder if that's intentional

18:53 dnolen`: ticking_: the second is sugar, the vector is always implicit

18:53 Shayanjm: Glenjamin: What's weird is that it runs through the rest of the program

18:53 but i can't connect to the repl which is def'd at the very top of -main

18:53 dnolen`: ticking_: and no I'm not interested in this change, much higher

18:53 priority things that need fixing.

18:54 ticking_: dnolen`: well, seemed like an easy PR for getting familiar with the codebase :D

18:56 Shayanjm: But I can connect to it fine if I use 'lein run' instead of 'java -jar <jarfile>'

19:09 justin_smith: Shayanjm: the problem is that you have the repl defined at the top level in a def

19:09 Shayanjm: you need to start the server inside -main

19:10 using a def to create a server is a top level side effect, and that doesn't play nicely with distributed jars

19:11 Shayanjm: oh wait, the defonce is inside -main?

19:12 defonce inside a function is not a great idea (the var is created as soon as the function is compiled), but it should have worked if you did it that way

19:36 cfleming: nicferrier: You could use pomegranate, which is what lein uses under the hood

19:38 nicferrier: You could also check out pallet/alembic which I think is similar - I'm not sure what distinguishes them

19:39 nicferrier: Both use aether under the hood I believe

19:40 Am I correct in thinking that the only way you can create a closure in Clojure (ba-doom *tschh*) is with fn or reify?

20:13 Shayanjm: justin_smith: yeah defonce is in main

20:46 justin_smith: cfleming: let also make a closure

20:48 cfleming: justin_smith: Really? How does that work?

20:48 justin_smith: let doesn't define a class

20:49 justin_smith: cfleming: it closes over the bindings so that any of them that escape scope can refer to one another

20:49 cfleming: maybe I'm not getting something here

20:50 cfleming: justin_smith: Can you give me an example of what you mean?

21:00 justin_smith: cfleming: come to think of it, I guess you would need a function to escape the let block to access any of the values.

21:00 or equivalently a protocol method or defmethod etc.

21:00 cfleming: justin_smith: Right, the let block itself doesn't create the closure

21:01 justin_smith: for some reason I always thought of the let as being the thing that creates a closure, but of course you need a function of some sort to access it

21:01 cfleming: Yeah, the let block itself isn't actually doing the capturing, just providing the locals to capture

23:13 mindbender1: Is there a way to remove a name from a namespace?

23:21 Got it. ns-unmap

23:21 LaVidaPortland: Example: (ns-unmap *ns* 'foo)

23:21 mindbender1: thanks.

Logging service provided by n01se.net