#clojure log - Apr 21 2014

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

0:02 ddellacosta: yedi: how are you deploying the uberjar?

0:02 yedi: i'm just using lein uberjar and then copying the uberjar from my local machine to the remote server

0:03 ddellacosta: yedi: seems like you'd need to compile the cljs and include it in the uberjar beforehand, no? Actually not sure how else you'd do it

0:05 owl-v-: (or) is nil, and (and) is true???

0:05 lazybot: owl-v-: Yes, 100% for sure.

0:06 ddellacosta: owl-v-: makes sense

0:06 ,(or nil nil)

0:06 clojurebot: nil

0:06 dbasch: yedi: I have two profiles, dev and prod

0:06 ddellacosta: ,(and nil nil)

0:06 clojurebot: nil

0:07 ddellacosta: whoops

0:07 ...would have expected that to be true.

0:07 dbasch: yedi: before I build the uberjar, I do lein cljsbuild once prod

0:10 amalloy: ddellacosta: why would (and nil nil) be true?

0:10 ddellacosta: amalloy: you're right, I realized my mistake just this moment. :-(

0:10 amalloy: &('#and nil nil) ;; bestest parlor trick

0:10 lazybot: java.lang.RuntimeException: No reader function for tag and

0:10 amalloy: &(#'and nil nil)

0:10 lazybot: ⇒ true

0:10 owl-v-: if (nil) is treated as false then (and false false) would be false

0:11 ddellacosta: amalloy: wat

0:11 amalloy: what is going on there?

0:12 amalloy: ddellacosta: macros take two additional implicit arguments, &form and &env. calling through the var gets at the underlying function, and lets you pass those yourself

0:12 &(#'and 1 2 'asdf 'anything)

0:12 lazybot: ⇒ (clojure.core/let [and__3822__auto__ asdf] (if and__3822__auto__ (clojure.core/and anything) and__3822__auto__))

0:13 amalloy: so (#'and 'anything 'whatever) really a silly way of calling (macroexpand '(and))

0:13 TEttinger: heh neat

0:13 ddellacosta: amalloy: huh, thanks for the explanation

0:14 learn something new (about Clojure especially) every day

0:14 owl-v-: ,(#'and true false)

0:14 clojurebot: true

0:14 yedi: dbasch: so just build the prod one right before building the uberjar, and then resume auto building the dev profile while developing?

0:15 TEttinger: ,(#'and nil nil nil nil)

0:15 clojurebot: (clojure.core/let [and__3973__auto__ nil] (if and__3973__auto__ (clojure.core/and nil) and__3973__auto__))

0:15 owl-v-: ,(and true false)

0:15 clojurebot: false

0:15 dbasch: yedi: yes, I have a prod.sh script that does that. It cleans everything and builds the prod profile and then the uberjar

0:15 TEttinger: ,(#'and nil nil nil)

0:15 clojurebot: nil

0:15 TEttinger: waaaaah

0:17 amalloy: TEttinger: because (and x) expands to x

0:17 TEttinger: even with the other implicit args?

0:17 ,(#'and 3 nil nil)

0:17 clojurebot: nil

0:18 rgrinberg: is there a way to play with clojure apps without creating a new project? for example i'd like to try out gorilla repl or incanter

0:18 TEttinger: uhhh you sure about that?

0:18 `szx: $google lein-try

0:18 lazybot: [rkneufeld/lein-try · GitHub] https://github.com/rkneufeld/lein-try

0:18 `szx: ^ rgrinberg

0:19 owl-v-: (#'and nil nil ture)

0:19 (#'and true nil nil)

0:19 rgrinberg: `szx: cool

0:19 owl-v-: ,(#'and nil nil ture)

0:19 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ture in this context, compiling:(NO_SOURCE_PATH:0:0)>

0:19 owl-v-: (#'and nil nil true)

0:19 ,(#'and nil nil true)

0:19 clojurebot: true

0:19 TEttinger: my brain

0:19 owl-v-: ,(#'and true nil nil)

0:19 clojurebot: nil

0:21 owl-v-: ,(and nil nil true)

0:21 clojurebot: nil

0:21 owl-v-: ,(#'and nil nil true)

0:21 clojurebot: true

0:23 amalloy: i think you guys must have missed the lesson here. (#'and x y z) always expands to z, for any x, y, or z

0:23 owl-v-: ,(and 1 2)

0:23 clojurebot: 2

0:23 owl-v-: ,(and 2 1)

0:23 clojurebot: 1

0:24 amalloy: it's not useful in any real program, except that it gives you a better understanding of how macroexpansion works

0:31 jwm: anyone care to help explain the add-watch first example

0:32 how can you pass nil to add-watch for key

0:33 seancorf`: ,(doc add-watch)

0:33 clojurebot: "([reference key fn]); Adds a watch function to an agent/atom/var/ref reference. The watch fn must be a fn of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference's state might have been changed, any registered watches will have their functions called. The watch fn will be called synchronously, on the agent's thread if an agent, before any pending sends if agent or re...

0:33 seancorf`: hmm, cut off

0:34 jwm: yeah I understand add-watch

0:35 http://clojuredocs.org/clojure_core/clojure.core/add-watch

0:35 I just needed help understanding the first example

0:35 how does it get away with using nil in the form

0:36 seancorf`: nil is just a key

0:36 as long as the keys of various watchers are all unique, it doesn't matter what their values actually are

0:36 per the docs, Keys... are otherwise considered opaque by the watch mechanism.

0:37 jwm: so its just a placeholder in an example

0:37 seancorf`: Well, it's the key for that watcher

0:37 you could remove it using nil as the key

0:37 jwm: yeah

0:38 kind of a weird example

0:38 wouldn't you want to pass the key into watch-agent

0:38 seancorf`: if you only want to add one watcher (via this function), it doesn't matter what the key is

0:39 the key could be 0, or :foo, or ""

0:39 or nil

0:40 jwm: how about the partial, I assumed partial took the arguments after the call

0:41 owl-v-: how do i express imaginary number???

0:41 lazybot: owl-v-: Oh, absolutely.

0:41 seancorf`: right... so watch-fn takes five args, and the partial supplies the context

0:41 owl-v-: ,(Math/sqrt 2)

0:41 clojurebot: 1.4142135623730951

0:41 owl-v-: ,(Math/sqrt -4)

0:42 clojurebot: NaN

0:42 seancorf`: and add-watch expects a function of four args - which is what is left

0:42 owl-v-: ,(Math/sqrt -1)

0:42 clojurebot: NaN

0:42 seancorf`: owl-v-: you'll need a library that handles complex numbers

0:47 jwm: does that clarify?

0:47 jwm: I'm still kind of at a loss

0:47 not sure why

0:48 what does context mean in this regard

0:48 not sure why this is so hard for me to understand I already have smtp, mongodb, http, uberjar, nrepl + lighttable going

0:48 hehe

0:48 I just let myself get stuck and it gets irritating :)

0:48 seancorf`: Could be a label to display

0:49 It could be a snapshot of state from wherever the watcher was added

0:49 jwm: ok so context just gets passed to the anonymous function

0:49 but where do the rest of the arguments get passed in from

0:50 seancorf`: add-watch takes a function of four args, (partial watch-fn context) is a function of four args

0:50 so when the item changes, the system calls the function (with four args)

0:57 jwm: you know where I went wrong

0:57 I didn't think in my head that add-watch was calling the function with the rest of the arguments

0:57 I'm a dildo

0:58 heh

0:58 the nil thing also through me off

0:58 that should be changed to some random key like :example :)

0:58 threw*

0:59 seancorf`: :context-watcher would probably be a better key for that example

0:59 jwm: yeah

0:59 the nil made me think somehow partial worked backwards also lol

0:59 I overthought it

1:02 I probably wont be using agents

1:02 they seem to fail in my environment

1:03 seancorf`: oh?

1:03 jwm: one last question any good tools to stop memory creeping

1:04 I'm running my code as an uberjar and it started at 96mb

1:04 no addition of data and its at 350 now

1:04 I plan to add a lot of introspection later down the road but I have a stupid deadline by tuesday

1:04 seancorf`: Have you used JVM-based languages before?

1:05 jwm: no, just in administration

1:05 I put off for two decades now because the jvm used so much memory :)

1:06 but now that we have gigs upon gigs..

1:06 seancorf`: The JVM starts with a minimum heap size and allocates more memory as it needs it up until the max heap size you specify

1:06 jwm: I've got a crapload of dependencies though so I imagine that isnt much memory at this point in time

1:06 seancorf`: A lot of people who've never used the JVM find the memory use surprising

1:07 We run servers with heap size set to 8GB :)

1:07 jwm: hehe

1:07 gone 64bit?

1:07 seancorf`: I usually run local JVM processes on my laptop with 1GB heap

1:07 jwm: I am running this code 64bit

1:07 seancorf`: heh, haven't had a 32bit system for years

1:08 jwm: I'm actually transitioning over from nodejs

1:08 getting off the imperative bandwagon since I am trying to get into more r&d type stuff

1:09 seancorf`: I've been using JVM-based systems for 17 years now

1:09 jwm: that is cool

1:10 I was an asm coder and then went to javascript lol

1:10 figured if I was going to use a vm might as well use a really good one :)

1:11 TEttinger: LLVM?

1:11 seancorf`: The JVM is certainly battle-tested

1:11 jwm: I did not get comfortable with llvm yet

1:11 but its sick how embeddable it is

1:11 TEttinger: I'll give Julia a shot

1:13 jwm: how's openjdk doing

1:13 I haven't tried running clojure on it yet

1:14 seancorf`: Clojure and its contrib libraries are all tested against OpenJDK

1:14 for example http://build.clojure.org/job/clojure-test-matrix/

1:15 and you can see how contrib libraries are tested against both multiple JVMs and multiple Clojure versions http://build.clojure.org/job/java.jdbc-test-matrix/

1:16 jwm: http://openjdk.java.net/projects/jdk8/

1:16 yeah, tested against 1.6 on that page

1:16 your page rather

1:18 seancorf`: I'm running Java 8 locally for all my testing now... and we're on Java 7 in production right now... We've tended to go to production with RCs of Clojure for a while as well... We first went to production with Clojure 1.3 alpha 7 or alpha 8

1:19 jwm: I must be a bad guy then I run everything at one level shy of beta

1:19 hehe

1:20 seancorf`: we test locally against master so we're always ready for the alphas and betas as they appear

1:20 jwm: I work for a cable company though so it's not exactly life threatening stuff

1:25 I really like lighttable

1:26 I've used emacs/slime/etc in the past but lighttable is really nice so far

1:27 seancorf`: I used Emacs for Clojure for about two years, before switching to LightTable when 0.6.0 came out

1:29 jwm: cool, do you try to stay up to date with git?

1:29 I tried updating once a couple weeks ago but it didn't want to start after that hehe

1:29 I've got my css to do transparency and a nice image bg

1:29 and font shadows

1:30 seancorf`: With LT you mean? No, I just use the official releases since I used it for all my work and need it to behave...

1:31 jwm: I finally got my project to a point I can just run the nrepl separate and jar it off and put it on the server.. it seems to run faster now

1:33 yedi: (inc dbasch)

1:33 lazybot: ⇒ 2

1:34 seancorf`: We tend to run an nREPL server inside our processes now, so we can connect into processes from LightTable and run diagnostics... or even update the code while it's running.

1:36 jwm: yep!

1:36 that is exactly what I wanted

1:37 really exciting

1:45 clojure.data/diff is nice

1:46 Frozenlo`: seancorf`: While the cljs/LT is pretty sweet, I stil feel more confortable in emacs.

1:47 But boy do I miss the magic connection between LT and the browser

1:47 Doing the same thing in Emacs is such a pain...

1:48 seancorf`: Frozenlo`: that pain is why I'll deal with LT and its quirks :)

1:48 jwm: yeah that is what I like the most out of LT.. it's kind of like sublime

1:48 it reads your mind on how you want to do things

1:49 I got clojurescript going in lt and the frontend to this project

1:49 next thing I want to try is nrepl from browser and nrepl from lighttable at the same time if possible hehe

1:55 seancorf`: LT can certainly connect into both client and server and eval code live into both. We do that.

1:57 jwm: yeah, I already have both repls going at once. I mean have something outside of lt running in browser

1:57 so when I am on the go I can just login and change some code from the web

1:58 Frozenlock: Is there a function to make a range that 'sometimes' skip a number? Like `(from 0 to 500 in 400 steps)'

1:58 --> with only int

1:58 jwm: I know they already have browser based repls I just would like both options. I had to load up the nrepl lt middleware so I would need two separate repl sessions if possible

2:00 seancorf`: jwm: what you change in the browser is only transient - for that browser and only until you reload the page

2:00 you need to be able to push updated source as well, and run lein cljsbuild auto on the server :)

2:00 jwm: yeah I run auto on the server

2:01 but if it is a nrepl in browser wouldn't it update clojure?

2:01 seancorf`: Frozenlock: range has a step argument

2:02 jwm: if your repl is connected to the browser, it's only affecting the running JS image - in the browser

2:02 the repl to the server will modify the (shared) server image, until the process is restarted

2:02 Frozenlock: seancorf`: I know, but it won't skip a step if needed.

2:03 seancorf`: Frozenlock: oh i see, you want the [0,500) divided by 400 and the nearest int used?

2:03 dbasch: ,(range 10 100 20)

2:03 clojurebot: (10 30 50 70 90)

2:04 seancorf`: jwm: whenever you reload the browser, you'll lose any repl-made changes - unless you've also pushed them in source to the server (which is what we plan to do)...

2:04 jwm: yeah, if you have an nrepl from the browser console to your server though

2:04 you're actually evaling into the clojure nrepl connection

2:04 dbasch: Frozenlock: do it for a multiple and then divide

2:04 seancorf`: ah, that wasn't what i thought you meant

2:04 jwm: of course then when you restart the server it would lose changes

2:05 yedi: dbasch: i'm guessing adding a `lein clean` to the start of this would be ideal? https://github.com/yedi/reasoned-rhymer/blob/master/deploy.sh

2:05 dbasch: yedi: yes, mine does a clean first

2:05 jwm: I played with bodil's catnip a bit

2:05 seancorf`: jwm: why use a browser-based login for the repl-to-server setup? why not just use LightTable and a VPN? :)

2:06 jwm: haha

2:06 yeah I do that now (vpn.. well autossh)

2:06 dbasch: ,(range 1 100 (quot 100 13))

2:06 clojurebot: (1 8 15 22 29 ...)

2:06 jwm: seancorf`: I want to go to session based coding in the future

2:06 for my own personal ide project :)

2:06 seancorf`: anyways, late here ... bed time...

2:07 jwm: same here night thanks for the help

2:08 actually they could make lighttable semi-embeddable into browser

2:08 ontoillogical: hello all, I'm trying to use this Java library in clojure and I'm having trouble importing it https://clojars.org/org.clojars.smallrivers/simplecaptcha/versions/1.2.1 . The class I want to use is nl.captcha.Captcha

2:08 jwm: that would be pretty meta

2:09 ontoillogical: I can't figure out how to require it, (require 'org.clojars.smallrivers.simplecaptcha.Captcha) doesn't work, neither does (require 'nl.captcha.Captcha)

2:11 jwm: it would just be org.clojars.smallrivers no?

2:12 ontoillogical: jwm: (require 'org.clojars.smallrivers.Captcha) and (require 'org.clojars.smallrivers.nl.captcha.Captcha) both fail :(

2:14 jwm: what about org.clojars.smallrivers

2:14 amalloy: you don't use require to talk to java classes. you import them

2:14 jwm: this is on maven though no?

2:16 ontoillogical: amalloy: ohhhhhh

2:16 jwm: (import '[org.clojars.smallrivers Captcha])

2:17 ontoillogical: import!

2:17 thanks all

2:17 jwm: hehe I got stumbled by that on a few of the ones without docs

2:18 ontoillogical: so it looks like this is a library on clojars that just contains the java classes, no clj wrapper. Is this common?

2:18 dbasch: ontoillogical: yes

2:19 ontoillogical: dbasch: is there a need to repackage java libraries for clojure, or is this just to make pulling them down from clojars using lein or what not convenient?

2:20 dbasch: convenience, people do it all the time

2:20 especially for the ones out of github that are not on maven

2:21 I’m guilty of that myself: https://clojars.org/org.clojars.dbasch/bip38

2:22 jwm: I use org.clojars.subethasmtp

2:27 I didnt know you could make a vector as a key

2:29 {[:spool :web] {:test 234},

2:29 that looks terrible

2:29 hehe

2:48 sm0ke: weird literal tag behaviour

2:48 if i pass a fucntion to a literal tag, it converts it to a symbol

2:51 owl-v-: is (reduce) == (apply) ???

2:51 lazybot: owl-v-: Yes, 100% for sure.

2:51 dbasch: owl-v-: no

2:51 owl-v-: haha

2:52 lazybot~

2:53 i can't tell difference between (reduce) and (apply)

2:53 dbasch: for one, reduce applies to two-argument functions

2:54 apply uses a list as arguments to a function

2:56 e.g.

2:56 (defn f [a b c] (println (+ a (* 10 b) (* 30 c))))

2:56 (apply f [1 2 3])

2:56 that won’t work with reduce, it would be meaningless

2:59 magopian: dbasch: owl-v-: i guess the confusion comes from functions that accept any number of arguments, like "str"

3:00 (i'm a noob and keep getting confused about that myself)

3:00 dbasch: magopian: sometimes you can get the same result with reduce or apply, but you should know what you’re doing and why

3:01 reduce keeps “carrying” a result and computing the operation with the next value

3:01 magopian: ,(reduce str ["a" "b"])

3:01 clojurebot: "ab"

3:02 magopian: ,(apply str ["a" "b"])

3:02 clojurebot: "ab"

3:03 magopian: with reduce, however, you can do nice things like specify a starting point

3:03 ,(reduce str "starting point" ["a" "b"])

3:03 clojurebot: "starting pointab"

3:03 Frozenlock: dbasch: seancorfield: That's what I settled with. It never returns more than the number of steps asked, and strech the range as much as it can. https://www.refheap.com/78060

3:05 owl-v-: ,(apply str "starting point" ["a" "b"])

3:05 clojurebot: "starting pointab"

3:06 owl-v-: ,(apply str "starting point" ["a" "b"] " fun")

3:06 clojurebot: "starting point[\"a\" \"b\"] fun"

3:06 owl-v-: ,(reduce str "starting point" ["a" "b"] " fun")

3:06 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: core/reduce>

3:07 owl-v-: (apply) > (reduce) ???

3:07 lazybot: owl-v-: How could that be wrong?

3:11 dbasch: ,(map (comp #(Math/round %) float) (range 0 20 (/ 20 18)))

3:11 clojurebot: (0 1 2 3 4 ...)

3:11 dbasch: Frozenlock: would that work?

3:13 or

3:13 ,(map (comp int #(Math/floor %) float) (range 0 20 (/ 20 18)))

3:13 clojurebot: (0 1 2 3 4 ...)

3:13 Frozenlock: ,(count (map (comp #(Math/round %) float) (range 0 100 (/ 100 90))))

3:13 clojurebot: 90

3:14 Frozenlock: looking now :-p

3:15 jonasen: owl-v-: (apply f [x y z]) -> (f x y z)

3:15 (reduce f [x y z]) -> (f (f (f x) y) z)

3:16 sorry, it's actually (reduce f [x y z]) -> (f (f x y) z)

3:16 Frozenlock: dbasch: I'd say it works o_O

3:16 Wow I'm terrible

3:17 I see, you steps in fraction and turn it into integers only when finished

3:17 jonasen: and with an initial value: (reduce f init [x y z]) -> (f (f (f init x) y) z)

3:18 dbasch: Frozenlock: the same thing happens to me when looking at the best 4clojure solutions

3:19 Frozenlock: dbasch: the 'wow I'm terrible' part?

3:19 dbasch: Frozenlock: yes

3:19 Frozenlock: Keeps your ego in check :)

3:20 owl-v-: ,(apply (fn [n m] (Math/pow n m)) [2 3 4])

3:20 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: sandbox/eval79/fn--80>

3:20 owl-v-: ,(reduce (fn [n m] (Math/pow n m)) [2 3 4])

3:20 clojurebot: 4096.0

3:21 owl-v-: :-)

3:22 jonasen: owl-v-: you see the difference now? ((Math/pow 2 3) 4) vs. (Math/pow 2 3 4). The latter throws an ArityException

3:22 owl-v-: it does :)

3:22 TEttinger: ,(reduce (memfn Math/pow) [3N 4N 5N])

3:22 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox/eval131/fn--133>

3:23 owl-v-: thanks

3:23 jonasen: That first one should ofcourse be (Math/pow (Math/pow 2 3) 4)

3:27 dbasch: Frozenlock: btw, (map int (range…))) works fine, I was just trying to get closer to the numbers in your example

3:28 dissipate: which approach to polymophism is considered more 'idiomatic' in clojure? protocols, multimethods or just plain old functions as parameters?

3:29 i seeing quite a few open source projects using protocols a lot. but it reminds me more of OO style programming

3:30 dbasch: dissipate: multimethods http://clojure.org/runtime_polymorphism

3:30 jonasen: dissipate: I usually start with plain functions (polymorphism isn't always needed). If I do need polymorphism I'd go with multimethods first. They are more flexible and often efficient enough

3:31 dbasch: (inc jonasen)

3:31 lazybot: ⇒ 1

3:31 Frozenlock: dbasch: I see that. I think at the beginning I wanted to avoid duplicates in case of steps <1 and got lost from there.

3:32 dbasch: Frozenlock: well, with steps < 1 you have to use floats or fractions

3:32 Frozenlock: (distinct (map int (range..))) is way simpler anyway

3:34 dbasch: Frozenlock: steps < 1 means you want more than the range, or else just use 1

3:35 dissipate: jonasac, my situation is that i want to write some functions that are going to kick off and keep track of some running tasks, but i want to create an 'interface' so that i can easily swap out for a different implementation if needed later. for instance, i want to do 'start-task', 'stop-task' etc.

3:35 Frozenlock: There, fool(me)-proof (map int (range from to (max 1 (/ to in-n-steps))))

4:07 ptcek: exit

4:14 owl-v-: if i have function (defn filter-red [image] (filter-color image "red")) will i have copy of image inside of the function 'filter-red'?

4:25 dissipate: owl-v-, depends on what you mean by 'copy', but 'image' will be bound locally to whatever is passed in to that function as that param

4:27 owl-v-: image as array of pixels

4:29 dissipate: owl-v-, you mean a vector? or a list?

4:29 owl-v-: (let [image (get-image-from-camera 0)] (filter-red image))

4:29 list/vector matters?

4:30 dissipate: owl-v-, not really, but 2 different data structures

4:31 owl-v-: all i want to know is does image in the function have duplicated image or not?

4:33 dissipate: owl-v-, it will be bound to the list/vector, yes. lists and vectors are persistent data structures, which means that essentially what you get is a 'copy' of the data structure when the function is called.

4:34 owl-v-, more on that here: http://clojure.org/data_structures

4:35 owl-v-: is there way to pass reference?

4:36 dissipate: owl-v-, yep, instead of a list/vector, it could be a ref. more on those here: http://clojure.org/refs

4:48 owl-v-: how do i update value just like c or python?; 'a = 0' -> 'a = 1'

4:49 if i don't want to have old value?

4:53 dissipate: owl-v-, it depends on what you are trying to do

4:53 owl-v-: y?

4:54 (def a 0) and then (def a 1) ?

4:54 dissipate: owl-v-, because in Clojure, mutation is managed. and there are different ways of managing mutation depending on what you are doing.

4:55 owl-v-, atoms are one of the simplest ways of doing mutation in clojure. but there are also transients.

4:57 owl-v-, http://clojure.org/atoms

4:59 owl-v-, this blog post gives more of an overview: http://blog.fogus.me/2011/07/12/no-stinking-mutants/

5:06 owl-v-: the reason i need to remove old value is because i need to get image forever~

5:06 a new image for each iteration

5:07 perses: hello, i just tried jiraph lib, and when i did lein run, i got http://sprunge.us/FciM

5:07 is there anybody help pleasE?

5:07 owl-v-: start (get image) (filter image) (display image) loop

5:09 if i don't get rid of old images, stack overflow may occur.

5:10 dissipate: owl-v-, sounds like you could use a lazy sequence: http://clojuredocs.org/clojure_core/clojure.core/lazy-seq

5:11 owl-v-, set up a function that generates the images and then use 'lazy-seq' so you can keep getting images from it

5:21 perses: please anybody here can help

5:21 http://sprunge.us/FciM , how may i fix this?

5:33 i changed the version to the recent and i got another errors http://sprunge.us/WUPO

5:39 jonasen: perses: Is jiraph in your :dependencies vector in project.clj?

5:42 perses: jonasen: http://sprunge.us/FbDS

5:44 jonasen: perses: looks ok

5:44 perses: jonasen: what maybe cause this ?

5:47 jonasen: perses: what does your (:require ..) form look like? I think you should require the flatland.jiraph.graph namespace

5:51 perses: jonasen: http://sprunge.us/iNXI

5:52 jonasen: perses: Try removing (use 'jiraph.graph)

5:57 perses: jonasen: check usage section https://github.com/ninjudd/jiraph , i need to define use stuff to can use the methods there, when i tried without it i got undefined

6:01 jonasen: perses: I think the usage section might be outdated. I can find no jiraph.graph namespace in the source code.

6:01 maybe they have reorganized the namespace structure or something

6:05 owl-v-: how do i use java api?

6:06 jonasen: owl-v-: which one?

6:06 owl-v-: java gui

6:07 java.awt

6:09 jonasen: owl-v-: you import the classes you want to use and use them with Clojure's Java interop support: http://clojure.org/java_interop

6:10 perses: jonasen: http://sprunge.us/FQYH i tried simple example from usage but without use 'jiraph.graph with require part you mentioned, and got this error

6:10 maveneagle: hey folks, are there any forum where i can find recent whitepapers about computer science and software development in general? hacker news is good but not all whitepapers makes its way to hacker news..

6:13 jonasen: perses: You'll probably have to study the source code if the usage examples are out of date. My guess is the namespace jiraph.masai-layer has been renamed to flatland.jiraph.layer.masai

6:14 perses: ah ok

6:30 kras: what is the difference between filter and remove?

6:30 ,(doc filter)

6:30 clojurebot: "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."

6:30 kras: ,(doc remove)

6:30 clojurebot: "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns false. pred must be free of side-effects."

6:31 llasram: kras: false vs true from the pred

6:31 kras: oops, overlooked it

6:31 thanks

6:32 fn names are little confusing though

6:32 filter-if filter-if-not sounds better, no?

6:54 owl-v-: why can't i call java class? https://www.refheap.com/78079

7:00 class not found exception; https://www.refheap.com/78080

7:01 penthief: owl-v-: Dunno, can you call the constuctor with the package name included? (org.opencv.objdetect.CascadeClassifier. ...) If not, then my guess is its not on the path. Does "ps -wef|grep java" show the relevant library?

7:07 I don't much like, nor understand why add-watch agent functions are called about 3 times instead of once, because I was hoping that I could use an add-watch function as an async callback for a send-off IO operation.

7:28 Frozenlock_sleep: That's weird... congomongo just started giving me back strings instead of joda DateTime

7:31 jwm: is there a good way to output the contents of a ref straight to a file

7:31 that has mix and match content (mime file types, buffered data byte streams, etc)

8:04 petron: hey peeps. I need some help with my Clojure workflow. I can't believe how hard it is to not wait 3 seconds every time I run "lein test".

8:04 I'm not an Emacs user.

8:04 I like Light Table, but maybe it's the wrong IDE.

8:04 I just want to run tests every time I change my source or test files, without restarting the repl each time.

8:04 agarman: I suggest prism

8:05 beamso: https://github.com/jakemcc/lein-test-refresh or https://github.com/dakrone/lein-autotest ?

8:05 agarman: https://github.com/aphyr/prism

8:05 I've tried them all...prism just runs tests relevant to the namespace

8:06 petron: thx, I'll try that

8:06 beamso: can you use prism without using midge?

8:06 s/midge/midje/

8:06 agarman: I'm not using midje

8:06 so probably :-)

8:07 beamso: ha. okay.

8:07 agarman: I checked prism's dependencies...it's not pulling in midje, so I can give a definitive yes

8:08 petron: prism exits

8:08 if I run "lein prism", it runs tests once, and exits

8:08 (I'm on Windows, if that matters)

8:08 beamso: oh. i've misread an "inspired by midje's excellent autotest".

8:08 agarman: no, it's that you have to reference it in your deps

8:09 in my lein profile :user { :dependencies [com.aphyr/prism "0.1.2" :scope "test"]

8:09 petron: I followed the instructions on the GitHub repo and placed the plugins and dependencies lines in my ~/.lein/profiles.clj file.

8:10 agarman: it may be a windows thing then...I'm on a mac and also use this on an ubuntu machine

8:11 petron: prism 0.12 seems to work, even without the :scope "test" thing

8:11 I was on prism 0.11

8:11 it did not auto-watch

8:11 agarman: ah, ok

8:11 petron: so I'm presuming 0.12 may have a fix for windows

8:11 agarman: the :scope test is to keep the dep from getting to production

8:12 petron: now I'm getting a "failed to reload..."

8:12 my project is called "b"

8:13 when I change b/src/core.clj, I get "java.io.FileNotFoundException: Could not locate \path\to\b\src\b\core__init.class"

8:13 do I need :gen-class somewhere maybe?

8:13 agarman: no

8:14 it could be an issue with windows still

8:14 yedi: i think it should be b/src/b.core.clj

8:14 i think it should be b/src/b/core.clj *

8:16 petron: it appears to be watching the right folders

8:16 and my source is at b/src/b/core.clj

8:18 oh nm I have a typo in my project.clj

8:19 agarman: @petron it all working now?

8:20 petron: hmmm no :\ fixed project.clj, but still getting "Could not locate \b\src\b\core__init.class or \b\src\b\core.clj on classpath: ..."

8:21 I don't have :classpath in project.clj, but it must be inferring it correctly because it shows "Watching *\b\src *\b\test" when I run "lein prism".

8:21 where * is /path/to/parent-directory/

8:23 agarman: you can always fall back to https://github.com/jakemcc/lein-test-refresh

8:27 petron: thx agarman, lein test-refresh is working

8:27 this is great

8:28 right now it's wayyy to hard to get these simple things working and I hope leiningen becomes better at automatically pulling in plugins or something, for newbies.

8:31 agarman: something like lein-try for plugins?

8:38 kras: how do I pass a seq of args to a macro

8:39 (apply fn args) doesn;t seem to take macro for a fn

8:39 ,(apply and [true false])

8:39 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)>

8:40 gfredericks: kras: you don't -- what do you actually want to do?

8:40 kras: (defn xor [& xs] (and (and xs) (or xs)))

8:41 I am trying to see if I can make this function work as expected

8:41 unfortunatley and with a seq doesn;t work as expected

8:41 ,(and [true false])

8:41 clojurebot: [true false]

8:41 gfredericks: well if this is for serious, you'd want to write a macro instead so that it can short-circuit like and/or do

8:42 but if you don't care about short-circuiting you can implement the required logic with reduce

8:44 kras: any of the higher order functions won;t take a macro I guess since it gets unwrapped

8:44 gfredericks: you also might want to look at every? and some for function-based analogs of and/or

8:45 I guess a proper xor can't short-circuit anyhow

8:45 so you could just do

8:45 ,(defn xor [& xs] (reduce #(cond-> %1 %2 not) false xs))

8:45 clojurebot: #'sandbox/xor

8:45 gfredericks: ,(xor true true true)

8:45 clojurebot: true

8:45 gfredericks: ,(xor true true)

8:45 clojurebot: false

8:46 gfredericks: ,(xor true false false false true)

8:46 clojurebot: false

8:46 gfredericks: ,(xor)

8:46 clojurebot: false

8:48 kras: gfredericks: thanks, never used cond-> will lookup

8:48 gfredericks: slightly longer without it: #(if %2 (not %1) %1)

8:52 oskarth: ,(doc cond->)

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

9:47 jwm: is there an easy way to serial a map to a file that contains mime/stream data?

9:47 serialize*

9:47 seems like a hard task to solve

9:50 arrdem: you can't generally stream a map..

9:50 you have to impose some constraint like ordered keys or fully known keys

9:51 jwm: yeah I was hoping there would be a library that does it

9:51 like right now I store emails in a map "spool"

9:51 basically just keyworded map for inboxes

9:51 emails have mime and base64 encoded data which gets to become a base64decodestream

9:51 probably due to subetha doing that for me

9:52 I was hoping I could just take the map and serialize it to disk

10:01 cool just found Nippy

10:01 serializing library

10:05 guess I'll worry about serialization later

10:23 ssqq: When a string match a regexp, How to get the location of the matched substring?

10:26 bbloom: ssqq: you probably need to use re-matcher

10:27 ssqq: bbloom: Maybe, I try it.

10:28 bbloom: ssqq: i'd probably just use the facilities of java.util.regex direclty for more specialized use cases

10:29 ssqq: bbloom: Thanks.

10:46 wildeyes: Hello

10:46 Anybody here?

10:47 AeroNotix: No

10:47 wildeyes: Sup aero

10:51 joegallo: no one is here

10:51 jwm: whats a good pattern for doing something every few minutes in clojure?

10:52 coventry: A core.async go block which waits on an async/timeout channel.

10:53 bbloom: jwm: on the jvm, you can just use a timer class

10:53 joegallo: java.util.concurrent is full of nice things for that, too

10:53 jwm: hmm too many choices

10:53 :)

10:53 joegallo: and, of course, there's quartz

10:53 jwm: figured as much

11:01 llasram: For an in-between there's https://github.com/overtone/at-at

11:01 wildeyes: Lala

11:02 xwildeyes: Hello?

11:02 bbloom: dnolen_: i spent > 2 days trying to fix that damn bug. today, i fixed it in 20 minutes

11:03 PSA: take a fucking break everyonce in a while guys, debugging is mentally taxing & you need your beauty rest.

11:03 hfaafb: doesn't necessarily mean those > 2 days weren't required :)

11:05 bbloom: hfaafb: i'll tell myself that so that i feel better about it, thanks :-P

11:05 coventry: bbloom: If only it were possible to grind away at a perplexing bug without getting frustrated, maybe it wouldn't be so taxing.

11:06 tudd: bbloom: state-transition, both in code and in person. Mix up your environment. put your computer somewhere else. change _something_ about your physical state. change in mental state follows. hard bugs become "obvious" how to fix.

11:08 coventry: (Didn't mean that as advice, don't know an easy answer.)

11:09 xwildeyes: Good thing clojures functional or mind perplexing would have been almost like a death sentence :p

11:09 Say, who's here doing some cljs?

11:10 jwm: hehe quartz would take me a week to learn/use

11:18 BobSchack: xwildeyes I'm doing some clojurescript and the is the clojurescript irc channel

11:18 devn: ,(require '[clojure.walk :as walk])

11:18 clojurebot: nil

11:19 devn: (map #(-> (zipmap ["a" "b" "c"] %) walk/keywordize-keys) (repeat 3 [1 2 3]))

11:19 ,(map #(-> (zipmap ["a" "b" "c"] %) walk/keywordize-keys) (repeat 3 [1 2 3]))

11:19 clojurebot: ({:c 3, :b 2, :a 1} {:c 3, :b 2, :a 1} {:c 3, :b 2, :a 1})

11:20 devn: walk/keywordize-keys uses postwalk, postwalk consumes seqs "as with doall" -- does that mean the right hand side above will be realized with doall? no right? just each sub seq, right?

11:25 coventry: ,(time (do (map #(-> (zipmap ["a" "b" "c"] %) walk/keywordize-keys) (repeat [1 2 3])) 1))

11:25 clojurebot: "Elapsed time: 0.145169 msecs"\n1

11:26 coventry: ,(time (map #(-> (zipmap ["a" "b" "c"] %) walk/keywordize-keys) (repeat [1 2 3])))

11:26 clojurebot: "Elapsed time: 0.142967 msecs"\n({:c 3, :b 2, :a 1} {:c 3, :b 2, :a 1} {:c 3, :b 2, :a 1} {:c 3, :b 2, :a 1} {:c 3, :b 2, :a 1} ...)

11:26 devn: annnndd that is my answer

11:26 thanks coventry

11:26 i cant brane gud today

11:41 arrdem: devn: it's okay, just get some coffee and we'll be here when you can function again :D

12:03 shiranaihito: what's the most common mistake that causes an AbstractMethodError when trying to implement clojure.lang.IFn for a record? -It blows up from Compiler.eval() at fn.applyTo(..) .. do i need to somehow implement "applyTo" in addition to "invoke"?

12:03 llasram: shiranaihito: Yes -- when implementing IFn, you always need to implement applyTo

12:03 shiranaihito: hm

12:04 llasram: It's not difficult to express in terms of your invoke implementations though

12:04 shiranaihito: llasram: alrighty, thanks :p and is there something special to implementing it? .. oh, so i can just delegate to "invoke" by calling the "this" given to applyTo?

12:05 llasram: yep

12:05 shiranaihito: ok, cool, let's see..

12:05 mmm the explosion went away :P

12:06 llasram: is implementing IFn a sign of trouble in general, though? .. or just business as usual?

12:07 llasram: It depends on why you're doing it. In my experience it isn't common, but sometimes is really useful

12:08 Usually when I think "I'd like a thing which I can call as a function," what I really want is a function :-)

12:08 shiranaihito: :P

12:09 well, i've got a record that acts as a placeholder for a couple of values, and participates in a protocol, aaaaand now implements IFn

12:10 if i haven't done anything dirty, then i guess this is just a good example of why Clojure is awesome :P

12:10 llasram: In your case, what's the benefit of the record also being a function vs producing closures over the records when you need them?

12:10 shiranaihito: at least using it this way will result in neatness for what i'm doing

12:11 closures over the records?

12:11 llasram: kk

12:11 shiranaihito: :P

12:11 you're confusing me :p

12:11 llasram: Oh, like (partial mk-my-record-fn record)

12:12 shiranaihito: but the record kind of represents both "state" _and_ something to call.. it's supposed to act like a ring handler, and ofc, it's like a part of a web-application too

12:12 llasram: I see

12:12 shiranaihito: hmm, well, i guess i'll just continue and see how it goes.. looks promising so far

12:12 thanks for the tip!

12:24 btcNeverSleeps: hey all, I'm trying to learn macro and I want to try to write a macro which can take either 1 or 2 argument, but which should fail if there are 0 or 3 arguments passed to the macro. Is (defmacro sample [a & [b & c]] ...) the way to go?

12:25 sir: btcNeverSleeps: or sir you could do two bodies, one with one arg, one with two

12:25 btcNeverSleeps: sir that would likely be the cleanest way

12:26 btcNeverSleeps: sir: so macros, just like functions, can accept multiple arities?

12:26 sir: btcNeverSleeps: yes sir

12:26 btcNeverSleeps: sir: thank you sir!

12:26 * btcNeverSleeps is trying that right away

12:26 sir: btcNeverSleeps: you're welcome sir

12:27 hyPiRion: I thought #clojure suddenly turned extremely polite, then I realised sir is a nickname.

12:28 btcNeverSleeps: seems to be the nickname of someone extremely polite ^ ^

12:29 sir: btcNeverSleeps: why thank you sir

12:29 hyPiRion: sir, your nickname makes everyone so polite. So magical.

12:30 dkinzer: :)

12:33 btcNeverSleeps: does this look correct to you: (defmacro sample ([a] `(uch ~a nil)) ([a b] `(do (println "a: " '~a " b: " '~b) ~a ~b))) (trying to write a macro with arity either 1 or 2, but not 0 nor 3+)

12:33 oops

12:33 (defmacro sample ([a] `(sample ~a nil)) ([a b] `(do (println "a: " '~a " b: " '~b) ~a ~b)))

12:33 sir: btcNeverSleeps: seems right to me sir

12:34 hyPiRion: humm, is Eastwood/some other linter able to detect poor usage of transients?

12:34 sir-or-maam: btcNeverSleeps: You can test it with commands like (macroexpand '(sample arg1 arg2 arg3))

12:36 justin_smith: hyPiRion: if they don't one would think it would be easy to add

12:37 hyPiRion: https://github.com/jonase/eastwood/search?q=transient&ref=cmdform

12:38 sir: btcNeverSleeps: only way to find out is to try it and see sir

12:38 hyPiRion: justin_smith: hrm, doesn't look too comprehensive

12:38 sir: btcNeverSleeps: also, try to never use macros

12:38 btcNeverSleeps: macros are almost never ever worth it

12:40 justin_smith: https://github.com/jonase/eastwood/blob/266a76732da84d829de21ab3e3ad50b50e826adc/resource/var-info.edn hyPiRion a search for ! in this ns finds the transient ops, plus "warn-if-ret-val-unused" on all of them

12:40 which should be what we would want

12:41 *in this resource edn file

12:41 hyPiRion: justin_smith: That's part of it, but it should complain if I do e.g. (do (conj! a 1) (conj! a 2))

12:42 justin_smith: wouldn't "warn-if-ret-val-unused" complain about that?

12:42 or do I misunderstand that flag?

12:42 hyPiRion: justin_smith: alright, perhaps this is a better example

12:42 btcNeverSleeps: sir: I'm writing a macro which spawns a thread (consuming from a queue) which shall should stay active for the lifecycle of the app and which shall take care of logging should an exception happen (otherwise if I never deref the future I may miss the exception). So I need to "wrap" code in a try / catch block.

12:43 hyPiRion: (let [a (transient! #{1 2}) b (conj! a 3) c (conj! a 4)] [a b c]) is very bad

12:43 btcNeverSleeps: sir: don't know if I should do it with a function or a macro

12:43 justin_smith: oh yeah...

12:43 hyPiRion: So a linter should invalidate multiple transient calls on the same transient.

12:43 justin_smith: hyPiRion: that requires some higher order logic for sure - more than we seein in Eastwood I think

12:43 sir: btcNeverSleeps: it'd be significantly better to write it as a function that takes a (possibly anonymous) function sir

12:43 justin_smith: right

12:43 hyPiRion: justin_smith: probably

12:44 I haven't looked too much at Eastwood, which is why I asked in the first place :p

12:44 sir: btcNeverSleeps: the only legitimate reason for writing macros is to "extend" the language in an extremely generic and unspecific way, like ->> and -> do, for example

12:44 btcNeverSleeps: sir: it'd be significantly better because macros would be avoided?

12:45 sir: btcNeverSleeps: yes, macros are significantly less flexible than functions and should be avoided mostly.

12:45 btcNeverSleeps: the good news is that your original question still applies even to writing functions, so your learning this morning has not been in vain sir

12:45 btcNeverSleeps: sir: it's late afternoon on this side of the pond sir! ; )

12:46 justin_smith: btcNeverSleeps: it may help to ask yourself "will making this a macro offer anything a function wouldn't?" - if no, functions are simpler and easier to reason about and to use

12:46 hyPiRion: ~UGT

12:46 clojurebot: UGT is Universal Greeting Time http://www.total-knowledge.com/~ilya/mips/ugt.html

12:46 sir: btcNeverSleeps: ugt is intended to fix that, but which has flaws of its own

12:47 UGT is the Go of sociality.

12:47 btcNeverSleeps: I like it, UGT looks nice.

12:47 sir: So did Go.

12:47 btcNeverSleeps: so now I learned two things this morning!

12:47 hyPiRion: hehe

12:47 It's always morning on IRC

12:47 sir: Sounds like a good time to call it a day and pack it up.

12:48 justin_smith: {{greeting-for time-of-day}} {{time-of-day}} everyone!

12:48 Averell: this morning (ugt)?

12:49 btcNeverSleeps: back to my question: if I write a function (instead of a macro), then I now have to pass one (or two) function(s) as argument(s). Doesn't using functions instead of macros lead to code with lots of (anonymous) functions? (at least when your macro/functions plans to "wrap" code)?

12:50 sir: btcNeverSleeps: yes, and that's good

12:50 btcNeverSleeps: anonymous functions are not that hard or ugly to create in Clojure, and very flexible too.

12:50 hyPiRion: not sure what you mean

12:51 ,(defn foo ([a] (foo a 1)) ([a b] (+ a b)))

12:51 clojurebot: #'sandbox/foo

12:51 sir: btcNeverSleeps: look at the API for compojure, it works almost entirely on anonymous functions

12:51 btcNeverSleeps: actually don't look at it

12:51 hyPiRion: ,[(foo 1) (foo 1 2)]

12:51 clojurebot: [2 3]

12:52 sir: hyPiRion: sir he seems more concerned about it being verbose if he doesn't hide the creation of anonymous fns for the end-user

12:52 hyPiRion: oh right, in the macro he created

12:52 btcNeverSleeps: I'll give an example

12:52 sir: btcNeverSleeps: use refheap.com sir

12:55 btcNeverSleeps: ,(defmacro tm [code] (let [t (gensym)] `(try ~code (catch Throwable ~t (println "doing logging here")))))

12:55 clojurebot: btcNeverSleeps: Gabh mo leithscéal?

12:55 hyPiRion: not allowed, I'm afraid

12:55 btcNeverSleeps: macros aren't allowed?

12:55 hyPiRion: not in clojurebot

12:56 btcNeverSleeps: I see, I'll use refheap

12:56 hyPiRion: Or perhaps it's the try catch statement

12:56 justin_smith: btcNeverSleeps: why not use & code / ~@code to allow an arbitrary body of expressions (which try already supports)

12:57 also t# ... ~t#

12:58 and maybe (let [t# (gensym "ErrorCaught") ...

13:03 btcNeverSleeps: https://www.refheap.com/78308

13:04 the goal is both to solve my issue and to learn how (and when to use or not) macros ^ ^

13:06 I don't want to have to manually call try / catch and add specific logging code everytime I'll run producers / consumers that shall live for the lifecycle of the app

13:07 so instead of doing (future ...) I want to do something like (spawn-with-logging-if-exception-caught ...) [name is facetious], but which acts like a future, excepts that exceptions are transparently caught and logged

13:07 because I've had the case where exceptions in future would "magically" disappear (I've seen both blogs entries and talks about Clojure mentioning that "feature" )

13:07 for example, at the REPL:

13:08 ,(future (/ 0 0))

13:08 clojurebot: #<SecurityException java.lang.SecurityException: no threads please>

13:08 btcNeverSleeps: ok well... at the REPL this give a "division by zero"

13:08 but

13:08 justin_smith: btcNeverSleeps: my suggestion for the macro (tested and works in my repl) https://www.refheap.com/78309

13:08 btcNeverSleeps: (future (do (Thread/sleep 1000) (/ 0 0)))

13:08 (future (do (Thread/sleep 1000) (/ 0 0))) <-- exception is now nowhere to be seen, magically disappeared once a small delay is introduced

13:09 justin_smith: btcNeverSleeps: is this in emacs?

13:09 you will see it if you have the repl running in a terminal (this is why I avoid the *-jack-in commands actually)

13:09 sir: It's like I always say: use it up, wear it out, make do, or do without.

13:10 btcNeverSleeps: justin_smith: yup, in Emacs

13:10 justin_smith: there will likely be a *<foo>-messages* buffer that catches some if not all of that stuff

13:10 btcNeverSleeps: ah damn

13:10 justin_smith: yeah, that is why I don't use the jack-in stuff - just connect to a repl in a terminal, the extra step adds clarity

13:11 btcNeverSleeps: justin_smith: do you connect to a repl in a terminal from inside Emacs? (say from an eshell Emacs buffer) Or directly in a "real" terminal, without using Emacs for the REPL at all?

13:11 justin_smith: I start the repl in a terminal, and it opens a repl listener, I connect to that via emacs

13:12 some things print in the emacs repl, some print in that terminal, but nothing goes missing (or so it seems)

13:12 btcNeverSleeps: justin_smith: ah, that's interesting, so I do, say "lein repl" and then what do I need to do from Emacs?

13:12 justin_smith: do you use cider or nrepl?

13:12 btcNeverSleeps: cider

13:12 justin_smith: M-x cider

13:13 give it the port name that lein repl printed

13:13 btcNeverSleeps: gotcha... cider, without -jack-in

13:13 justin_smith: yeah

13:13 bonus, you can kill emacs without losing the repl, and visa versa

13:13 (or more easily do these things)

13:14 btcNeverSleeps: I'll probably do that too from now on... In addition to that I'm using timbre/{debug,info,warn,error} logging for my app and have a terminal constantly doing a "tail -F logfile"

13:14 justin_smith: sounds great, definitely trying it ASAP

13:14 justin_smith: you can think of it as connecting the repl and editor, rather than trying to combine them (with all kinds of leaky abstraction); "decomplecting", as they say

13:15 btcNeverSleeps: another option is that emacs has a tail mode

13:15 M-x auto-revert-tail-mode

13:15 (on the log file buffer, of course)

13:15 btcNeverSleeps: I like timbre's ANSI logging (for exceptions it is really quite clear and helpful, the colored output really helps). I also configured my Emacs / cider buffer so that ANSI escapes are converted to colors.

13:16 justin_smith: cool

13:16 btcNeverSleeps: justin_smith: I'll check auto-revert-tail-mode too

13:16 owl-v-: I'm having some difficult time getting the concept of (lazy-seq)

13:17 btcNeverSleeps: owl-v-: takes some time to get used to, best is probably to try to write some and things should become clearer

13:17 justin_smith: owl-v-: it is the only way to create something lazy, as far as I know

13:19 btcNeverSleeps: owl-v-: funny that Rich Hickey's only answer on SO is about lazy seqs and doall: http://stackoverflow.com/questions/1641626/how-to-convert-lazy-sequence-to-non-lazy-in-clojure

13:19 coventry: owl-v-: You're not supposed to learn from clojure.core, but you might have a look at these functions: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L2618

13:20 * btcNeverSleeps shall bbl

13:22 coventry: owl-v-: It's useful to take those and redefine them with (println)s in the beginnings of the functions and the (when) blocks and see how they behave as you take elements from the seqs they create.

13:28 dbasch: coventry: btw, I solved my cljs config for dev/prod with different paths to config.cljs in profiles. I prefer avoiding macros for those things.

13:28 in fact I prefer avoiding macros period :)

13:29 coventry: I have a weakness for macros, but that sounds like a good arrangement. :-)

13:29 justin_smith: dbasch: what we do is to have resources/config/production.clj resources/config/development.clj etc. (really they are edn files we should fix the naming0

13:29 and then a runtim var decides which config to load

13:29 so the same artifact can be run locally, on staging, or on prod

13:31 dbasch: justin_smith: the problem is that for cljs you have one extra level of indirection

13:31 justin_smith: oh yeah, the artifact creation (and you may want to create a different js artifact based on config...)

13:34 dbasch: owl-v-: do the 4clojure exercises about lazy sequences, that forces you to learn

13:35 sandwichmaker: http://technomancy.us/161

13:35 *oops* sorry for that one, at least wasn't a password or a secret formula for success

13:36 sir: sandwichmaker: Yes you accidentally pasted that from #emacs sir.

13:37 sandwichmaker: sir: yeah, I clicked the mouse wheel by accident after selecting the url you wrote there :)

13:38 sir: sandwichmaker: I don't use linux anymore so I don't have that happen anymore fortunately.

13:39 justin_smith: Middle button paste is like my favorite thing. You may want to remap the scroll wheel button not to be button 2 though :)

13:39 sandwichmaker: sir: lol , I can understand that, I continually switch between OSX and Linux. I love them both, I hate them both :(

13:39 sir: sandwichmaker: sir I feel the same way

13:40 sandwichmaker: justin_smith: good advice

13:40 justin_smith: in .Xmodmap: pointer = 1 7 3 4 5 6 8 9 10 11 12 13 (not middle button is a back button in your web browser)

13:40 *now

13:40 sandwichmaker: :)

13:41 justin_smith: oh, sorry, 8 is the one for back in a browser

13:41 mutatis mutandis

13:41 hyPiRion: haha

13:52 owl-v-: dbasch: thanks

14:02 holo: hi

14:02 is there any way to build clojurescript on the REPL?

14:05 I mean like lein cljsbuild once

14:06 sir: Are there any theories on the declining popularity of Clojure?

14:07 Perhaps it could be due to Scala having a more familiar syntax and semantics to Java and Ruby than Clojure, which is more Lisp like and thus off-putting?

14:07 hyPiRion: declining? I thought it was steadily increasing, at least from what I gather from the Clojure surveys

14:07 llasram: sir: Yeah -- what suggests there is a declining popularity to Clojure?

14:08 holo: I converted a human to clojure recently :)

14:08 mi6x3m: hey clojure, I need some explanation about metadata

14:08 gtrak: sir: I've never heard this argument :-)

14:08 mi6x3m: it is the var that caries the metadata, right?

14:08 not the symbol

14:08 but on the otherhand, the symbol is bound to the var

14:08 amalloy: mi6x3m: i mean, you can put metadata on symbols and on vars. on lots of things, really

14:08 mi6x3m: unless I miss something and there's a way to create a 2nd reference to a var

14:08 amalloy: but is it the same?

14:09 sir: amalloy: but not consistently, such as not any kind of seq, only some kinds

14:09 hyPiRion: Scala came out earlier than Clojure, and they've been working more heavily on marketing Scala for the enterprise afaik. So it follows that it is more popular than Clojure right now

14:09 amalloy: well, only metadata on vars typically has stuff like :arglists, :tag, :added

14:09 that's added by the defn macro

14:09 llasram: mi6x3m: I mean, if you use `def`/`defn`, at run-time the metadata ends up on the Var

14:09 technomancy: holo: what did you do with the body when you were done?

14:09 llasram: But you can p

14:09 amalloy: but you could in principle put it on a symbol too if you wanted

14:09 llasram: ack

14:09 hyPiRion: Although I don't know if the growth decreases or increases relative to Scala's growth.

14:10 mi6x3m: amalloy: ok, I see

14:10 amalloy: and you can certainly have many symbols referencing the same var

14:10 holo: technomancy haha :}

14:10 mi6x3m: so var and symbol are different in terms of metadata

14:10 gtrak: we have 770 folks in the IRC channel here, and #scala has 470, just a data-point, maybe clojurists like IRC more :-)

14:10 llasram: mi6x3m: Well, when you have metadata on a symbol, it is on *that instance* of the symbol with a particular name

14:11 technomancy: holo: I'm imagining something like http://makerbot-blog.s3.amazonaws.com/wp-content/uploads/2012/06/TronTeleport.jpg

14:11 mi6x3m: llasram: symbols have instances?

14:11 wat

14:11 holo: I heard rumours 2014 was the year that #clojure overcomes #ruby

14:11 llasram: ,(identical? 'foo 'foo)

14:11 mi6x3m: isn't a symbol just itself

14:11 clojurebot: false

14:11 llasram: ,(identical? :foo :foo)

14:11 clojurebot: true

14:12 mi6x3m: llasram: I see

14:12 llasram: THat self-identity is what keywords are for, and is part of why keywords don't support metadata

14:12 sir: hyPiRion: Scala has a much more familiar syntax and semantics, being naturally imperative and line-based, with only a small part of functionality programming embedded

14:12 Bronsa: mi6x3m: unlike keywords, symbols are not interned.

14:12 mi6x3m: Bronsa: but how come

14:12 what is the motivation of this

14:12 llasram: Well for one thing it lets you have different metadata on different instances of a symbol :-)

14:12 Bronsa: mi6x3m: metadata

14:12 gtrak: sir: you should try ruby, it sounds right for you.

14:13 mi6x3m: only this reason ?

14:13 interesting

14:13 Bronsa: mi6x3m: I don't know of any other

14:13 llasram: gtrak: Hey, keep it clean. No need for insults

14:13 sir: gtrak: sir thank you for the suggestion it is not my intention to switch languages I am merely asking the question to provoke thought within the intellects

14:13 gtrak: there is no better way to growth within the community continuous learning

14:15 holo: they invented the Continuous Integration, the Continuous Deployment, now the Continuous Learning. what next? :D

14:15 mi6x3m: Bronsa: so evaluating "foo" creates a new instance of this symbol ?

14:17 gtrak: llasram: was curious if parkour can do sorts

14:17 cursory examination said no.

14:18 llasram: gtrak: In what sense? Generally Hadoop sorts for you

14:18 There's some tricks you can do to get what's called a "total order sort", which Hadoop comes with some utility classes to setup

14:19 I've never needed it, so have not yet integrated that into Parkour, but it should be usable via interop

14:19 amalloy: mi6x3m: i mean, you have to be careful, because "foo" is a string, not a symbol. and if you actually evaluate the symbol foo, you get whatever the value of foo is in the current context. only when the reader reads the string "foo", or you evaluate 'foo, or you evaluate something like (symbol "foo"), is an instance of Symbol created

14:20 gtrak: ah yea? maybe I'll give it a try. Just thinking through a problem, my experience is with cascading mostly, but I wouldn't use that to actually use hadoop :-).

14:20 llasram: gtrak: Cool. Feel free to ping me if you've got any questions

14:21 gtrak: thanks!

14:24 tpope: gtrak: :argslist-str should probably be "" rather than "nil" if there's no arglists

14:25 almost opened an issue but I feel weird popping up in emacs land

14:26 gtrak: ah, I can fix that :-)

14:26 amalloy: tpope: there's no visa requirements at the border. you're welcome to visit

14:27 gtrak: tpope: do you need the key to be there at all in that case? I bet that could happen for normal vars and namespaces.

14:27 tpope: nah

14:34 gtrak: I'm also wondering if you could provide a home for a "classpath" op, if I implemented it. you've already got a java.classpath dependency so it should be a trivial addition

14:35 gtrak: yea, that sounds reasonable

14:35 tpope: awesome, it's my last significant eval

14:35 the rest is just bs like require and macroexpand-1

14:36 gtrak: what do you use the classpath for?

14:37 tpope: gtrak: heuristically determining which repl connection to use, jump to source, and populating vim's 'path' option, which enables assorted built-in behavior

14:38 bbloom: tpope: you're practically a vim ambassador in the lisp embassy at this point. you should totally just go chill in #emacs

14:38 gtrak: ah, interesting.

14:38 bbloom: (i know nothing about diplomats, i'm sure that makes no sense)

14:38 tpope: lol

14:40 justin_smith: also you will have diplomatic immunity vs. any charges of trolling

14:40 if you get ambassador status, that is

14:41 gtrak: tpope: ah, that's why you want the relative path.

14:41 not sure we handle jump-to-def on remote repls, but it would need something like this.

14:43 tpope: yeah admittedly it's still mostly a hypothetical for me. but I was thinking about this use case from the start

14:43 gtrak: so, you grab the classpath, and I'm guessing you could mirror it in the local maven repo? peel off the right prefix?

14:44 that's assuming the project is running in lein with maven classpaths.

14:44 tpope: gtrak: I guess you could, but right now I just ignore the classpath from any repl that appears to be remote

14:45 gtrak: you'd be able to see the project's CLJ files, but nothing more in that case.

14:45 tpope: and another plugin optionally provides a fallback of `lein classpath` if there's not a local repl

14:46 gtrak: ah

14:47 tpope: I figure the common use case is just to have an implicit local connection from .nrepl-port, and then any remote connection will shadow that for most things

14:51 danno: (def counter (agent 0)) \n (send counter inc) \n (println @counter) hangs when run on the command line

14:51 Any ideas?

14:51 amalloy: your repl is broken, danno. that works fine

14:52 danno: amalloy: not using REPL

14:52 amalloy: oh. you're talking about running that from the actual unix shell?

14:53 $google clojure shutdown-agents stackoverflow

14:53 danno: yes. ;)

14:53 lazybot: [clojure - Restart agent thread-pool after calling ... - Stack Overflow] http://stackoverflow.com/questions/2944900/restart-agent-thread-pool-after-calling-shutdown-agents

14:53 amalloy: bah

14:53 ~shutdown-agents

14:53 clojurebot: Cool story bro.

14:53 justin_smith: ~agents

14:53 clojurebot: agents put it on a queue and call it George

14:53 amalloy: anyway, the point is thread pools are confusing

14:53 danno: ha.

14:54 still not using a REPL though.

14:54 amalloy: danno: agents have a thread pool, with threads that hang around for a couple minutes in case you have more work for them

14:54 technomancy: amalloy: wait, wouldn't thread pool shutdown just cause that to print zero?

14:54 danno: it prints 0, but hangs

14:54 amalloy: technomancy: no, the point is it's printing (either 0 or 1), and *then* hanging

14:54 he just didn't actually say that

14:54 technomancy: oh, well that's different then

14:54 danno: yeah, that's right

14:54 amalloy: i had to use my psychic powers :)

14:54 danno: haha

14:55 llasram: I love psychic debugging

14:55 justin_smith: cold reading is an art

14:55 danno: Ill try (shutdown-agents) even though I am not running on REPL

14:55 nice

14:55 thanks amalloy

14:55 amalloy: you need to shutdown agents *because* you're not using the repl

14:55 technomancy: llasram: "I sense ... deep pain. I sense... using def inside a function definition. Such suffering."

14:56 justinholguin: danno: FWIW, I ran that code with lein exec and it exited after printing

14:56 no (shutdown-agents)

14:56 amalloy: what's your *clojure-version*, danno? i don't recall having run into this problem in recent versions; maybe it's fixed?

14:56 danno: amalloy: ohhhhhhhh

14:57 amalloy: clojure-1.7.0-master-SNAPSHOT.jar

14:57 amalloy: well, that's recent all right

14:57 danno: I just fetch recent updates now and then from github and use that

14:57 amalloy: wow, running from source?

14:57 danno: amalloy: yes

14:58 amalloy: like, you can do that, but it sounds like a lot of work

14:58 danno: amalloy: Not too bad. mvn clean package and go

14:58 amalloy: sure, but why bother? lein is so much easier

14:58 justin_smith: clojure has some of the best dependency management in the programming world, so forgoing it is an interesting choice

14:59 danno: I hadn't gotten around to that yet, picked up language in January

14:59 justin_smith: Just my maturity with the language at this point

15:00 justin_smith: Just learning right now, nothing where I require dependencies etc.

15:00 justin_smith: fair enough, IME lein will make things easier, with very few exceptions

15:00 even if your only dep is clojure itself

15:00 amalloy: yeah, lein makes everything easier

15:00 danno: I am sure if I am doing a project with dependencies, etc. lein would be where I first go to.

15:00 technomancy: even without lein, not using a repl is pretty handicapping

15:01 justin_smith: danno: even with only clojure as a dep, lein simplifies things (ie. lein jar / lein uberjar / lein check / lein test / lein compile ...)

15:01 danno: justin_smith, amalloy, technomancy: Also this is my project: https://github.com/dhinojosa/language-matrix/tree/master/clojure

15:02 I am just using this as learning and creating small samples of 10 languages that I know, or are trying to learn

15:02 technomancy: but if you've only used the repl that ships with clojure I can see why you would think repls aren't worth bothering with =\

15:02 danno: technomancy: My interest is piqued.

15:02 technomancy: danno: part of the point of lisp is interactive programming

15:02 danno: I like REPLs. I found that Clojure's doesn't have tab completion

15:02 technomancy: a big part

15:03 danno: Am I wrong?

15:03 justin_smith: danno: lein repl has it, at least

15:03 technomancy: yeah, clojure's built-in repl is more of a proof-of-concept than something that people actually use

15:03 justin_smith: dunno about naked clojure repl

15:03 llasram: You can wrap it in rlwrap, but there's usually little need to

15:03 danno: oh, I get the lein thing then

15:03 technomancy: justin_smith: iirc the built-in one doesn't even have arrow support

15:03 amalloy: justin_smith: the naked repl has like nothing. for all features x, clojure.jar's repl does not include x

15:04 danno: part of its power is its repl

15:04 amalloy: technomancy: right you are

15:04 technomancy: it's pretty stone-age

15:04 llasram: amalloy: Can it read, evaluate, print, or loop?

15:04 justin_smith: lol

15:04 amalloy: llasram: allegedly. i never manage to type in a form correctly on the first try, and i can't use readline or arrow-key stuff to edit, so i just give up before i finish a form

15:04 danno: liasram: The basic REPL does that. My strength is with Scala and Java. Scala's REPL is pretty nice.

15:04 llasram: I'll agree it lacks literally all non-essential features of a REPL though :-)

15:05 danno: I was comparing the Clojure Basic with Scala's.

15:05 justin_smith: danno: also, ns-publics, clojure.repl/apropos, clojure.repl/doc and clojure.repl/source

15:05 llasram: amalloy: Haha. Good point.

15:05 justin_smith: are godsends

15:05 danno: But sounds like a better match would be with lein

15:05 I do love doc and source

15:05 that is fancy goods right there

15:06 amalloy: anyway, danno, neat project. now imagine if instead of a million little files with their own :main, it was one file you just load into your repl and type (for-example), eh?

15:06 you wouldn't have to keep tearing down and restarting the jvm and the clojure runtime

15:07 danno: amalloy: I will look into that. (for-example)

15:07 amalloy: Not sure if I will go with that, because this project will have equivalent C, C++, Java, Clojure, Scala, etc.

15:07 and all that is command line, and don't expect anyone who finds value in it, to load lein

15:08 amalloy: i look forward to reading the equivalent MacroExample.java

15:08 danno: but as someone who is interested in more of the language, I am interested in it for other projs.

15:08 thanks amalloy

15:10 I think by end of May I will have most of what I need to know about Clojure in this cranium of mine. Ha

15:10 justin_smith: amalloy: (throw (UnsupportedOperationException.)) <- just translate this to java

15:16 danno: So another question to all: You work on clojure full time for a living?

15:16 justin_smith: yes

15:16 rberdeen: danno: not yet

15:17 justin_smith: (well sometimes I have to mess with devops and stuff but technically I am a clojure programmer)

15:17 llasram: danno: Most-of-the-time. We have some mostly-legacy stuff in other languages, some devops, etc. But pretty much all new code in Clojure

15:17 danno: Very interesting, I bet tons of fun

15:18 justin_smith: I would definitely consider myself spoiled for other languages for the most part, at this point

15:19 danno: justin_smith: I would never consider a mutable preferred language anymore.

15:20 tbaldridge: +1 to that

15:20 justin_smith: agreed

15:20 gtrak: oiy.. yea, not sure what the next lang I'll learn will be, or when.

15:20 tbaldridge: If I had to pick a language other than clojure (and couldn't write my own), I'd probably pick F#

15:20 gtrak: elisp with reluctance..

15:20 justin_smith: (except those same special cases where I would use mutability in clojure: things with such great real time data processing needs that I truly need mutation).

15:20 tbaldridge: it's static typed, but the syntax is so minimal that it approaches lisps in simplicity

15:21 justin_smith: tbaldridge: how would you compare it to OCaml?

15:21 tbaldridge: justin_smith: I only know a minimal amount of OCaml, but F# is more OOP than OCaml.

15:22 technomancy: F# actually has concurrency, which is kinda great

15:22 gtrak: I've heard really good things about F#

15:22 justin_smith: that is nice

15:22 tbaldridge: justin_smith: it differs really only in interop syntax.

15:22 technomancy: I mean, depending on what you're doing

15:23 justin_smith: also CLR language means better lib options via interop I assume (or at least better / easier integration of libs)

15:24 I tried to make OCaml bindings once upon a time - made the mistake of picking a lib that was implicitly mp which made a bunch of "this should really be working" type bugs happen.

15:27 tbaldridge: justin_smith: yeah the interop story on the CLR is better if you have a static typed lang. Clojure on the CLR is...interesting due to the lack of type erasure.

15:29 amalloy: technomancy: is there a lein profile that's active only when i'm connected via jack-in?

15:29 (using swank still)

15:29 technomancy: amalloy: no

15:29 llasram: amalloy: !!!!

15:29 amalloy: llasram: i've tried nrepl/cider a few times. have not been impressed

15:29 technomancy: amalloy: you can change your command to lein with-profile +swank swank

15:29 justin_smith: he's trying to win a long-haired-yak competition

15:30 amalloy: ah, that makes sense. thanks

15:30 technomancy: np

15:30 llasram: amalloy: OOC what do you find is missing vs swank?

15:31 gtrak: amalloy: cider's getting a bunch of new features lately, we don't have a real release of it yet..

15:31 technomancy: gtrak: no problem just use melpa

15:31 llasram: ho ho ho

15:31 gtrak: gtrak: sure. :-)

15:31 technomancy: then instead of just having cider break, you can have everything break

15:31 gtrak: technomancy: sure :-)

15:32 didn't I mention I was learning elisp reluctantly?

15:32 the package story is a massive headache.

15:32 amalloy: llasram: mostly i found the behavior around exceptions pretty intolerable

15:32 technomancy: gtrak: it's really not that bad if you stick to stable releases

15:32 gtrak: it's the people who insist on "SNAPSHOT ALL THE THINGS" that cause the headaches

15:33 amalloy: i don't really remember the details; i always block it out of my mind, and re-discover what's wrong next time i reluctantly give it a try

15:33 llasram: amalloy: Huh. I have personally found no problems in that sphere

15:33 gtrak: technomancy: yea, I feel like I've got little control over the packages at this point, but I am running melpa, everything's not updated all the time, though.

15:33 technomancy: amalloy: you have to turn on "actually display stack traces" for whatever reason, which is dumb. but once you do that it's ok.

15:34 gtrak: technomancy: really I just want to see how many projects we can destroy by either making cider itself provide the needed functionality.

15:35 sorry, spurious either*

15:35 technomancy: gtrak: code deletion is the best thing

15:36 gtrak: every related or dependent project is still evaling clojure code.. either we need to define a real API for cider, or subsume/ignore them :-).

15:36 on the elisp-side..

15:37 technomancy: replacing slamhound.el with nrepl-discover.el was a pretty smooth process

15:37 gtrak: yea, I'd like to get there, I feel like I have a working understanding now.

15:54 whodidthis: how do i (distinct) a vector of maps by specific keys of the maps

16:03 dbasch: whodidthis: what’s the use case? why can’t you just merge all the maps?

16:03 whodidthis: the obvious way would be to loop over the maps, keep a set of the keys and ignore maps for keys you’ve seen

16:04 ivan: is there a better way to do (-> policy (assoc :path (if (:path policy) (i/as-path (:path policy))))) without extending as-path over nil?

16:06 bbloom: ivan: update-in and fnil ?

16:07 ivan: bbloom: thanks! I'll give that a try

16:10 fnil still calls f on the replacement value?

16:11 bbloom: ivan: yeah

16:11 (doc fnil)

16:11 clojurebot: "([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched."

16:11 ivan: anything built-in that doesn't?

16:12 bbloom: ivan: what about something like this...

16:13 ,(update-in {:x 1} [:x] #(and % (inc %)))

16:13 clojurebot: {:x 2}

16:13 bbloom: ,(update-in {:x 1} [:y] #(and % (inc %)))

16:13 clojurebot: {:y nil, :x 1}

16:13 ivan: bbloom: aha, thank you!

16:16 whodidthis: dbasch: ignoring duplicate File's in cljs by file name and size because user added file objects arent going to be equal for the same files. but yeah probably better to check if duplicate before conjing those bad boys

16:28 dbasch: whodidthis: do your maps have multiple, possibly overlapping keys?

16:31 whodidthis: im trying to find out duplicate-by-name-and-size from [{:name "a" :size 5 :file Obj} {:name "b" :size 6 :file Obj} {:name "a" :size 5 :file Obj} ...]

16:33 dbasch: whodidthis: you could do (group-by keys maps) and then pick the first of each group

16:33 rasmusto: whodidthis: (group-by #(select-keys % ...) maps) maybe

16:34 dbasch: whodidthis: yes, what rasmusto says if you want to restrict it to name and size

16:34 whodidthis: oh sweet, kind of like in sql

16:34 thank you

16:42 arrdem: Bronsa: gsoc accepted I assume?

16:46 Bronsa: arrdem: yes, you too?

16:55 tuft: what projects are you guys doing?

17:00 sdegutis: tuft: I'm working on work.

17:00 tuft: it's a web app mostly written in Datomic

17:01 tuft: with a lot of Compojure though too

17:34 kenrestivo: mystery function. needs a name, and, also, does this already exist somewhere else in another library maybe? https://www.refheap.com/78333

17:38 amalloy: kenrestivo: i think that's clojure.walk/walk

17:39 close to it, anyway

17:39 coventry: Only does one level, though.

17:39 amalloy: coventry: so does walk

17:39 coventry: Good point.

17:40 kenrestivo: hmm, i must have stolen the "outer"/"inner" terminology from walk

17:41 i'll play around with it and see if i could replace that with walk, thanks.

17:42 tho, what i was trying to accomplish was to not have outer be a #(assoc-in % [:x] y), but rather to take all those as & args as a convenience

17:50 tuft: sdegutis: cool -- i was referring to arrdem and Bronsa's gsoc projects, but nice to hear. =)

17:50 sdegutis: i'm doing a hobby project with datomic. no front-end yet

17:51 sdegutis: one of my favorite features so far is passing seqs of triples as the dbval during testing, and verifying properties of the transaction returned. so much better than loading fixtures into some ORM thing and checking for side-effects.

17:52 Bronsa: tuft I'll be working on porting the cljs analyzer to tools.analyzer & more work on tools.analyzer[.jvm]

17:53 sdegutis: Oh.

17:53 tuft: neat

17:53 tuft: I had not even thought of doing that. I am testing side-effects.

17:54 tuft: Have you written any blog post about this yet? It seems like a good alternative to how we do it now.

17:59 tuft: sdegutis: i should, there were gotchas and scant info involved

17:59 sdegutis: :)

17:59 tuft: I'm sure the mailing list would love to hear when you've written it.

18:03 tuft: Bronsa: cool. is this for static analysis of clojure code in clojure?

18:09 Bronsa: tuft: the AST can be used for static analysis, yes, but also as a backend for compilers (tools.emitter.jvm being one)

18:11 bbloom: Bronsa: s/backend/frontend ? middle end? IR?

18:11 justin_smith: just watch 20 custom readers all targetting that ast come out as soon as that is done

18:11 bbloom: :-P

18:12 hiredman: justin_smith: seems unlikely

18:12 Bronsa: bbloom: yeah definitely not backend. I always mix those.

18:13 bbloom: Bronsa: back vs front is all a perspective thing anyway. analyzer can be the backend from the perspective of somebody's parser :-)

18:17 tuft: Bronsa: moments later i'm coincidentally listening to dnolen mention you and explain more on cognicast #054 =)

18:17 gtrak: Bronsa: hopefully it's just as easy to support auto-complete/info with the new analyzer..

18:18 in a cljs repl

18:18 Bronsa: tuft: baader-meinhof hits again

18:19 gtrak: (also looking forward to when we get a clj-in-clj repl :-)

18:22 I hope cider-nrepl will support these in a unified way

18:30 rasmusto: is this bad? I want a side-effecty function to output something to /resources so I can put it into an uberjar

18:31 justin_smith: so a side effect you want specifically during jar build time?

18:32 rasmusto: justin_smith: yeah, that sounds right

18:32 justin_smith: you could add an injection to the :production profile in project.clj (or maybe there is a profile like "build")

18:33 hiredman: rasmusto: it is easy to screw that kind of thing up

18:33 justin_smith: definitely easy to screw up, yeah

18:33 hiredman: rasmusto: maybe look at https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md#hooks

18:33 rasmusto: a little more context: it's a bunch of edn files that are essentially a cache of some slurp+set calls

18:33 technomancy: rasmusto: can you write to target/classes?

18:34 that gets put on the classpath and included in jars and stuff

18:34 rasmusto: technomancy: I could. How is that different than resources + (resource "foo") ?

18:35 technomancy: rasmusto: it's already properly .gitignored, and it's easily exposed via the "clojure.compile.path" system property

18:35 plus lein clean will nuke it

18:36 keeping input paths segregated from output paths just seems like a good idea

18:36 rasmusto: when/how should I output to target/classes? Right now I have code in a (comment) that does it :p

18:37 technomancy: I don't really know what you're doing with it

18:40 arrdem: Bronsa: yep :D

18:40 Bronsa: dis gon b gud

18:40 Bronsa: arrdem: awesome!

18:41 arrdem: only question is how much of Clojure I'm allowed to optimize out :P

18:45 danlamanna: anyone help me out with a dependency not seeming to be on my classpath with lein run? https://gist.github.com/danlamanna/11159002

18:49 rasmusto: technomancy: when I run (System/getProperty "clojure.compile.path") in my uberjar it gives me nil, am I doing something wrong? (I know I'm going in circles a little bit)

18:50 justin_smith: danlamanna: ns forms already have their require clause quoted

18:50 so you should take out the '

18:50 also you probably want digest.core, or whatever ns digest defines

18:50 amalloy: if you have spare time, you should also murder the rascal who chose a single-segment namespace

18:50 justin_smith: no, i just checked, it's really digest

18:51 justin_smith: well that's quaint

18:51 amalloy: https://github.com/tebeka/clj-digest/blob/master/src/digest.clj

18:51 danlamanna: justin_smith: you were right, thanks :)

18:51 technomancy: rasmusto: no, that's normal. if you run outside lein you need to set that stuff up yourself.

18:52 justin_smith: danlamanna: "quote/digest__init.class " - that's how it parsed 'digest

18:52 rasmusto: technomancy: ok, that's what I thought. Since /resources seems like a bit of a hack, I'll just set up a common directory to store my "cached" edn files

18:52 justin_smith: of course there is no ns called quote/digest so it won't find it

18:53 danlamanna: justin_smith: makes sense

18:53 justin_smith: that gives me a terrible terrible idea to create a "quote" project, and fuck with people's heads by requiring it by using an extraneous '

18:55 amalloy: justin_smith: quote.lincoln defines a string containing the gettysburg address?

18:55 justin_smith: hah

18:55 arrdem: amalloy: haha

18:56 justin_smith: (inc amalloy)

18:56 lazybot: ⇒ 100

18:56 * arrdem stops himself from inviting fido in here

18:56 rasmusto: four__PLUS_7yearsago

18:56 arrdem: (inc rasmusto)

18:56 lazybot: ⇒ 9

18:56 justin_smith: ouch

18:56 (inc rasmusto)

18:56 lazybot: ⇒ 10

18:57 amalloy: oh...oh dear. that joke is too bad

18:57 rasmusto: bring on the decs

18:57 amalloy: i need to sit down

19:04 arrdem: ,(symbol "quote.quote/'")

19:04 clojurebot: quote.quote/'

19:05 arrdem: justin_smith: ^ get on this

19:06 justin_smith: arrdem: will do, lol

19:06 that is so evil

19:08 haha, I just got (require ''lincoln) to load the quote.lincoln ns - it feels so dirty

19:08 arrdem: (dec justin_smith) ;; you earned that

19:08 lazybot: ⇒ 33

19:09 arrdem: terrible terrible person

19:09 Bronsa: justin_smith: that's.. horrible

19:09 justin_smith: I know!

19:09 but it works

19:09 arrdem: I wish I didn't have homework so I could drown my horror at that require...

19:10 rasmusto: ,(macroexpand-1 (quote (quote lincoln)))

19:10 clojurebot: (quote lincoln)

19:10 * justin_smith now has to make (require ''lovecraft) work

19:10 justin_smith: of course that will be full of macros that alter atoms and def inside defn...

19:10 Bronsa: rasmusto: that works because of prefix lists in require

19:13 arrdem: justin_smith: should make extensive use of this... justin_smith: should make extensive use of this...

19:13 justin_smith: https://github.com/fredericksgary/qubits

19:14 justin_smith: hah

19:14 amalloy: justin_smith: i think ''lovecraft should contain (alter-var-root #'defmacro (constantly (fn [& args] `(quote ~(rand-nth '#{various lovecraftian horrors|)))))

19:14 justin_smith: ouch

19:14 amalloy: or something like it, anyawy

19:14 justin_smith: yeah

19:15 maybe ''necronomicon would be the better name for it

19:16 amalloy: or you could mutate one of the interned Number instances

19:17 really there are a lot of deep horrors you could put into a lovecraft library

19:18 justin_smith: indeed

19:19 stack traces generated using https://github.com/prismofeverything/zalgo

19:21 rasmusto: forgive me: z̷̼͖̰̜̣̗̝̞͚̹̪͛̂̚͟็็ạ̶̹͔็l̀̄͌̈̐ͫg̉̊̐͑ͮͦȏ̉̏̿̿ͩ̓ï̞̗͓̮̮͙̠͇̭͎͖̺͖̠̃̄̚็z̞̗͍̖̖̮͖̞̃͆̐͆͊̄̚็็็e͗ͣ̔ͣ

19:21 arrdem: justin_smith: what have you done...

19:21 amalloy: huh. clojurebot's sandbox allows you to actually do what i just said

19:21 ,5

19:21 clojurebot: 2

19:21 justin_smith: woah...

19:21 amalloy: i'll go put things back together now

19:22 * arrdem flees in terror

19:23 amalloy: uhhhhhh, i can't put it back. 5 is 2 now. even if you add 1 and 4 you get 2. so there's no longer a 5 to reset 5 to

19:23 hopefully clojurebot's regular sandbox-resetting takes care of that

19:23 rasmusto: ,(dec 5)

19:23 clojurebot: 1

19:23 arrdem: amalloy: what have you done...

19:23 rasmusto: seems to work

19:23 arrdem: ,(+ 3 5)

19:23 clojurebot: 2

19:23 justin_smith: rofl

19:23 ,(= 5 2)

19:23 clojurebot: true

19:23 justin_smith: ROFL

19:23 arrdem: I don't even have a gif for this level of wat...

19:24 justin_smith: (inc amalloy)

19:24 lazybot: ⇒ 101

19:24 rasmusto: ,(range 6)

19:24 clojurebot: #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>

19:24 arrdem: AHAHAHAHA

19:24 rasmusto: what

19:24 arrdem: (inc amalloy)

19:24 lazybot: ⇒ 102

19:24 justin_smith: lol

19:24 (take 10 (range 6))

19:24 ,(take 10 (range 6))

19:24 clojurebot: #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>

19:24 arrdem: amalloy: I want to see the source for this...

19:24 ,6

19:24 clojurebot: #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>

19:24 arrdem: WHAT THE hahaha

19:24 amalloy: oh, it's not hard. (let [field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field 5 2))

19:24 rasmusto: ,7 ;plz?

19:24 clojurebot: #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>

19:24 justin_smith: ,7

19:24 clojurebot: #<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>

19:25 amalloy: i think i broke all the numbers when i tried to put it back together

19:25 rasmusto: ah okay.

19:25 arrdem: wow.. that crowbar usage...

19:25 danlamanna: it seems if an nREPL command (in emacs) isn't responding, there's no way to just C-c C-c out of it, huh?

19:25 rasmusto: C-c C-b iirc

19:25 justin_smith: clearly the 'adams ns will turn every number up to N into 42

19:26 danlamanna: sometimes it takes a while, but for me C-c C-c works

19:26 amalloy: you can try C-g too, in case it's client-side emacs code that's not responding

19:27 btcNeverSleeps: re all... I read a comment here previously about Emacs and stack traces "inside" cider: <technomancy> amalloy: you have to turn on "actually display stack traces" for whatever reason, which is dumb. but once you do that it's ok.

19:27 Can someone tell me how you turn on "actually display stack traces"?

19:29 amalloy: hiredman: is clojurebot's auto-reload going to reload java.lang as well, or just clojurey bits?

19:30 Xe: How do you import functions from another clojure file?

19:30 Say I have main.clj and foo.clj

19:30 gtrak: Xe: namespaces

19:30 technomancy: btcNeverSleeps: M-x apropos-variable cider.*stacktrace

19:31 hiredman: amalloy: that is an interesting question

19:31 Xe: gtrak: How do I use it once I have a namespace?

19:31 gtrak: Xe: the (ns ..) form and (require ..)

19:31 Xe: so it would be

19:31 gtrak: http://clojuredocs.org/clojure_core/1.2.0/clojure.core/ns

19:31 hiredman: instead of trying to answer it I killed the evaluator service, and it got restarted, so *shrug*

19:32 arrdem: iiinteresting. tbaldridge, can I get a DL on the other accepted Lean Clojure project? we seem to be going for the same thing, unless his is atop the existing Java compiler.

19:32 gtrak: Xe: here it uses :require [clojure.string :as str] http://clojuredocs.org/clojure_core/1.2.0/clojure.core/ns#example_527

19:36 dbasch: gtrak: as str… pretty unfortunate example

19:36 gtrak: dbasch: still works :-)

19:36 (str ) is str, str/ is the ns

19:36 arrdem: you didn't really want clojure.core/str anyway :P

19:36 gtrak: doesn't it?

19:36 justin_smith: :as [str] will not make str unusable

19:37 Xe: gtrak: what am I doing wrong? https://gist.github.com/2309529ee383916f2e7b

19:37 arrdem: ,(require '[clojure.string :as str])

19:37 clojurebot: nil

19:37 arrdem: ,(str 1 2 3)

19:37 clojurebot: "123"

19:37 gtrak: Xe: I can't tell what that's supposed to do.

19:37 arrdem: ,(str/capitalize "a")

19:37 clojurebot: "A"

19:37 rasmusto: ,(str 5)

19:37 clojurebot: "5"

19:37 Xe: gtrak: import the functions in constellation.atheme

19:37 gtrak: your require looks fine but weird.

19:37 Xe: well it doesn't work

19:38 gtrak: Xe: ah, you'll want to alias the ns, that's what :as is for.

19:38 justin_smith: Xe: that is not how you do unqualified import

19:38 gtrak: :refer :all will import all the symbols, if that's what you need.

19:38 justin_smith: also unqualified import is bad

19:38 Xe: justin_smith: then how am I supposed to do it?

19:38 gtrak: [constellation.atheme :refer :all]

19:38 justin_smith: which is bad

19:38 :P

19:39 btcNeverSleeps: technomancy: thanks

19:39 gtrak: hey, I'm just handing out guns..

19:39 footguns

19:39 justin_smith: heh

19:39 gtrak: I need to make a lib called that..

19:40 justin_smith: it makes me imagine a foot with arms coming out (said arms having oversized biceps)

19:40 gtrak: footgun - a utility library

19:40 arrdem: gtrak: you already have knr what more do you need

19:40 gtrak: yea, exactly.

19:40 arrdem: gtrak: knr is footgun

19:41 gtrak: thinking of which... why the hell did you build knr

19:41 gtrak: I was satisfied with building it once I successfully crashed the JVM. but ztellman's vertigo is a completion of the idea.

19:41 arrdem: gtrak: I's cute and I enjoyed reading it... but what the hell

19:41 Xe: gtrak: I see now, thanks

19:41 gtrak: arrdem: he also said the unsafe isn't much faster than bytebuffers..

19:42 arrdem: oooh boy

19:42 part of me wants to start using both of these libraries

19:42 and the rest of me likes not writing C

19:42 gtrak: knr doesn't actually work... I'm making a note on the githubs :-)

19:42 it's half-completed

19:43 justin_smith: hey, half-complete knr, complete footgun, who would know the difference except for a few symbols and filenames?

19:43 amalloy: gtrak: 1/2 completed is the same as 1/5 completed, actually

19:43 arrdem: vertigo is evil. I love it...

19:43 amalloy: quiet you

19:43 justin_smith: lol

19:43 jwm: is it safe to do a for on a nil object?

19:43 justin_smith: ,(for [a nil] a)

19:43 clojurebot: ()

19:44 gtrak: amalloy: I think I'm missing something subtle there :-)

19:44 or is it 80/20?

19:44 arrdem: also gtrak. meajure is now a thing. you're entirely to blame for the name.

19:44 gtrak: hehe

19:44 amalloy: gtrak: no, i was referring to my recent clojurebot hack

19:44 justin_smith: gtrak: search up for ,(= 5 2)

19:44 arrdem: ,(= 5 2)

19:44 clojurebot: false

19:44 arrdem: good. clojurebot is no longer horked

19:44 rasmusto: ,(range 6)

19:44 clojurebot: (0 1 2 3 4 ...)

19:44 rasmusto: where's 5????

19:45 TEttinger: rasmusto: ##(range 6)

19:45 lazybot: ⇒ (0 1 2 3 4 5)

19:45 justin_smith: ,5

19:45 clojurebot: 5

19:45 rasmusto: :)

19:45 TEttinger: one of the bots trims output

19:45 justin_smith: we were just kind of worried about 5 and hoping 5 was OK

19:45 rasmusto: TEttinger: gotcha, was making a reference to ,(= (dec 5) 1) earlier

19:45 TEttinger: heh wha

19:46 justin_smith: probably the best clojure wat I have seen so far

19:47 amalloy: i figured out how i broke clojurebot the second time

19:47 justinholguin: ,(= (dec 5) 1)

19:47 clojurebot: false

19:47 justinholguin: phew

19:47 amalloy: i was trying to set 5 back to 5, but instead i set 2 to 5. so looking up the third item in an array caused you to look up the sixth item instead. thus all the ArrayIndexOutOfBoundsException problems

19:47 gtrak: how'd you do that in the first place? I didn't see it in the scroll-up

19:47 TEttinger: ,(def 5 4)

19:47 clojurebot: #<CompilerException java.lang.RuntimeException: First argument to def must be a Symbol, compiling:(NO_SOURCE_PATH:0:0)>

19:48 justin_smith: another good name for an intentionaly messed up lib would be angkor (named for the world's biggest Wat)

19:48 amalloy: gtrak: it's not hard. (let [field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field 5 2))

19:48 justin_smith: gtrak: amalloy pasted it, by setting some properties of Long I think

19:48 justinholguin: (inc justin_smith)

19:48 lazybot: ⇒ 34

19:48 justin_smith: oh, there it is again

19:48 gtrak: ah, ye old integer cache

19:49 justin_smith: probably will call for some new sandbox rules

19:49 * nDuff has a core.async mix, and is getting apparently nondeterministic behavior around whether the last item added to it is delivered, though the put to the mix *should* be happening before any associated close!, and all involved channels were constructed unbuffered

19:49 TEttinger: (let [field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field (rand-int 100) 101))

19:49 ,(let [field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field (rand-int 100) 101))

19:49 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Can not set final long field java.lang.Long.value to java.lang.Integer>

19:49 TEttinger: aw

19:49 rasmusto: justin_smith: glad someone else shares my taste for puns

19:49 amalloy: iit turns out you have to do a bit more work to set it back

19:50 (let [five (long (int (+ (int 1) (int 4)))), field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field five (int (+ (int 1) (int 4))))) ;; actually worked to recover my repl

19:50 rasmusto: amalloy: is this idiomatic code?

19:50 er, does it at least show how to use java interop properly?

19:51 TEttinger: there's nothing proper here

19:51 arrdem: rasmusto: do you see that crowbar? do you see it?

19:51 rasmusto: that's almost as [good|bad] as the reader macros with crowbars hack

19:51 amalloy: sure, just like carrying a chainsaw with you at all times is the idiomatic way to get into doors you really shouldn't be getting into

19:51 gtrak: arrdem: I also take credit for the name 'reagent'

19:52 rasmusto: hrm, trying to grok the long/int thing

19:52 hiredman: http://bldgblog.blogspot.com/2010/01/nakatomi-space.html

19:55 TEttinger: ,(count (range 100))

19:55 clojurebot: 94

19:55 arrdem: hiredman: interesting...

19:56 rasmusto: ,(apply str (range 100))

19:56 clojurebot: "0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899"

19:56 TEttinger: aww someone fixed it

19:56 jwm: hehe took my 8 hours to write this function today in a functional manner

19:56 I so suck

19:56 justin_smith: ,(count (range 100))

19:56 clojurebot: 100

19:56 jwm: :)

19:56 justin_smith: jwm: maybe you are learning

19:57 jwm: I am

19:57 I only used one for in it

19:57 got rid of ifs, another for

19:57 rasmusto: ifs and for are functional

19:57 amalloy: jwm: 'for is great

19:58 jwm: map is nicer I think

19:58 gtrak: for is way better

19:58 arrdem: for does really badly in -> tho...

19:58 jwm: I still use for but I got rid of like 7-8 lines of code

19:58 amalloy: it's context-dependent

19:58 justinholguin: Yeah, in the functional hierarchy I think if is fairly low

19:59 jwm: thank god let takes multiple bindings :)

19:59 rasmusto: jwm: for is cool when you need to unroll nesting

19:59 justin_smith: and also the _ idiom, if you need to sneak a side effect in

19:59 justinholguin: 'for is great if you can't replace it with map or filter

20:00 amalloy: arrdem: i don't find that piling together great chains of ->> or -> makes anybody's code more readable. the fact that for isn't easy to fit into such a pipeline is perhaps a reminder that those pipelines aren't an end in themselves

20:00 jwm: I was wondering what _ did

20:00 rasmusto: jwm: ##(let [_ 1] (inc _))

20:00 lazybot: ⇒ 2

20:00 rasmusto: its just a normal symbol

20:00 jwm: ahh figured it was

20:01 I used it for underscore in nodejs :)

20:01 arrdem: _ is just a symbol used for "I don't care about this value"

20:01 jwm: until I realized one of the functions was blasted by an internal usage in nodejs so I renamed it __

20:01 arrdem: I've seen (let [[a _ b _ c & rest] seq] ..) before..

20:01 rasmusto: ,(let [$_ 1] (inc $_))

20:01 clojurebot: 2

20:01 amalloy: speaking of which, i was surprised to discover that haskell actually doesn't treat _ as an ordinary symbol. it's only valid in a pattern-matching context, not a value context, so this fails: let _ = 1 in _

20:02 arrdem: weird.

20:02 jwm: :v (triml (apply str (map (partial second) (filter #(= (first %) "Vehicle Name") parted))))

20:02 you guys think you could make that shorter

20:02 amalloy: (partial second) => second

20:03 jwm: yeah that would be one thing :)

20:03 no, doesnt work

20:03 hiredman: (for [[k v] parted :when (= k "Vehicle Name"))] (str v))

20:03 amalloy: yeah. that

20:04 jwm: nice

20:04 amalloy: see how nice 'for is?

20:04 justin_smith: #(= (first %) "Vehicle Name") is (fn [[n]] (= n "Vehicle Name"))

20:04 the later is a little nicer I think

20:04 amalloy: justin_smith: i don't like the second one much at all

20:04 the first is fine, or i'd write (comp #{"Vehicle Name"} first)

20:04 jwm: I just didnt want to use regex

20:04 probably could do my entire program in one regex statement

20:07 amalloy: there are two things i don't like about (fn [[n]] (= n "Vehicle Name")). (1) it implies that there's only one item in the vector you're destructuring. obviously it doesn't *prove* that, but reading that code that would be my first guess. (2) it makes you pick a name for the first item in the tuple. that's fine, except that you picked a useless name like n, which suggests you'd rather not name it

20:08 justin_smith: fair points

20:09 jwm: well the top of the code is 4 lines

20:09 (for [msg (mailspool :reports)]

20:09 (when (.startsWith (msg :subject) "MCO Alert")

20:10 (let [content (string/split-lines (.getContent (msg :message)))

20:10 parted (map #(split % #":") content)]

20:10 rasmusto: ~refheap

20:10 clojurebot: https://www.refheap.com/

20:10 jwm: hehe, sorry

20:10 rasmusto: <3

20:10 jwm: I figured 4 lines was below the barrier for that :)

20:11 rasmusto: no, that's fine, just figured it'd be easier to paste the whole thing (and give readers some context or sample output)

20:11 justin_smith: it's polite to at least attempt to make it a one liner - we know how to make a four liner out of that if we are interested

20:12 also, you could probably turn the when block into a :when in the for bindings?

20:14 jwm: well, I am just doing this for chatting purposes.. I know it'll probably be another few months before I get decent at clojure

20:14 probably a stupid idea to switch languages for a 2 week deadline on a big project

20:14 haha

20:15 you guys like the idea of using yyyymmdd dates for keys?

20:15 its temporary storage anyway

20:16 justin_smith: ,(java.util.Date.) why not use this format?

20:16 clojurebot: #inst "2014-04-22T00:12:43.774-00:00"

20:16 justin_smith: it's what clojure already uses after all

20:20 jwm: yyyymmdd is the smallest/largest you can store a unique date in an int

20:20 without time of course

20:20 rasmusto: famous last words

20:20 jwm: its just habit

20:20 dbasch: I know all of you are desperate to base58encode / decode Bitcoin stuff. https://github.com/dbasch/base58/

20:22 n_b: Why is a star required before the exception identifier in the following code (where the future throws an exception)? I've never seen it in Clojure code before and it doesn't seem to be mentioned in the Java interop or reader sections: http://stackoverflow.com/questions/9325492/why-does-clojure-wrap-checked-exceptions-with-unchecked-exceptions

20:22 Oh, never mind. I see now. *e at the REPL refers to the last exception, right?

20:22 justin_smith: yeah, * is not special, it is just part of certain names by convention

20:23 see also *1, *2, etc.

20:23 ,*1

20:23 clojurebot: #<Unbound Unbound: #'clojure.core/*1>

20:23 justin_smith: erm...

20:23 dbasch: ,*e

20:23 clojurebot: #<Unbound Unbound: #'clojure.core/*e>

20:23 dbasch: anyway, type *e into your repl

20:23 justin_smith: ,*1

20:23 clojurebot: #<Unbound Unbound: #'clojure.core/*1>

20:23 justin_smith: yeah

20:24 coventry: ,(throw (Exception. "Does this work?"))

20:24 clojurebot: #<Exception java.lang.Exception: Does this work?>

20:24 coventry: ,*e

20:24 clojurebot: #<Unbound Unbound: #'clojure.core/*e>

20:24 justin_smith: I think clojurebot does not handle *{e,1,2,...} normally

20:24 ,(pst)

20:24 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to java.lang.Throwable>

20:25 justin_smith: ,(pst)

20:25 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to java.lang.Throwable>

20:25 n_b: Yup, had a true facepalm moment when I clicked through to make sure it was the right link and realised it was all done at the REPL

20:26 *after* I had hit enter of course – I suppose there's an adage on how asking the question to yourself can avoid you bothering IRC floating around bash.org somewhere

20:26 justin_smith: see also rubber duck debugging

20:27 http://en.wikipedia.org/wiki/Rubber_duck_debugging

20:28 amalloy: justin_smith: well, he handles them semi-normally. it's just that those things are set! thread-locally, and he evaluates in a fresh dynamic context each time, i think

20:28 justin_smith: ahh

20:28 amalloy: unlike in a repl, where you do everything inside the same top-level binding form

20:29 justin_smith: ,(do 22 *1)

20:29 clojurebot: #<Unbound Unbound: #'clojure.core/*1>

20:29 justin_smith: oh that wouldn't work anyway, never mind

20:29 amalloy: ,(do (set! *1 22) *1)

20:29 clojurebot: #<IllegalStateException java.lang.IllegalStateException: Can't change/establish root binding of: *1 with set>

20:30 amalloy: oh, he doesn't even bind it at all. that must be something clojure.repl does

20:30 justin_smith: in my repl: user> `*1 => clojure.core/*1

20:30 ,`*1 actually

20:30 clojurebot: clojure.core/*1

20:31 amalloy: uh huh...

20:31 justin_smith: hmm

20:31 amalloy: i mean, those are indeed defined in clojure.core

20:31 danlamanna: is it common to filter based on a list of functions? i.e. i have a list of items, they need to return true for every function in a list to remain in the list of items

20:31 amalloy: but the code for setting them lives in clojure.main

20:32 (filter (every-pred f1 f2 f3) xs)

20:32 justin_smith: (doc every-pred) danlamanna

20:32 clojurebot: "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns true if all of its composing predicates return a logical true value against all of its arguments, else it returns false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical false result against the original predicates."

20:32 justin_smith: ,(doc every-pred) danlamanna

20:32 clojurebot: "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns true if all of its composing predicates return a logical true value against all of its arguments, else it returns false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical false result against the original predicates."

20:32 justin_smith: oops

20:32 amalloy: hope you brought your galoshes, cause it's flooding in here!

20:33 thank you folks, the puns will be here all week. no need to applaud

20:40 devn: I wonder if something like claypoole could be brought into clojure.core at some point.

20:43 amalloy: i can't imagine that making it into clojure.core

20:44 a contrib library is more realistic, although i don't personally see the value it brings

20:45 devn: it brings value to pmap

20:45 and has an unordered pmap

20:46 pmap without control over threadpool size makes it less than useful in many of the situations people first set out to use it

20:47 nDuff: whew!

20:47 * nDuff has a reproducer for his unexpected core.async behavior; question now is where to post it.

20:48 jwm: watch is pretty cool

20:48 justin_smith: jwm: like the unix command, or add-watch?

20:48 coventry: nduff: What happens?

20:51 amalloy: devn: for sure, pmap is pretty useless. but i don't think the answer is a version of pmap with purportedly-better defaults, it's to understand what's going on

20:51 nDuff: coventry, a race condition wherein the last element fed into a channel going through a mix can be lost when the function doing the writes, on exit, calls close! on the mix's output channel --- which surprises me since all channels involved are unbuffered, so I'd expect the writes to block.

20:52 Ohh. Now that I'm explaining it, I see what's going on...

20:52 justin_smith: (inc rubberduck)

20:52 lazybot: ⇒ 1

20:53 nDuff: ...there's actually some computation going on in the pipeline between input channel and the mix, and that's where the relevant behavior is coming from.

20:53 ...question now is how to fix it, while still closing my output channel on completion.

20:54 If a mix could be configured to close its output channel after all input channels were unmixed, that would solve the problem nicely. :)

20:57 (hmm; strikes me as a reasonably straightforward patch...)

21:00 haole: how do I change Clojure's classpath? in my environment it seems to be ignoring the -cp argument passed to Java

21:00 I've asked it to print the classpath with the following snippet: (println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))

21:00 gfredericks: haole: how are you starting clojure?

21:01 haole: but I get only a single dir there, which is clojure's .jar dir

21:01 gfredericks: java -cp /my/classpath/dir -jar clojure.jar <myprog.clj>

21:01 gfredericks: haole: I think -jar precludes -cp

21:01 amalloy: gfredericks: right

21:01 gfredericks: try java -cp /my/classpath/dir:clojure.jar clojure.main <myprog.clj>

21:02 amalloy: haole: lein is way better at starting clojure than you are, or i am. it's easier, even for projects that don't need exciting dependencies managed

21:02 jwm: justin_smith: add-watch

21:02 I added a watch to my main ref a few days ago

21:02 still running strong :)

21:02 gfredericks: clojurebot: leiningen is better at starting clojure than amalloy is

21:02 clojurebot: Ok.

21:03 haole: amalloy: lein seems nice indeed but I'll have to collaborate with vanilla Java devs so I'm starting with Maven

21:03 will probably migrate to lein as soon as I get all the pieces together

21:03 amalloy: well, note that lein cooperates with maven. it fetches deps from ordinary maven repos, and so on

21:03 gfredericks: I support haole's desire to know wtf is going on

21:04 haole: gfredericks: heh yeah

21:04 justin_smith: and creates artifacts maven can use and find etc.

21:04 amalloy: clojurebot: amalloy |can| probably pass the turing test

21:04 haole: gfredericks: I've tried the following command without success: java -cp "/home/user/.m2/repository:/home/user/sources/clojure:clojure.jar" clojure.main tutorial.clj

21:04 clojurebot: c'est bon!

21:04 haole: I it complains that it can't find clojure.main

21:04 amalloy: haole: putting .m2/repo in your classpath isn't going to help - you need individual jars on the path

21:05 haole: ouch

21:05 amalloy: give the full path for clojure.jar, and you'll find it

21:05 haole: yeah, it worked now... I guess this is one of the reasons lein exists

21:07 maven is pretty nice too! I've been able to put a lot of really dumb programmers to help me with some project in like 5 minutes lol

21:07 with a private repo and easy IDE integration

21:08 gfredericks: I don't know if I've ever had the thought "I could get this project done in time if only I had a lot of really dumb programmers"

21:08 technomancy: gfredericks: maybe it's time to try a new tactic

21:08 justin_smith: gfredericks: spoken like someone with a limited supply of monkeys

21:09 coventry: haole: Curious what sort of application you're developing.

21:10 haole: gfredericks: the idea is to get them to not be so dumb in the future... maybe dumb is a strong word... I meant beginners :)

21:10 coventry: artificial intelligence

21:10 hence lisp :)

21:10 amalloy: justin_smith: i read a story a little while ago about someone who actually gave typewriters to a bunch of monkeys

21:10 coventry: hilarious!

21:11 gfredericks: haole: very good; I'm a big user of dysphemisms myself

21:11 justin_smith: amalloy: that actually sounds interesting, I am sure it at least led to some good photos

21:11 gfredericks: amalloy: was this some popular science gimmick?

21:11 amalloy: mostly they got four pages of "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", and then a lot of monkey urine, followed by smashed typewriters

21:12 gfredericks: I wonder if the most likely monkey-shakespeare scenario involves the keys accidentally getting pressed while the monkey smashes the typewriter

21:12 amalloy: http://www.theguardian.com/uk/2003/may/09/science.arts

21:12 bbloom: amalloy: 6 monkeys is a long long way away from infinite

21:13 amalloy: what did they expect?

21:13 amalloy: bbloom: well, given an infinite amount of time 6 is fine

21:14 gfredericks: http://bottledchicken.blogspot.com/2008/07/scientific-discoveries.html

21:14 amalloy: gfredericks: wait what is the deal with the links on that page?

21:15 is this some weird joke?

21:15 coventry: haole: Are your collaborators are basically entering a lot of domain-specific knowledge, or something like that?

21:15 gfredericks: amalloy: this was me six years ago

21:15 amalloy: so...yes?

21:16 amalloy: humor is ever inexplicable

21:16 gfredericks: amalloy: I'd forgotten all about the links; mostly I just remember "The MacBeth Exception" being rather catchy

21:24 amalloy: it's always exciting for me when i forget that `cat *.csv > combined.csv` doesn't do what i want

21:25 dbasch: amalloy: what did you expect?

21:26 amalloy: dbasch: to concat together the N csv files currently in a directory together

21:27 bbloom: headers get in the way? :-/

21:27 ravals: Hello - I’m having trouble using clojure.contrib/mock. I’m trying to mock out a function call use expect, line 11 here: https://gist.github.com/sidraval/11162258 — I’m getting a “Can't dynamically bind non-dynamic var: gol-clojure.core/sum-excluding-middle” error when I run lein test. Would love some help :)

21:27 amalloy: bbloom: no, try it and see! this command, run in a directory with 1 or more nonempty CSV files, will consume all available disk

21:28 i had actually written `(for f in *.csv; do tail -n+2 $f; done) > combined.csv`, because i'm clever and thought about headers already

21:28 bbloom: amalloy: you're saying the cat resolves the * after the > creates it?

21:28 amalloy: i'm skeptical....

21:28 amalloy: maybe the simpler version with cat doesn't break. it does do something weird, as i recall

21:29 danlamanna: can i inspect the result of a function that returns a function? by inspect i mean "view source"

21:29 amalloy: but if you use this subshell/for thing, you definitely cat a file into itself

21:29 bbloom: amalloy: yeah that's b/c the pipe is evaluated before the subshell call

21:29 it's not an issue w/o a subshell

21:29 amalloy: yeah

21:30 i take it back, everyone, unix is still smarter than me

21:31 bbloom: amalloy: why did you do the subshell thing at all?

21:31 amalloy: bbloom: what if you create a file foo.txt containing foo, and then run `cat foo.txt>foo.txt"? on linux that complains, but i vaguely recall that maybe bsd/osx let you do it?

21:31 coventry: danlamanna: Not really. E.g., if you want to know exactly what (partial myfn) is doing, you have to go look at the source for partial and piece it together from that.

21:31 bbloom: why not just put the > on the tail line?

21:31 use >>

21:32 amalloy: i get "file exists" complaint

21:32 dbasch: just do (for f in *.csv; do tail -n+2 $f; done) > foo ; mv foo combined.csv

21:32 bbloom: but that's a shell config if i recall

21:32 noclobber

21:32 amalloy: bbloom: >> would have been fine, but it felt more natural to build one stream with all the output rather than N streams with some of it

21:33 still thinking functionally, even in the shell

21:33 bbloom: amalloy: well that's your mistake right there

21:33 you expected your shell to be natural

21:33 tisk tisk

21:36 dbasch: I must be the only person working on cryptocurrency stuff in Clojure, there’s almost no bitcoin code out there

21:36 coventry: There was someone talking about it here a few months ago. I think they wanted to make a BTC client.

21:38 dobry-den.

21:39 dbasch: found it: http://clojure-log.n01se.net/date/2013-11-08.html

21:41 arrdem: dbasch: why do anything in Clojure when you can just use bitcoin-rpc

21:41 dbasch: or dogecoin rpc, or shitcoin rpc

21:41 dbasch: arrdem: I built my site/app in Clojure

21:42 arrdem: the actual communication with the daemon was the trivial part, building the rest of the application is the work

21:42 arrdem: dbasch: I hear you there..

21:42 dbasch: arrdem: here it’s what I have so far https://cointipping.com

21:49 danlamanna: trying to write a function which returns a function to be passed to filter, produces 0 results though, perhaps i'm doing it wrong? https://gist.github.com/11162744

21:50 bbloom: ,(= "-" \-)

21:50 clojurebot: false

21:50 bbloom: ,(class "-")

21:50 clojurebot: java.lang.String

21:50 bbloom: ,(class \-)

21:50 clojurebot: java.lang.Character

21:50 bbloom: danlamanna: ^^

21:51 danlamanna: also: ##(doc int)

21:51 lazybot: ⇒ "([x]); Coerce to int"

21:51 bbloom: danlamanna: and ##(doc alength)

21:51 lazybot: ⇒ "([array]); Returns the length of the Java array. Works on arrays of all types."

21:52 danlamanna: bbloom: i see where i messed up with = and int, where would alength come into play?

21:52 bbloom: danlamanna: instead of .length

21:52 danlamanna: bbloom: oh .length is java io file .length

21:52 bbloom: as in, the length of the File object in bytes

21:53 bbloom: ,(map #(get {\- <, \+ >} (first %) =) ["+1 "2" "-3"])

21:53 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading string>

21:54 bbloom: ,(map #(get {\- <, \+ >} (first %) =) ["+1" "2" "-3"])

21:54 clojurebot: (#<core$_GT_ clojure.core$_GT_@54919e> #<core$_EQ_ clojure.core$_EQ_@84fa6a> #<core$_LT_ clojure.core$_LT_@1abb81e>)

21:54 bbloom: danlamanna: you can avoid repeated the majority of the code by doing something like:

21:55 ,(defn size-filter [size-str] (let [cmp (get {\- <, \+ >} (first size-str) =)] (fn [f (cmp (alength f) (int (rest size-str)))))

21:55 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

21:55 bbloom: ,(defn size-filter [size-str] (let [cmp (get {\- <, \+ >} (first size-str) =)] (fn [f (cmp (alength f) (int (rest size-str))))

21:55 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

21:55 * bbloom always fails at coding in irc

21:55 bbloom: but you get the idea

21:55 ,(Integer/parseInt "123")

21:56 clojurebot: 123

21:56 bbloom: ,(Integer/parseInt "+123")

21:56 clojurebot: #<NumberFormatException java.lang.NumberFormatException: For input string: "+123">

21:56 bbloom: whoa weird, that works locally

21:56 ,(Integer/parseInt "-123")

21:56 clojurebot: -123

21:56 bbloom: ,(Integer/parseInt "+123")

21:56 clojurebot: #<NumberFormatException java.lang.NumberFormatException: For input string: "+123">

21:58 TEttinger: clojure's number parser has mo' powah ##(print 36rZAMBONI)

21:58 lazybot: ⇒ 76829540238nil

21:59 bbloom: wat

22:00 i guess i shouldn't be surprised that clojure's reader is too permissive

22:01 arrdem: http://i3.kym-cdn.com/photos/images/newsfeed/000/615/442/089.png

22:02 beamso: angry doge

22:04 nightfly: Searching for SDL on clojars gives nothing, are there really no useful SDL/OpenGL wrappers?

22:05 TEttinger: bbloom, it is useful for stuff like ##(print 2r1111)

22:05 lazybot: ⇒ 15nil

22:05 TEttinger: nightfly, sure. take a look at play-clj if you're doing idiomatic clojure game dev

22:05 bbloom: TEttinger: oh yeah, duh. i misread that as the RADIX was zamboni

22:05 heh

22:06 nightfly: LWJGL is mostly static methods, so it's pretty straightforward to use from clojure directly

22:06 TEttinger: indeed, play-clj I think is a nice wrapper around the java bits of LWJGL

22:07 nightfly: TEttinger bbloom awesome! ty

22:07 TEttinger: err I was mistaken

22:08 it's a wrapper around libgdx, which wraps lwjgl

22:08 so many acronyms

22:08 bbloom: so many wrappers

22:09 TEttinger: which wraps OpenGL yes

22:09 but play-clj is all well-documented pretty much

22:09 should get better now that libgdx is stable at 1.0

22:10 also, nightfly: #lispgames has some good tips I bet

22:21 jwm: (mailspool :reports first read-message :body second :body slurp pprint)

22:21 I love macros

22:21 hehe

22:22 Pupnik: there is also this handy play-clj video https://www.youtube.com/watch?v=9ilUe7Re-RA

22:36 zspencer: Is there an "opposite" of get-in

22:36 I.e. (foo :key :key :key map)

22:37 arrdem: wat?

22:37 zspencer: clarify input and output please

22:37 zspencer: I'm doing (get-in map :key-a :key-b) to get the nested hash-maps key-b

22:37 I want something that reverses the order of inputs

22:38 ,(get-in { :foo { :bar 5 } :foo :bar)

22:38 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

22:38 zspencer: ,(get-in { :foo { :bar 5 } } :foo :bar)

22:38 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword>

22:38 zspencer: ,(get-in { :foo { :bar 5 } } [:foo :bar])

22:38 clojurebot: 5

22:38 zspencer: sorry my syntax is horrible

22:38 I want ,(get-from [:foo :bar] { :foo { :bar 5 } })

22:39 arrdem: why....? -> is for solving that problem

22:39 or as->

22:39 zspencer: more for readability than anything

22:39 It's for a test where I'm ensuring that this and only this attribute has value x

22:39 arrdem: ,(defn rget-in [ks m] (get-in m ks))

22:39 clojurebot: #'sandbox/rget-in

22:39 arrdem: ~next

22:40 still ignored by bots. right.

22:40 zspencer: so nothing built in for reversing arguments?

22:40 arrdem: nope.

22:40 zspencer: k

22:40 clojure is wide as hell. So many things I don't know exist.

22:42 (inc arrdem)

22:42 lazybot: ⇒ 24

23:13 leif-p: Hi. Any Storm users around?

23:16 beppu: https://github.com/apache/incubator-storm ?

23:17 fowlslegs: What is the easiest modification I can make to https://github.com/weavejester/crypto-random/blob/master/src/crypto/random.clj if I want to generate 512-bit strings?

23:17 arrdem: ,(/ 512 8)

23:17 clojurebot: 64

23:18 arrdem: fowlslegs: just kick out 64 random bytes

23:18 fowlslegs: no library hacking required

23:20 fowlslegs: arrdem: I guess I meant to ask how I can get that into a binary string.

23:22 leif-p: beppu: yes

23:23 dbasch: fowlslegs: what do you mean by a 512-bit string?

23:25 fowlslegs: dbasch: I'm not familiar with working with binary strings/ byte arrays. I'm essentially trying to generate 512 random bits, which I want to split into 16 32-bit words.

23:26 arrdem: okay... so just generate 16 random ints from the getgo

23:26 dbasch: fowlslegs: from that library, just do (bytes 32)

23:27 fowlslegs: The only function I found was Integer/toBinaryString and that produces variable length results instead of consistently 8-bit strings

23:27 dbasch: fowlslegs: that’s 512 random bits

23:27 btw, do you need them to be cryptographically strong?

23:30 fowlslegs: dbasch: Yes.

23:30 dbasch: fowlslegs: (partition 4 (crypto.random/bytes 32))

23:32 fowlslegs: although, given that you’re not familiar with binary strings and need cryptographically strong bits I have to ask

23:32 what are you really trying to do?

23:32 arrdem: dbasch: openssl implementation

23:32 * arrdem ducks for cover

23:33 fowlslegs: Evolve a compression function for a cryptographic hash function.

23:34 arrdem: wat.

23:34 dbasch: fowlslegs: are you creating your own cryptographic hash function?

23:35 fowlslegs: http://www.seg.inf.uc3m.es/papers/2008recsi2.pdf

23:37 dbasch: is that for fun, or do you have a specific application in mind?

23:39 fowlslegs: Fun. I wouldn't use a cryptographic hash I made myself.

23:41 With (partition 4 (crypto.random/bytes 64)) I still have the problem of how to implement bit-xor on two of the 16 32-bit words.

23:42 Wait maybe (map bit-xor (25 ...) (-112 ...)) would work.

23:43 Yup.

23:44 I'm a bit rusty with Clojure, I'll try to search/ remember before asking another easy question.

Logging service provided by n01se.net