#clojure log - Feb 05 2016

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

2:12 macrolicious: how/can I access clojure language documentation inside emacs? ex. for 'recur' ?

2:12 justin_smith: ,(doc recur)

2:13 clojurebot: excusez-moi

2:13 justin_smith: macrolicious: anyway, there is a function clojure.repl/doc that is often helpful

2:13 there's some mode that makes it pop up automatically as part of cider

2:14 macrolicious: ok, thx

2:43 scottj: macrolicious: C-c C-d d when on a function name, if using cider. recur is a special form, so may not work like most functions/macros.

2:43 macrolicious: oh man, bam!

2:43 thanks, that's sweet.

2:44 every day, learning emacs is like finding something cool you didn't know you owned

2:45 ridcully_: the same is true for vi, but there you discover it by typos

2:48 macrolicious: to be honest, I've found a few things by typos so far in emacs, too ;-)

2:49 well, key bindos

4:11 kungi: Anyone else experiencing problems when trying to connect to nrepl after updating to version 0.2.12?

4:11 I get the following error: SocketException The transport's socket appears to have lost its connection to the nREPL server

4:13 adam____: I am using 0.2.12 and it seems to be working fine

4:14 are you using cider?

4:15 kungi: adam____: I tried using cider and lein repl :connect

4:15 adam____: yeah im not going to lie, the setup is a bit painful the first time

4:15 do you have a .lein/profiles.clj

4:15 {:repl {:plugins [[cider/cider-nrepl "0.11.0-SNAPSHOT"]]

4:15 :dependencies [[org.clojure/tools.nrepl "0.2.12"]]}}

4:16 those two version generally work for me

4:16 kungi: adam____: Ok wait a second. Let me clarify the problem a bit more. I have a working development setup. In my app I am using (nrepl/start-server) to start an nrepl server.

4:17 This one I cannot connect to any more

4:17 adam____: hmm, sorry I don't know

4:18 maybe check the github page and see if somebody had a similar issue?

4:18 kungi: adam____: tools.nrepl does not use github issues as far as I see

4:19 adam____: http://stackoverflow.com/questions/20088908/problems-connecting-to-a-clojure-nrepl-with-ring-compojure

5:01 kungi: Downgrading the tools.nrepl version from 0.2.12 to 0.2.6 solved the problem. I will try to find the most recent working version.

5:11 CaptainLex: I am trying figwheel on a fresh lein install on the flappy bird demo and running "lein figwheel" hangs after dependencies are met

5:11 Well, I don't know about hags, but it doesn't output anything

5:13 Scratch that, lein is just misbehaving inside repos

5:20 This is bonkers:

5:20 '$ time lein version'

5:21 'Leiningen 2.6.0 on Java 1.8.0_72-internal OpenJDK Zero VM'

5:21 'real 0m23.441s'

5:21 It takes 23 seconds just to output version

5:21 What could possibly be causing lein to be so slow?

5:21 ridcully_: -SNAPSHOT plugins?

5:21 MJB47_: takes 4 seconds for me

5:21 which while not as extreme, is still odd

5:22 jeaye: real0m2.064s

5:22 MJB47_: is there a hidden progress bar we can disable?

5:22 CaptainLex: I can see why I would interpret this as hanging for anything more complex

5:22 I'm going to try...restarting, I guess?

5:22 Be right back

5:27 CaptainLex_: Well, restarting definitely did not help

5:27 MJB47_: out of interest, what hardware are you running?

5:28 lets say cpu ram ssd/hdd to keep it short

5:29 CaptainLex_: MJB47_: Nothing super respectable- it's a Chromebook. ARM processor, 2 gigs of RAM, 16 gigs of SSD

5:31 MJB47_: Just running up Clojure's JAR on Java doesn't take hardly any time at all, for what that's worth

5:32 MJB47_: thats to be expected

5:33 i was just wondering why it took you 20 something and me 4 seconds

5:33 i have a laptop i7, which might explain it

5:33 but why it would take so long is rather odd

5:34 CaptainLex_: MJB47_: Yeah, 36 seconds to run lein help is more than one can reasonably chalk up to hardware issues, at least to my mind

5:34 MJB47_: indeed

5:35 CaptainLex_: My guess is that something in the environment is out of date, but I grabbed lein from the website and it should be pulling in everything it needs except Java itself

5:35 And I think Java's a good version: 'openjdk version "1.8.0_72-internal"'

5:38 MJB47_: im using Java 1.8.0_25 Java HotSpot(TM) 64-Bit Server VM

5:39 CaptainLex_: Wow, it just took it 10 seconds to tell me "fighwheel" was not a task. It is probably too much to hope that I can get anything done under these circumstances. What's the best way to go about reinstalling lein and its dependencies?

5:45 Oh look, the figwheeling has picked up! I guess for the purposes of the project I need to do I can just be patient

5:45 and just not worry too hard about doing any real dev until I get home to my real computer

6:16 gfdhjf: bad uncle is inserting his penis into 10 year old girl's vagina causing her to moan in agony because they both are niggers

7:01 hyPiRion: amalloy_: ping

7:12 bcoburn: I have a project with three namespaces, call them A, B, and C. A requires B and C. I have a single that I want to have available in all 3 namespaces. What's the easiest way to accomplish this?

7:13 hyPiRion: bcoburn: a single what?

7:14 bcoburn: ph

7:14 function

7:15 typing is hard

7:16 hyPiRion: The easiest way to solve that is to make a new namespace D (usually it's called utils) and require that in all the namespaces.

7:16 But you can also pass the function in as a parameter if that's suitable for your use case.

7:18 bcoburn: I think I'll do the new namespace plan, just sad at having to make another file etc for ~4 lines of code

7:20 hyPiRion: yeah, it feels painful at first. It'll be better if/when you end up having more utility functions though

8:49 python476: hi there

8:52 cider github page mention C-c C-i to inspect value, I believe they meant C-c M-i (using cider 0.10.2, maybe the main page document a previous version though)

8:53 shiranaihito: what's this about: "IllegalArgumentException: interface c2d.struct.IJavaize is not a protocol" -- "IJavaize" is very much a protocol.. i'm trying to extend it to a Record in another namespace

8:54 python476: maybe I should "complain" on github ~_~

8:55 hyPiRion: python476: yeah, I guess that's just a typo

8:55 python476: aight

8:55 it's not an life critical feature, but as any documentation typo, it makes you question your sanity

9:03 hyPiRion: heh

9:14 dysfun: so has anyone tried using emscripten with clojurescript?

9:14 (to use a c library from clojurescript)

9:59 justin_smith: i've changed several projects to using group.package instead of package.core . are you happy now, free-speech-hater? ;)

11:03 kwladyka_: justin_smith ha i understand loggers! thank you for you help and patient. Anyway what do you think about https://github.com/ptaoussanis/timbre to use for logs?

11:50 python476: hi again

11:51 any idea why lein check would hangs at `Compiling namespace ...` ?

11:51 the codebase is two tiny files

11:53 almost no cpu usage, no io ~_~;;

11:55 dysfun: how long has it been hung?

11:55 python476: forgot some effectul network code.. I noobed

11:55 dysfun: minutes

11:55 dysfun: well that's not supposed to happen, obviously

11:55 but if you know your code did it... :)

11:56 python476: the price of free lisp code, I tested a few stuff on the go, and forgot to comment / delete http requests...

12:02 blackbird_: hi, maybe i'm screwing up my thinking here, but if i've def'd a map, and then call a macro with that def'd map, how do i get that map in the macro? is that possible?

12:02 python476: no more idl-ing but still a good minute, odd

12:04 blackbird_: here is an example: https://www.refheap.com/114516

12:17 amalloy: hyPiRion: ?

12:28 rhg135: blackbird_: macros run at compile-time and thus only gets a symbol instead of the map

12:31 blackbird_: rhg135: so is it impossible to get the value of a symbol in a macro? shouldn't something that is def'd be there at compile time?

12:34 rhg135: For eagerly using it with the unquote, no. But if you return a form that operates over the value at runtime, that would work

12:36 blackbird_: rhg135: ok, thanks for the info!

12:37 rhg135: ,(do (def x 1) (defmacro y [i] `(do ~(inc i) nil)) (y x))

12:37 clojurebot: #error {\n :cause "clojure.lang.Symbol cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Symbol cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers inc "Numbers.java" 112]}]\n :trace\n [[clojure.lang.Numbers inc "Numbers.java" 112]\n [sandbox$y invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$y invoke "NO_SOURCE_FILE" 0]\n [clo...

12:38 rhg135: ,(do (def x 1) (defmacro y [i] `(do (inc ~i) nil)) (y x))

12:38 clojurebot: nil

12:40 blackbird_: rhg135: ahh, i can see how that works, still unclear as to why x the value of x there isn't known at compile time, guess i need to read up on what happens when.

12:44 rhg135: It might be known, but the macro gets a symbol. You can do resolve, or other such things, to look it up manually. But that probably is frowned upon.

12:47 blackbird_: rhg135: ok thanks

13:00 WorldsEndless: Is my suspicion correct that {:keys} can't be used twice in the same let statement?

13:00 justin_smith: WorldsEndless: no

13:00 WorldsEndless: hmm... I guess I need to continue debugging

13:01 hiredman: http://clojure.org/reference/special_forms#binding-forms

13:01 justin_smith: ,(let [{:keys [a b c] {:keys [e f g]} :d} {:a 0 :b 1 :c 2 :d {:e 3 :f 4 :g 5}}] [a b c e f g])

13:02 clojurebot: [0 1 2 3 4 ...]

13:03 WorldsEndless: Doh! yet another case of an upload coming through ring that appears to be a map, but is actually a string

13:03 justin_smith: WorldsEndless: sounds like you need a wrap-json middleware or something

13:04 WorldsEndless: Transit is what I'm going for...

13:57 KevinCorcoran: Is EuroClojure going to happen this year?

14:11 arcatan: I'd assume so

14:11 python476: so, I learned about (shutdown-agents)... that's what was blocking lein check

14:11 also (prn ...) isn't threadsafe

14:12 justin_smith: python476: OK, nothing in your namespace should make shutdown-agents neccessary

14:12 LucidTortoise: Anyone here uses Light Table as their primary editor?

14:12 justin_smith: def shouldn't have side-effects

14:12 python476: justin_smith: toying with (future ...)

14:12 hiredman: python476: that means you are launching new threads (agents or futures) as a side effect of code loading, that is generally a bad practice

14:12 justin_smith: python476: yeah, that should be inside your -main or an init of some sort

14:13 python476: sure, but I just I put everything inside functions, and only -main is running them

14:13 justin_smith: python476: then why would you need shutdown-agents in order for lein check to return?

14:13 lein check doesn't run -main

14:13 hiredman: python476: either you didn't do that, or some library you are using didn't

14:14 python476: right sorry, previously, these expressions weren't in (defn...), and blocking lein check

14:14 justin_smith: OK, that makes more sense

14:14 hiredman: ah

14:14 python476: I thought it was a bad timer variable or something but now I see that was normal behavior for (future...) without (shutdown-agents). right ?

14:14 justin_smith: right

14:15 python476: cool

14:15 hiredman: prn, println, print, etc don't do any synchronization on anything

14:15 python476: I put side effects into my source code. I'm down to php3 level

14:15 hiredman: thanks, I assumed they were, scrambled output is a rare thing to witness :)

14:16 justin_smith: python476: (def outcome (launch-missiles))

14:18 python476: yum

14:23 ha, concurrency is so fun http://stackoverflow.com/questions/5181367/is-defn-thread-safe

14:56 binjured: is there a simple/idiomatic way to chain-filter a collection into different groups? for instance, i have a collection where certain predicates need to come before others and filter out values that would have matched later predicates but belong in the former group, if that makes any sense. it's like sifting, maybe?

15:06 irctc: Can I read in a file using clojurescript?

15:11 dnolen: irctc: ClojureScript has not I/O facilities you have to rely on whatever the JS environment you're targeting provides

15:11 side note there is a #clojurescript specific channel

15:11 s/not/no

15:16 ridcully_: there is noe there ?!

15:20 rhg135: any reason why my `lein repl` would time out on a slow fs if target is on a fast one (it doesn't write elsewhere afaik).

15:21 as an aside launching a clojure.main repl with that classpath loads really fast. so I assume lein is loading something.

15:21 ridcully_: network?

15:21 rhg135: yes, sshfs

15:21 target is symlinked to my home dir

15:26 hmm, apparently if I require seesaw.cor., a dep, java segfaults

15:29 python476: wasn't there a lein plugin to avoid clojure bootstrapping time ?

15:30 rhg135: no, but there is LEIN_FAST_TRAMPOLINE

15:30 python476: I don't wanna be a circus employee

15:31 justin_smith: python476: you can not use lein, then you'll notice that most of that "clojure bootstrapping time" was actually lein startup

15:31 ridcully_: python476: are you anti circi?

15:32 rhg135: and ragequit life when trying to gater dependencies by hand

15:32 python476: ridcully_: I'm somehow noobish on clojure (especially the ecosystem)

15:33 justin_smith: that's also possible indeed, let's go standalone

15:33 rhg135: hey, trampoline repl starts. justin_smith, I'm fairly certain the splash is a lie

15:33 justin_smith: python476: there's a middle ground, where you let lein calculate deps once, then you reuse those deps without running the whole lein thing again

15:33 rhg135: nrepl timesout normally

15:34 justin_smith: python476: that is what that FAST_TRAMPOLINE option mentioned above does

15:34 rhg135: mhm

15:34 justin_smith: ~faster

15:34 clojurebot: faster is https://github.com/technomancy/leiningen/wiki/Faster

15:34 justin_smith: see above for elaborate documentation of these issues ^

15:35 rhg135: idk why it's not the default

15:35 python476: justin_smith: thanks, also, any reference doc about clojure dev without lein (should I dig clojure's website ?)

15:35 justin_smith: rhg135: there's subtle issues, for example I've seen "lein trampoline repl" eat stack traces that are shown with "lein repl" on startup

15:35 rhg135: if you do want to excise lein for production, you'd make a uberjar

15:36 justin_smith: python476: "java -jar clojure.jar" will give you a repl, "rlwrap java -jar clojure.jar" gives you a nicer repl

15:36 clojure.jar can be found via maven, or the clojure.org site

15:37 python476: justin_smith: this part I knew, I meant running namespaced -main(s), tests

15:37 (sorry, I sounded impatient)

15:37 rhg135: or lein trampoline repl lying about nrepl

15:37 python476: I'm actually reusing lein .m2 cache

15:38 justin_smith: python476: java -cp clojure.jar:src clojure.main -m my.ns; java -cp clojure.jar:src:test clojure.main -m my.ns.test

15:38 python476: ha, -m

15:38 of course u_u

15:38 justin_smith: yeah, the output of lein cp can be cached and provided to the -cp arg

15:39 python476: it's indeed a tad more reactive

15:39 * rhg135 coughs; fast trampoline

15:40 python476: I can reuse emacs+make to wrap things up and run with a shortcut

15:40 rhg135: I'll take a loop at that a bit later

15:41 justin_smith: python476: this is really what trampoline with lein does, when you have the LEIN_FAST_TRAMPOLINE env var

15:41 rhg135: ^

15:42 I just set it in my .zshenv

15:43 I can just unset it if I ever need the default

15:43 python476: no value attached to LEIN_FAST_TRAMPOLINE, just its existence is enough ?

15:43 justin_smith: python476: the value doesn't matter, but I think it needs to be non-empty

15:44 python476: LEIN_FAST_TRAMPOLINE='#golang'

15:44 justin_smith: lol

15:44 rhg135: heh, that works

15:46 python476: well, it's not uber faster

15:46 but I've learned a few things

15:46 phorse: is compojure-api meant to be a standalone server sort of deal, or is it typically grafted onto a regular application server?

15:46 python476: gonna replenish electrolytes, my scales are all cracky

15:46 * python476 fabulousssssss~

15:47 rhg135: lein trampoline run -m clojure.main

15:48 justin_smith: python476: trampoline is faster after the second time

15:48 python476: the first time it's still caching

15:48 python476: justin_smith: I'm not that noobish

15:48 justin_smith: phorse: the great thing is it doesn't care

15:48 python476: I did run it a few time, it's a cache thing

15:48 I'll forgive you, here https://pbs.twimg.com/media/CZLC9yPW0AArfnl.png

15:48 justin_smith: it can be standalone (a few different embedded server options), or it can run in a container

15:48 clojurebot: No entiendo

15:49 python476: (Super No entiendo)

15:53 koshmar: is the clojure a good lang for scientific computing - solving PDE in parallel. are numerical libraries mature? if so, what is the best tutorial to start picking numerical oriented clojure? (I have no experience with java or lisp, however I do know haskell if it helps)

15:55 justin_smith: koshmar: core.matrix has a protocol for numeric stuff, with a few implementations you could check out

15:55 koshmar: honestly clojure can be tricky because of auto-boxing issues, but core.matrix can help with that

15:55 *good numeric performance in clojure

15:57 koshmar: what about maturity of core.matrix?

15:58 could I start learn core.matrix skipping clojure tutorials, or at least learning very basik clojure

16:01 rhg135: why is '(try (clojure.core/require (quote nil)) (catch java.lang.Exception t__11836__auto__))' in the init script lein makes??

16:06 justin_smith: koshmar: I think so, seeing as you have haskell experience

16:07 koshmar: some of the exercises on 4clojure.com might help you figure out what's what

16:07 koshmar: core.matrix has been around a while, at the least it's the most mature clojure option for numerics

16:08 the implementations are not all the same - there's tradeoffs for performance vs. safety, but it should be easy enough to swap them out

16:34 algal: Hello, chaps.

16:34 I've got a possibly dumb question.

16:34 If I want to trigger some side-effect only when a swap! succeeds in modifying the value of an atom, what's the recommended way to do that?

16:34 Should I put the side-effecting code inside the update function I am passing to swap? Or should I add a watch to the atom?

16:35 Actually, now that I think on it, a watch would not work, because the parameter for the side-effecting function also depends on the call to swap. Hmm.

16:36 hiredman: swap! always succeeds

16:36 algal: So this suggests I should put the side-effecting fn call inside the update fn which I pass to swap!, but that seems odd, because I think of that function as something that should be pure as the driven snow.

16:36 hiredman: in that swap! retries the function you give it until the compare and swap succeeds

16:36 algal: Right, sorry. I meant that I am passing an update function to swap that sometimes returns a modified value and sometimes returns an unmodified value

16:37 And I only want to call the side-effect when that update function is returning a modified value.

16:43 justin_smith: (let [a @v b (swap! v f)] (if (= a b) ... ...)) ?

16:43 python476: is 6 seconds normal for LEIN_FAST_TRAMPOLINE ?

16:43 justin_smith: python476: what task

16:44 python476: lein run, still that same small clj script

16:44 justin_smith: repl booting to user? way too long, repl booting to your ns? depends on what your deps are

16:44 lein run, depends what you code is doing of course

16:44 python476: a tiny 10 iteration loop + prn

16:45 and no, i'm not running on a 386 :)

16:45 justin_smith: yeah, 6 seconds is way too long there

16:45 python476: how are you running it?

16:45 python476: sad trampoline

16:45 justin_smith: "lein trampoline run" ?

16:45 python476: ha ffsssss

16:45 justin_smith: ?

16:46 python476: down to 1s

16:46 I'm facepalming hard

16:46 justin_smith: oh did you forget the part where you actually trampoline?

16:46 python476: I thought the env var was enough for lein to trigger the rest

16:46 I hope you appreciate fixing noobs typing before they understand things

16:47 while we're at that, what's your favorite(s) book / tutorial (on any part of clojure)

16:47 justin_smith: clojure applied is great

16:48 python476: real problems no 'yet another language reference' ?

16:49 justin_smith: it gets a little deeper into how to do clojure right than most books I've seen

16:49 python476: very nice

16:49 25$ e-book

16:50 justin_smith: python476: and while still learning, http://conj.io is a great thing to leave open at all times while developing

16:50 and to skim occasionally so you don't forget the awesome stuff in core

16:51 python476: yeah, even if 'tiny' it's still large in some way

16:52 phorse: I'm trying to use compojure.api.sweet, but none of the symbols defined in that library are being recognized by the compiler. I've got the correct dependency in my project.clj and in my namespace declaration, is there anywhere else I should check?

16:52 algal: justin_smith: So the thing about that idea << (let [a @v b (swap! v f)] (if (= a b) ... ...)) ? >>, is that there could be changes in v in between the binding (a @v) and the binding (b (swap! v f)] (if (= a b) ... ...)) . Right?

16:52 justin_smith: python476: even now I sometimes accidentally re-implement some function from core just because I forget it's there

16:52 algal: yes, this is unavoidable

16:53 perhaps you want a ref

16:53 refs can do coordinated changes, and this sounds like something you would need coordination to be sure of

16:53 algal: But I am not trying to produce coordinate updates. I'm trying to produce a side-effect if there is a certain kind of udpate. I'm only updating the one atom.

16:54 python476: justin_smith: that's how fun clojure is

16:54 algal: hmm..

16:54 justin_smith: algal: but you need coordination in order to know whether your swap! actually changed the object or not

16:55 algal: Well, the update function which I pass to the swap knows if it changes its arguments, so it knows. So that was why I was wondering about sticking the side-effecting call in there. But that seemed odd..

16:55 justin_smith: algal: (dosync (let [a @v b (alter v f)] (= a b))

16:56 that actually allows you to know if the altering function changed the value

16:56 there's no equivalent with an atom (or at least nothing simple)

17:03 amalloy: watchers?

17:04 aztak: g'd evening all.

17:04 amalloy: seems like exactly what algal wants, not refs

17:04 justin_smith: amalloy: oh, yeah, I guess a watcher could do that, since it gets the before and after

17:04 amalloy: you can also do it by hand on an atom, by changing what the atom stores: instead of just storing the current value, you can make it store both the previous and current value in a tuple

17:05 that means you have to change all readers and writers, but it can be done without the coordination of a ref

17:05 justin_smith: amalloy: "I hate the other people who use this value anyway"

17:05 aztak: anyone "going to" clojure-remote next week?

17:05 justin_smith: oh, right

17:05 amalloy: (honestly you can do a surprising amount with atoms if you make them into tuples)

17:06 justin_smith: simplifying update logic, at the cost of an extra lookup with every usage

17:06 (every non-update usage)

17:07 algal: amalloy: ah, interesting.

17:08 amalloy: but if your goal is to just sometimes do a side effect based on what happened in the swap, that's exactly the case watchers were designed for

17:10 algal: amalloy: So I need the parameters I pass to my side-effecting function to be different for different calls to swap! So that makes it harder to use a watcher.

17:10 justin_smith: algal: why would that matter?

17:10 algal: But I guess I can (again) pass more information into the atom, like a tuple, just to expose that extra piece of info to the watcher.

17:10 sdegutis: justin_smith: What's your favorite Clojure HTTP library?

17:10 justin_smith: algal: the extra parameters change how the side effect should happen?

17:11 phorse: When I use (dir compojure.api.sweet) I get a list of 18 functions. When I check the api docs for compojure.api.sweet, they list 21 functions with only some overlap between the two. Is the documentation out of date?

17:11 justin_smith: sdegutis: I kind of hate all of them right now sorry, I'll let you know if I start liking one

17:11 algal: yes. But the extra parameters are not strictly needed to compute the change in the atom's state.

17:11 sdegutis: :D

17:11 justin_smith: Any reason?

17:12 justin_smith: sdegutis: my app needs to suck up the internet and the internet is terrible

17:13 sdegutis: :D

17:13 I just need to interface with MailChimp so I'm gonna stick with clj-http.

17:17 amalloy: justin_smith: re the internet being terrible: today at lunch my company had joel spolsky come give us a talk entitled "how to have nice things" (in contrast to the usual "this is why we can't have nice things")

17:17 justin_smith: amalloy: interesting

17:18 I've learned that scraping data for urls and trying to check those urls en mass can lead to lots of stupid stuff (who would have guessed, right?)

17:19 amalloy: no kidding. even if they are all valid urls to sites with actual data

17:19 why do you want to slurp up the whole web, again?

17:19 justin_smith: amalloy: we do social analytics, our client wants to know what's happening regarding a certain topic, finding and following rss and blogs from social media is part of this

17:20 eg. figuring out the hot content, and part of that is figuring out two people were talkign about the same content even if via two different clickbait sources...

17:21 amalloy: and then some guys' gonna be lick "this is my rss feed" and it's actually like an xml bomb or something

17:22 amalloy: yep

17:22 lockdown: amalloy: material things?

17:22 you guys are not giving in to slack? ;)

17:23 justin_smith: ~slack

17:23 amalloy: the talk was about why creating sustainable internet communities is hard, and what kind of stuff you should expect to have to do if you want to try it

17:23 clojurebot: It's greek to me.

17:23 amalloy: i think slack is great. it's a way to trick people without neckbeards into using an irc-like

17:24 aztak: This is good: https://drive.google.com/file/d/0B8ZX1RoWHuiJSnZHZFJqOERqaDg/view

17:26 rhg135: I didn't know I had a neckbeard

17:27 aztak: where's the largest Clojure community then, on IRC or on Slack? (They are obviously not exclusive)

17:28 rhg135: I've never been on slack, but it seems to be quite active

17:29 justin_smith: aztak: 4859 signed into clj slack, usually about 800 here

17:29 aztak: justin_smith: so metrics says "Slack" then? :)

17:29 too bad, I've just learnt so configure ERC in Emacs :(

17:30 justin_smith: also too bad because I don't trust slack, and prefer irc

17:30 lockdown: justin_smith: of those 4859 normally less than 500 are online

17:31 * rhg135 mumbles something about 'slack' and 'evil'

17:31 lockdown: so this channel is bigger!

17:31 justin_smith: lockdown: oh, where's that number?

17:31 rhg135: and 'hipsters'

17:31 aztak: hehe

17:32 lockdown: justin_smith: click in the number

17:32 slack is so laggy, don't know if it is because I use firefox instead of chrome

17:32 rhg135: probably

17:33 Bronsa: can we just stop talking about slack? :)

17:33 rhg135: it's horribad on some js

17:34 lockdown: Bronsa: be we feel slighted

17:34 :P

17:35 aztak: either way - it's great that there is a big and diverse Clojure community.

17:35 For neckbeards *and* for hipsters!

17:35 :)

17:36 rhg135: yay neckbeards :)

17:36 s/neckbeards/clojure/

17:37 lockdown: when you do in-ns in a repl to switch to an existing ns, the ns macro of that ns is not parsed right? you have to use ns functions in the repl to replicate the ns macro?

17:37 justin_smith: so yeah, at any given time there are more users here

17:37 rhg135: nope, the repl just switches to it

17:37 doesn't even have to exist

17:37 justin_smith: lockdown: the ns macro is a wrapper for in-ns

17:38 lockdown: you probably want to make sure you have required your ns before doing the in-ns

17:38 or use ns, yes

17:38 amalloy: (ns foo) is no better than (in-ns 'foo)

17:38 justin_smith: lockdown: also, solution to a common problem (clojure.core/refer-clojure)

17:39 saves you from the situation of having switched to an empty ns that doesn't even have access to clojure.core

17:39 rhg135: I just stay in user and alias it

17:39 lockdown: ok thanks

17:39 rhg135: keeps dev utils handy that way

17:40 lockdown: yeah, looks staying in user and using require seems the way to go

17:41 so if you require a ns from user, all the ns macro of the namespace is loaded?

17:41 rhg135: I wish CIDER had a better way to do that than typing it manually in the repl

17:41 yes

17:41 lockdown: and attached to the repl?

17:41 ok

17:42 justin_smith: rhg135: doesn't cider have a "load this file" keystroke?

17:42 rhg135: I may as well use inf-clj if not for the debugger

17:43 amalloy: rhg135: of doing what?

17:43 rhg135: yeah, justin_smith, I meant to send '(alias <something> <ns name>)

17:43 justin_smith: ahh

17:43 lockdown: justin_smith: yeah, I hit that problem already (the refer-clojure) ;), the repl only loads clojure.core for user

17:44 rhg135: when the ns name is 50 chars long it gets tedious

17:44 amalloy: rhg135: i don't understand what tedious task you're doing that you can't fix with ten seconds of elisp

17:44 or by using require :as instead of require + alias

17:44 lockdown: justin_smith: makes sense since user is only for trying things out

17:45 amalloy: ,(macroexpand-1 '(ns foo))

17:45 rhg135: I'm new to emacs though, amalloy, and elisp is greek to me

17:45 clojurebot: (do (clojure.core/in-ns (quote foo)) (clojure.core/with-loading-context (clojure.core/refer (quote clojure.core))) (if (.equals (quote foo) (quote clojure.core)) nil (do (clojure.core/dosync (clojure.core/commute (clojure.core/deref (var clojure.core/*loaded-libs*)) clojure.core/conj (quote foo))) nil)))

17:45 amalloy: it's nothing to do with the user ns

17:45 (ns) expands to code that calls (refer-clojure)

17:45 lockdown: ~emacs

17:45 clojurebot: emacs is an out-moded belief system

17:45 lockdown: ~cursive

17:45 clojurebot: cursive is that thing what colin wrote

17:46 justin_smith: ~ed

17:46 clojurebot: ed is the standard editor!

17:46 rhg135: when cursive doesn't require X call me

17:46 lockdown: amalloy: yeah, ns does the refer-clojure implicitly

17:46 justin_smith: rhg135: it'll run without X on osx or windows no problem :P

17:47 rhg135: a real masochist uses a steady hand and a needle, justin_smith

17:47 not ed ;)

17:48 justin_smith: true heh

17:48 lockdown: ~vim

17:48 clojurebot: Gesundheit!

17:48 lockdown: ~atom

17:48 clojurebot: I don't understand.

17:48 rhg135: ~editor

17:48 clojurebot: Huh?

17:48 tolstoy: Ugh. Having the worst lock with eastwood.

17:49 amalloy: i just realized: do they have something like clojurebot in the slack channel?

17:49 lockdown: tolstoy: clint is a tough guy

17:49 justin_smith: amalloy: yup

17:49 and on slack you don't even need one liners

17:49 tolstoy: lein eastwood: Caused by: java.lang.ClassNotFoundException: leiningen.core.project$reduce_dep_step

17:49 amalloy: requiring one-liners is a feature, to stop people pasting giant essays

17:49 justin_smith: tolstoy: oh man, clearly reduce-dubstep was a terrible idea

17:50 * justin_smith flees.

17:50 lockdown: amalloy: yeah, you normally see walls of code there

17:50 rhg135: I have a char limit on mine

17:51 and if you trip the alarm you get kicked/banned

17:51 tolstoy: justin_smith: Yeah. What's even calling it? Oy. ;)

17:55 Eastwood is broken using Lein 2.6.0? Oy. I don't even care anymore. If my code doesn't bomb, it's perfect!

17:55 rhg135: 2.6.0 is out??

17:56 tolstoy: Yep.

17:57 https://groups.google.com/forum/#!topic/clojure/XlROLH76yNg

17:57 justin_smith: tolstoy: "lein upgrade 2.5.3" is also an option

17:57 2.6.0 also broke lein-ring

17:57 tolstoy: Or downgrade?

17:58 Yeah, but I was having issues with eastwood anyway (a protocol with two many methods?). And there are 62 issues. I'll come back next year.

17:58 justin_smith: tolstoy: the command is "upgrade", ¯\_(ツ)_/¯.

17:59 tolstoy: Even when the announcement says, "As usual, for those who manually installed, `lein upgrade` will pull in

17:59 the latest. `lein downgrade 2.5.3` will back it down to the previous

17:59 version if you run into any issues."

17:59 justin_smith: oh, well why remember two commands when one command works

17:59 sdegutis: Hi.

18:04 tolstoy: Indeed!

18:06 Somelauw: I'm a bit of a beginner. When using Emacs, I get the following warnings on start-up https://pastee.org/xn98p telling me nREPL is outdated. How do I get this up to date?

18:06 justin_smith: Somelauw: https://github.com/clojure-emacs/cider-nrepl

18:07 that has comprehensive instructions for making sure you have the right version

18:07 lockdown: Somelauw: make sure cider and nrepl-cider versions are in sync

18:08 Somelauw: also, use the latest version of leiningen, which pulls nrepl 0.2.12

18:08 so cider doesn't complain

18:08 justin_smith: lockdown: as a plugin, cider overrides nrepl version anyway

18:09 Somelauw: so might just updating lein be enough?

18:09 justin_smith: that won't fix your cider-nrepl version, no

18:09 rhg135: can someone explain the advantage of nrepl middleware over just sending code to eval?

18:09 lockdown: justin_smith: yeah, that's another way to do it

18:09 Somelauw: rhg135: probably autocompletion

18:10 rhg135: you can def. autocomplete without it.

18:10 lockdown: Somelauw: if you installed cider from melpa you also need nrepl-repl master branch

18:10 rhg135: afaik, neither cursive nor fireplace need middleware

18:10 justin_smith: rhg135: how would you get the auto-complete results without nrepl?

18:11 lockdown: errr nrepl-cider I mean

18:11 justin_smith: the idea is to get the data from clojure itself, and nrepl lets you separate that request from the data going to your repl window

18:11 rhg135: I don't mean no nrepl, although you can, I mean without custom middleware

18:11 justin_smith: OK

18:13 Somelauw: Instead of hard-coding the version number as "0.10.2" would it be wise to use something like :latest?

18:14 justin_smith: Somelauw: then it will break when it's newer than your cider version

18:14 (or might)

18:14 rhg135: justin_smith: https://github.com/clojure-emacs/inf-clojure/blob/master/inf-clojure.el#L634

18:14 justin_smith: better to leave it explicit so you can upgrade the two halves together

18:15 rhg135: yeah, I had misunderstood what you were saying, I just meant nrepl was useful for sending completions to elisp while having a separate repl not full of those things

18:15 rhg135: ah, indeed.

18:16 maybe the tools.nrepl readme would help

18:17 Somelauw: My cider version is even 0.11.0-snapshot

18:18 seangrove: Hey all, what's the clojure equivalent of `jse = (JavascriptExecutor)wd;` ?

18:18 Not sure about the (...) casting part

18:19 rhg135: the only thing I can think of is bandwith

18:19 justin_smith: seangrove: since our bindings are not typed, we don't need casts

18:20 seangrove: justin_smith: That's what I thought, but this object is missing a method, thought that might be related

18:20 Probably just an outdated dep though - thanks

18:20 justin_smith: seangrove: how would telling the compilar "treat x as a y" make a method show up on x?

18:21 amalloy: justin_smith: well, that *is* a thing you sometimes need to do, and there is a way to do it

18:21 justin_smith: amalloy: oh?

18:21 amalloy: the usual place this comes up is when trying to submit a function to an executorservice

18:21 which is overloaded to take either a Callable or a Runnable, and functions implement both

18:21 justin_smith: ahh, and you would handle that with a hint, right?

18:21 amalloy: right

18:23 rhg135: what is clojure.core/cast for then

18:23 justin_smith: rhg135: read the doc

18:23 it's a silly function

18:23 ,(doc clojure.core/cast)

18:23 clojurebot: "([c x]); Throws a ClassCastException if x is not a c, else returns x."

18:24 justin_smith: rhg135: I mean maybe that's what you want, but most times when people ask how to cast something in clojure that is not the functionality they are asking for

18:26 rhg135: so, it's more of a specialized assertion (not actually an assertion)

18:27 basically says x is a c or die

18:27 justin_smith: right

18:28 rhg135: cool, that's good for defensive code

18:32 justin_smith: yeah, an assertion would throw an error (no way to stop things, app dies now), but it throws an exception (something might be catching class casts and dealing with them I guess)

18:32 lockdown: Somelauw: then you need 0.11.0-snapshot for nrepl-cider

18:32 Somelauw: lockdown: I put a new version of cider-nrepl in profiles.clj. Now it complains that my refactor-nrepl is still out of date.

18:33 amalloy: justin_smith: assertions are perfectly catchable too, if you want

18:33 just catch AssertionError

18:33 it's just...a pretty bad idea

18:33 rhg135: I just throw WorldIsDoomedBecauseValueIsNotRightError

18:33 Somelauw: lockdown: https://pastee.org/bgsy2

18:33 justin_smith: fair enough, but error family vs. exception family carry different implications

18:34 rhg135: then I watch it all burn to the ground, metaphorically of course

18:35 amalloy: i think if you catch Error you deserve to have it non-metaphorical

18:35 lockdown: Somelauw: I haven't use refactor-nrepl but looks like you have sync isssue again, between refactor-nrepl and clj-refactor

18:36 rhg135: it doesn't even subclass Error, it's Throwable

18:37 Somelauw: I not sure if I need refactorings, but autocomplete doesn't work either or not as I expect (which is just pressing tab)

18:37 lockdown: Somelauw: if you are just learning can you do without the refactor package?

18:37 remove it so you don't get the warning

18:38 rhg135: but for real, code with catch Throwable is terrifying

18:38 Somelauw: I can ignore the warning. My priority is figuring out how autocompletion works.

18:38 lockdown: Somelauw: did you read the auto-completion docs for cider?

18:39 justin_smith: rhg135: the classy thing would be (throw (Throwable. "Updog"))

18:41 lockdown: clojure doesn't need autocomplete, you should keep your modules and in your head ;P

18:41 rhg135: justin_smith: hopefully that's not from your code base

18:41 justin_smith: rhg135: heh, I just made it up

18:41 rhg135: good, good

18:42 Somelauw: a bit hacky, but I manually ran company-mode, and it worked after the second launch

18:42 lockdown: err your modules small I mean

18:42 justin_smith: lockdown: auto-complete can save you manually typing (dir some-stupid-ns) or going and opening the source file

18:43 rhg135: ,(doc dir)

18:43 clojurebot: "([nsname]); Prints a sorted directory of public vars in a namespace"

18:43 rhg135: I didn't know that one

18:44 justin_smith: dir+doc+apropos are a nice combo

18:45 ,(apropos #"^ns")

18:45 clojurebot: (clojure.core/ns clojure.core/ns-aliases clojure.core/ns-imports clojure.core/ns-interns clojure.core/ns-map ...)

18:45 Somelauw: the docs say (global-set-key (kbd "TAB") #'company-indent-or-complete-common), but I think I would only want this in clojure-mode or something, so I can bind tab differently in other filetypes.

18:47 amalloy: Somelauw: you can "globally" add it to the keymap for a particular mode. or you can, in the hook for a particular mode, use local-set-key instead

18:48 see https://github.com/amalloy/dotfiles/blob/master/.emacs.d/init.el#L40-L55 for an example of the latter

18:50 (define-key slime-repl-mode-map (kbd "<C-return>") nil) ;; is an example of the former

18:50 justin_smith: haha, amalloy's a slimer

18:50 amalloy: i unbound C-RET for some reason or other

18:50 justin_smith: which is a term I just made up for people who still use slime, I hope it sticks

18:51 amalloy: never upgrade. never surrender

18:51 * lockdown steals the default-frame-alist from amalloy

18:52 Somelauw: amalloy: thanks

18:52 lockdown: justin_smith: sometimes I think we just obsess to much with tooling

18:53 justin_smith: lockdown: it's an evolutionary thing, our ancestors who did not obsess about tooling never compiled and shipped

18:54 amalloy: that's what a public dotfiles repo is for. although i'm surprised my default-frame-alist is the thing you'd want to steal

18:54 like pls, i wish more people would steal my rebinding of C-x C-c

18:54 lockdown: justin_smith: I bet amalloy would be just as productive with slime as with cider

18:55 amalloy: was using spectacle (an osx window resize thing) for setting the size of emacs

18:55 amalloy: do you code on a laptop? 42 seems low

18:55 justin_smith: lockdown: I was making a bad evo-psych joke

18:56 amalloy: i have vision problems

18:56 so the font size is jacked way up, and the resolution way down

18:56 lockdown: justin_smith: oh ;)

18:56 amalloy: i'm going to an Evo Psych concert this weekend

18:56 lockdown: amalloy: I see

18:57 justin_smith: lockdown: I gave up on cider myself, and just use clojure in a repl, sometimes lein repl and sometimes a jar launched with java

18:57 * lockdown googles evo psych

18:57 amalloy: you and hiredman should start a club

18:57 justin_smith: so beleive me I have plenty of skepticism about tooling

18:57 hiredman: hmmm?

18:57 justin_smith: amalloy: I totally would but he has had me on ignore for years

18:58 amalloy: people who advocate use of clojure from a repl rather than editor integration

18:58 lockdown: justin_smith: yeah, if the buil-in repl had readline support I wouldn't even use lein sometimes

18:58 amalloy: lockdown: rlwrap

18:59 justin_smith: ~rlwrap

18:59 clojurebot: excusez-moi

18:59 justin_smith: ~rlwrap is good enough sometimes.

18:59 clojurebot: Ok.

18:59 lockdown: interesting

19:00 * lockdown tries rlwrap

19:00 justin_smith: rlwrap is great for making any unixy thing that expects lines of text more usable

19:00 rlwrap ed is like 1% of the way to being vim

19:01 lockdown: heh

19:02 justin_smith: inf-clojure hits a sweet spot I guess

19:03 justin_smith: I might try it one of these days

19:12 arrdem: I should get a CIDER tatoo

19:12 justin_smith: arrdem: tattoo upgrades suck, wait until it goes stable

19:14 arrdem: nah man -SNAPSHOT for lyfe

19:14 what's the point of living if you aren't on the bleeding edge

19:15 amalloy: haha, i was jsut playing around with gist.el, and M-x gist-list breaks because i apparently have too many gists

19:15 if: Variable binding depth exceeds max-specpdl-size

19:16 arrdem: hah

19:19 amalloy: i tried tracking it down, but the implementation is apparently a maze of generic functions or something and i'm no good at elisp

19:21 justin_smith: and elisp is no good at generic functions

19:21 so there we go

19:27 tolstoy: If a component only appears once in a system map, is there some reason Component would call start twice?

19:28 justin_smith: tolstoy: if you had your system in an atom and used swap! to start it and the calls overlapped

19:29 tolstoy: No, not doing that. Very weird. Starts two instances.

19:30 justin_smith: tolstoy: I don't see how it would do that

19:32 tolstoy: Weird. The component recvs messages on a topic, and, sure enough, it's doing it twice. So it's not a spurious log thing.

19:32 justin_smith: tolstoy: what if your whole system got started up twice?

19:33 tolstoy: Why wouldn't the other recv comps duplicate? Hm.

19:33 Heh. Just checked to see if I didn't name two records the same thing.... nope.

19:34 justin_smith: what about copy/paste error giving two names to instances of the same record?

19:34 Somelauw: i got emacs to freeze

19:35 tolstoy: That's what I just checked for. If so, can't find it.

19:35 justin_smith: there's a few ways to do that, a bunch of them involve very long lines

19:35 tolstoy: lein clean, etc.

19:40 justin_smith: tolstoy: can you share a paste of the system map?

19:40 or, rather the system/using call etc.

19:41 tolstoy: https://gist.github.com/zentrope/72820037e77062607f44

19:45 justin_smith: I'm more familiar with system/using rather than inline component/using calls, but if component/using works like I expect that looks fine

19:46 tolstoy: Seems to have worked in lots of place.

19:47 justin_smith: tolstoy: what about writing your component such that starting the same one twice won't do anything? you could put a key in the system map that marks whether it's started

19:47 tolstoy: I'll give that a shot. I've just removed a bunch of deps to see if somehow that affects it, but, no....

19:47 justin_smith: (start [component] (if (:this-started component) component (do .... (assoc component :this-started))))

19:48 something like that

19:49 next step if that doesn't help is a delay or promise outside start that ensures the component is a singleton I guess

19:49 tolstoy: Yeah. I wonder _why_ the problem is there. I guess I'll have to try to repro with a minimum case, if I'm up for some madness.

19:49 justin_smith: maybe even throw an exception if starting after already started, and then see from the stack trace who is fucking up

19:50 (def started (promise)) (start [component] (assert (not (realized? started))) ... (deliver started true) (assoc component ...)))

19:51 tolstoy: Interesting. Setting a :starting? prop, it actually gets set twice.

19:59 Heh. Renamed the file "foo.clj": solved.

19:59 justin_smith: wat

20:00 Somelauw: I'm getting nuts if some "Unmatched bracket or quote" error

20:01 tolstoy: Slowly renaming things back to see what's what.

20:02 Somelauw: found it, I had an unmatched ] instead

20:03 tolstoy: Interesting. If my component is in health.clj, or the ns ends with .health (my-app.component.health) I see the prob.

20:03 justin_smith: Somelauw: many editors have tools that make this much easier to find and fix

20:04 tolstoy: that's weird and bad

20:04 tolstoy: Yep.

20:04 justin_smith: something clashing on the classpath?

20:05 tolstoy: I don't see how. Moving the health.clj file to another part of the tree.

20:06 Somelauw: justin_smith: I was told emacs is the most potent editor for clojure. I do have rainbow-coloring and such. I was looking for a round bracket and all my round brackets matched, it was a square bracket missing.

20:06 Sorry for using bracket and parenthesis interchangeably.

20:08 justin_smith: Somelauw: if you use highlight parens your mismatching parens would be a distracting / obvious color. Even with rainbow parens they should have been.

20:09 delimiters, I like the word delimiters (which I forgot to use just now)

20:11 tolstoy: justin_smith: Okay, we can restore our faith. It's because I inadvertantly had two loggers (myapp.component and myapp.component.health) defined in logback.

20:11 justin_smith: hahaha

20:11 so it was only starting once, but logging too much

20:11 tolstoy: justin_smith: Given that, it "seemed" as if I was processing dual copies of the message.

20:11 Right.

20:11 justin_smith: (dec loggers)

20:11 tolstoy: That's why the :started? scheme didn't work.

20:12 Somelauw: Ok, red isn't yet distracting for me

20:12 justin_smith: Somelauw: yeah, maybe you can change the color

20:12 maybe set a fast blink on the face :P

20:40 Somelauw: emacs + cider freeze yet again :-(

20:41 justin_smith: Somelauw: what makes it happen?

20:42 Somelauw: justin_smith: I'm not sure. I think "Mark set" is the last thing I read in the minibuffer.

20:42 justin_smith: Somelauw: what happens if you hit Control-g a bunch of times?

20:43 (while it's locked that is)

20:43 Somelauw: I've already killed it. I'll try next time.

20:44 justin_smith: Somelauw: anyway, in the future you could try turning on debug-on-error and then using Control-g when it locks up and the debugger should give an idea of what emacs was trying to do, and at least the cider folks could do something with that info maybe

20:53 scottj: justin_smith: Somelauw: I think you want M-x toggle-debug-on-quit (not error) for C-g to bring up debugger.

20:55 justin_smith: scottj: I assumed that after the quit an error would be exposed

20:55 scottj: but yes, that is more direct I guess

20:56 scottj: I find debug-on-quit annoying because I often quit from things...

Logging service provided by n01se.net