#clojure log - Oct 05 2015

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

0:03 Ilie: namra: Regarding the "right way" to use riemann, should I create a new project with lein and try to add riemann as a dependency?

0:04 Will my lean repl :connect localhost:5557 work?

0:05 justin_smith: Ilie: I mentioned requiring it from your own project because that's normally how we use clojure libs, but it could be reimann has it's own conventions

0:05 namra: Ilie: do you just want to use riemann in production or do you want to add you custom functionality to riemann? or is there some feature in the master branch that isn't within one of the prebuild uberjar releases?

0:06 even if you have some custom stuff like with your email, there's really no need to fiddle with the riemann source

0:06 Ilie: I want to use riemann in production, I'm presenting my POC tomorrow to management, any help is more than appreciated

0:06 Ok, so I should create a new lein project and try to add riemann in the dependencies list?

0:07 namra: then i'd recommend you to just download a prebuild uberjar instead of wrestling around with leiningen

0:08 and then you can take your custom functions you have in function.clj put that in the same directory as riemann.config and add (include "functions.clj") to the top of riemann.config

0:08 that's really it. no need for leiningen.

0:09 there are even binary packages for the major linux distributions

0:10 Ilie: Ok, thank you again for the help guys

0:18 I'm using (require 'riemann.seiso) and it works, I moved seiso.clj to src/riemann/seiso.clj, thank you again for your help

1:10 zematis: Is there a simple function to remove members of one collection from another collection, but only in proportion to the amount of them in each collection?

1:10 e.g:

1:10 (remfunc [1] [1 1 2]) => [1 2]

1:10 )

1:17 kenrestivo: is there some way to exec a file (with shell) that's in a uberjar?

1:17 there's an embedded ! put in there by... i dunno, java? it's not making the shell happy, i.e.:

1:17 java.io.IOException: Cannot run program "file:/home/djdash/target/djdash-0.1.1-standalone.jar!/scripts/nowplaying.py": error=2, No such file or directory

1:18 Kneiva: kenrestivo: you can unzip the jar

1:18 kenrestivo: no, i mean, from within the clojure code, running in the uberjar

1:19 amalloy: kenrestivo: it's not a file, it's an entry in a zip file. you can run that iff your OS/shell has a way to treat an entry in a zip file as if it were a file on disk

1:19 kenrestivo: interesting. i'll find out if it can.

1:20 googling this will not be fun

1:23 amalloy: you probably can't

1:23 i mean, you could like...unzip the file to stdout, parse out the file you want, and pipe that to sh or whatever

1:24 but is that really how you want to spend an evening

1:28 Kneiva: zematis: http://stackoverflow.com/a/1511428 maybe?

1:29 kenrestivo: amalloy: very true. i'll just dump the script in the filesystem somewhere and call it that way

1:44 zematis: Kneiva: nope, doesn't work :(

1:44 removes items multiple times

1:44 Kneiva: zematis: Can you give another example of what you want?

1:45 zematis: excuse me, removes all instances of the items in the set

1:45 (remove #{1} [1 1 2]) => [2]

1:46 for ease of comparison, I wanted:

1:46 (remfunc [1] [1 1 2]) => [2]

1:46 (remfunc [1 2 3] [1 2 2 3 3 3]) => [2 3 3]

1:48 amalloy: zematis: you can't really do that very efficiently if they're both vectors

1:49 roelof: if I have this code : http://lpaste.net/142334 why do I see this error : http://lpaste.net/142335

1:49 zematis: amalloy: lists would be fine too

1:49 amalloy: but if you took the "things to remove" and made it into a multiset you could do it efficiently, like (multi-remove '{a 1, b 2} '[a b c a b c]) => '[c a c]

1:50 lists are even worse. you need an actual data structure with fast lookup, if you want to look compare items in two collectinos

1:50 zematis: ah yes, was thinking removal time, not lookup time :)

1:50 that's what I'm looking for. Thanks!

1:51 amalloy: i mean you still ahve to write multi-remove

1:51 but it's not hard with that API

1:54 zematis: well, can't always have thing the easy way

1:58 amalloy: note also that you can use clojure.core/frequencies to convert your original removal list into a removal map

1:58 zematis: roelof: you have two '(' s before map

1:59 amalloy: i've looked at my usecase and ended up implementing the function "duplicates: [coll

2:00 ]" instaed

2:00 but I'll keep that in mind when this comes up again.

2:02 roelof: so the outer wrapping '(' is trying to execute the first item it's given, which is the lazy-sequence generated by map. But the sequence isn't a function, so it can't be executed.

2:03 amalloy: zematis: "call as a function", not "execute"

2:03 zematis: thanks )

2:03 *:)

2:10 roelof: Thanks, ir works, Is this a good clojure way to make the fib numbers ?

2:16 then it would be this using only anomous functions : (fn [n] (take n (map first (iterate (fn [a b] [b (+ a b)] ) [0 1]))))

2:24 someone a tip how I can improve this. This looks even long as a loop - recur solution ?

2:26 amalloy: well, remove the n and the take, so you can just return the infinite seq

2:38 roelof: amalloy: I did use the take n because I want only some numbers not the whole sequence

2:39 amalloy: what i mean is, if you are implementing "produce fibonacci numbers", you want a function that produces all of t hem, and then you can call take on that. you don't want to *have* to specify an n to get any fibonacci numbers

2:44 roelof: oke, but what if I want one time three numbers and the other time 4 times, That is why im using the n

2:47 amalloy: then you can just write (take 3 (fibs)) and (take 4 (fibs)), or (defn n-fibs [n] (take n (fibs))) (n-fibs 3) (n-fibs 4)

2:47 it's just unnecessarily limiting to tie your fibonacci function to the take function

2:48 roelof: oke, I try to find a solution to this problem: https://www.4clojure.com/problem/26 and there a x or n is given

3:00 amalloy: did you give a answer after my last question. My wife pressed all my sites away

3:01 amalloy: no. i think for an exercise site like 4clojure it's perfectly fine to bake in the n. i certainly would

3:01 but i guess we shouldn't have written the problem that way! (= (take 3 (__)) ...) would have been a better problem

3:03 roelof: oke, then I have now a loop - recur and this solution.

3:13 chips : this one (fn [n] (map first (iterate (fn [a b] [b (+ a b)]) [0 1]))) fails the unit test of 4clojure

3:15 luxbock: ,(def fib ((fn [f] ((fn [x] (x x)) (fn [x] (f (fn [xx] ((x x) xx)))))) (fn [f] (fn [x] (condp = x 0 0 1 1 (+ (f (dec x)) (f (dec (dec x)))))))))

3:16 clojurebot: #'sandbox/fib

3:16 luxbock: ,(fib 10)

3:16 clojurebot: 55

3:16 luxbock: yay

3:19 roelof: Can anyone explain why my solution fails on 4 clojure but works on my own box

3:19 luxbock: roelof: if you mean the snippet you posted above, the argument `n` isn't used anywhere

3:20 roelof: oke, somehow the take part is missing

3:22 also this one fails : (fn [n] (take n (map first (iterate (fn [a b] [b (+ a b)]) [0 1])))) :(

3:23 emauton: I'm curious whether there are any ongoing efforts to improve Clojure's REPL error output? I kind of get by, having some Java background, but I have a friend who's finding some of the obscure errors quite frustrating.

3:23 amalloy: roelof: the 4clojure problem thinks fibs start at 1, not 0. another problem with the puzzle

3:23 luxbock: roelof: you are passing too many arguments to the `f` that `iterate` takes

3:24 roelof: you probably meant to use `[[a b]]` instead of `[a b]` there

3:24 amalloy: oh that too

3:27 roelof: thanks , chaning it to [ 1 1 ] instead of [0 1] and the extra [] around the [a b] did the job

3:27 can anyone explain why the extra [] must be added ?

3:28 luma: because the function takes only one parameter, a vector of two numbers

3:28 the [[a b]] is a destructuring that takes one vector and binds its first item to a and second item to b

3:29 roelof: oke, thanks

3:29 now I have to figure out how to reverse a seq without using reverse.

3:35 I think map and conj can do the job

3:36 luma: how would map do it?

3:39 roelof: luma: that is one of the things I do not know at the moment. One way or the other I need some sort of accumenlator to store the new map I think

3:41 amalloy: roelof: indeed! and "accumulator" is a word that should immediately make you think "reduce", not "map"

3:41 roelof: oke, at this moment just doig some thinking

3:43 I can also look at reduce. I always thought that reduce was more about adding , counting where the output is one things and not a whole map

3:49 amalloy: well, the problem you'll run into with map is that it can only transform one element at a time, and leave it in the same place

3:49 you can't use it to do "global" transformatinos across a whole sequence

3:51 roelof: oke, then I will do some experiments today how I can use reduce . Thanks so far for the help

4:20 marshzor_: exit

5:29 nXqd: hi guys, I'm trying out component system of Stuart, but I'm not so clear how to use one dependency in a component

5:29 for example : I have user component, I have one function user-add , and it needs connection from :db component

5:30 how do I get the conn from db component in user component. ( Just assume that I have all configuration regarding dependency-map and system-map setting up correctly )

5:41 sveri: Hi, how can I convert a map into a vec? I came up with (flatten (into [] {:foo :bar})) but that looks so much code

5:42 schmir: ,(seq {:foo :bar})

5:42 clojurebot: ([:foo :bar])

5:44 sveri: schmir but thats also wrapped into a seq

5:44 oddcully: ,(mapcat identity {:foo :bar :1 :2})

5:44 clojurebot: (:foo :bar :1 :2)

5:44 schmir: ,(apply concat {:a 1 :b 2 :c 3})

5:44 clojurebot: (:a 1 :b 2 :c ...)

5:45 sveri: Ok, thank you both. I guess I just pick one randomly :D

6:14 TEttinger: ,(apply vector {:a 1 :b 2}) ;; not sure how this works

6:14 clojurebot: [[:a 1] [:b 2]]

6:14 triss: has it been decided that we should encourage namespace aliases?

6:14 TEttinger: ,(apply vec {:a 1 :b 2}) ;; not sure how this works either

6:14 clojurebot: #error {\n :cause "Wrong number of args (2) passed to: core/vec"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (2) passed to: core/vec"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 36]\n [clojure.lang.AFn applyToHelper "AFn.java" 156]\n [clojure.lang.AFn app...

6:15 TEttinger: triss: as in, (:require [clojure.string :as s])

6:15 ?

6:15 triss: yep.

6:15 Does it say this anywhere?

6:16 TEttinger: AFAICT that's very common and encouraged heavily over (:use [clojure.string]) or referring to all of it

6:17 notably for this example, (:use [clojure.string]) will make the clojure.core fn replace not available by its normal name (you can use clojure.core/replace to use it, but replace will be the one in string, confusingly)

6:19 ~use

6:19 clojurebot: I am putting myself to the fullest possible use, which is all I think that any conscious entity can ever hope to do.

6:19 TEttinger: ha

6:19 ~require

6:19 clojurebot: excusez-moi

6:26 tolu: Hi

6:27 What’s the best web framework to use in clojure

6:29 scottj: tolu: compojure is by far the most popular and a good starting point

6:29 tolu: scottj: thanks

6:33 scottj: what about Hoplon? I just a few things about it now

6:34 : scottj: what about Hoplon? I just read a few things about it now

6:35 scottj: tolu: idk much about it. luminus is probably second most popular.

6:36 tolu: scottj: alright

7:07 javjarfer: Hi there! Anyone using seesaw knows if frame min-size is respected while resizing?

7:27 crocket: https://upload.wikimedia.org/wikipedia/commons/1/1d/Newlisp-lisp-thought.png

7:31 roelof: Hello, for 4clojure I have to reverse a seq without using reverse. So I thought I could do it this way (reduce (conj {} xxx ) list) but I cannot figure out what must be xxxx. I do not have a name for a item as far as I know

7:31 who can give me a tip here ?

7:33 luma: what is the empty map in conj?

7:33 why would you conj anything onto a map if you want to reverse a seq?

7:34 roelof: luma a empry map is {} as far as I know

7:34 dstockton: ,(reduce #(conj %) [1 2 3 4] '())

7:34 clojurebot: [1 2 3 4]

7:34 luma: yes, why do you have an empty map there

7:34 dstockton: ,(reduce #(cons %) [1 2 3 4] '())

7:34 clojurebot: [1 2 3 4]

7:34 luma: ,(reduce conj '() [1 2 3 4])

7:34 clojurebot: (4 3 2 1)

7:35 dstockton: :D

7:35 roelof: I thougtht it was needed. I have to put the answer somewhere ?

7:36 luma: but the answer isn't a map, it's a sequence (and list works well in this case)

7:37 roelof: wierd. I thought conj needed two arguments. A seq and a item. On your solution I see only 1 '() or is the list now a argument for reduce and for conj ???

7:38 luma: yes, it is given two arguments there

7:39 the first argument to reduce is a function that takes two arguments (the accumulator and the current item from the input sequence)

7:40 and the initial value for the accumulator is the empty list '()

7:41 roelof: thanks but sometimes the clojure syntx can be very confusing

7:42 luma: what's confusing about reduce?

7:42 roelof: I thought the first argument of reduce is the conj function and the second one the list. Conj needs also 2 argument the element and a list.

7:43 luma: yes, and that's how reduce calls it

7:44 basically, (reduce conj '() [1 2 3 4]) is equal to (conj (conj (conj (conj '() 1) 2) 3) 4)

7:44 TMA: roelof: consider: (reduce (fn [accumulator item] (conj accumulator item)) '() [1 2 3 4])

7:46 roelof: you can then simplify (fn [accumulator item] (conj accumulator item)) to just conj by eta conversion

7:46 roelof: eta conversion? I have still a lot to read

7:46 snowell: I think the doc for reduce is worded confusingly

7:47 But once you see it in use once or twice it clicks

7:47 tdammers: eta reduction means that if you have (fn [x] (f x)), you can reduce it to just (f x)

7:47 luma: eta conversion is a lambda calculus thing, don't worry about it

7:47 TMA: roelof: never mind. eta conversion is a concept from lambda calculus; basically it says that (fn [x] (f x)) is the same thing as f itself

7:48 tdammers: that, yeah

7:48 it's a bit more obvious in Haskell/ML-like languages, where it amounts to removing the last argument from both sides of the "equation"

7:49 f x = g x => f = g

7:49 roelof: Thanks , I hope he click will come after more and more practice

7:50 TMA: roelof: it eventually clicks

7:51 snowell: roelof: reduce didn't really click with me until last week when oddcully and I were helping you with it :)

7:51 roelof: i hope so. so when I use a anymous function like (fn (counter) (inc counter) I can also make it smaller that way ?

7:52 luma: yes, that anonymous function is exactly equal to just "inc"

7:52 oddcully: roelof: yes (but you have wrong syntax there)

7:53 roelof: #(inc %) (fn [x] (inc x)) inc are all three a function to increment one passed argument

7:53 snowell: Haha sorry I summoned you, oddcully!

7:53 oddcully: roelof: so you can do this: (#(inc %) 42)

7:54 snowell: haha! now you have banish me

7:54 TMA: roelof: you can safely continue to use (fn (counter) (inc counter)) if it provides you with better understanding

7:56 roelof: oke, I was thinking about a solution for counting for 4 clojure which now looks like this : (fn [list] (reduce (fn [counter _] (inc counter)) 0 list))

7:56 I wonder if I could make it smaller

7:57 luma: not really, since the function must accept two parameters

7:57 TMA: roelof: there is no need to have the smallest code; that will come as you will advance

7:58 roelof: oke, I will leave it this way then and do whatever I think is better working for me.

7:58 Thanks all

7:58 luma: you could do it a bit differently: (fn [list] (reduce + 0 (map (constantly 1) list)))

7:58 TMA: roelof: you can cheat a bit with #(%) shortcut: #(reduce (fn [c _] (inc c)) 0 %)

7:59 snowell: Good luck, roelof :D

7:59 roelof: thanks

8:00 oddcully: roelof: if you dont like the wrapping of (fn [list] (... list)) you could learn about partial

8:00 roelof: and again thanks , your guys/girls are learning me very much and I appreciate it also a lot

8:01 oddcully: partial is the next chapter I want to read in the programming clojure book

8:01 oddcully: which brings me to: is there are bizarro-partial, that gens a fn, that has more arity than the wrapped one (as for the inc case in a reduce)?

8:02 tdammers: how would that work? what would the generated fn do?

8:02 I don't think there's a generic way of having this make sense

8:03 it would for specific cases, such as turning a function that takes exactly one vector into a variadic fn

8:03 TMA: something like (defn bizarro-partial [f] #(apply f %&)) ?

8:03 tdammers: but not as generic as currying

8:04 oddcully: TMA: nice!

8:05 crocket: Woohoo?

8:06 TMA: ,((partial inc) 1 2 3)

8:06 clojurebot: #error {\n :cause "Wrong number of args (3) passed to: core/inc"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (3) passed to: core/inc"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 40]\n [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 invo...

8:07 oddcully: TMA: yes does not work for the reduce case

8:07 TMA: ,(apply inc [1 2 3])

8:07 clojurebot: #error {\n :cause "Wrong number of args (3) passed to: core/inc"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (3) passed to: core/inc"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 40]\n [clojure.lang.AFn applyToHelper "AFn.java" 160]\n [clojure.lang.AFn app...

8:07 tdammers: one could of course make an uncurry fn

8:08 (defn uncurry [f] (fn [arg & args] ((f arg) args)))

8:08 sth like that

8:12 crocket: Will tail call optimization be useful in clojure?

8:16 ane: well, yes

8:19 Bronsa: relatively useful, we don't use recursion as much as in, say, scheme

8:24 Leonidas: One could program CPS in Clojure then, but I doubt that people would like that.

8:26 roelof: /me hopes once he could make a sort of bank account programm which can leads to a accounting programm but he think he has to learn a lot before he can begin

8:29 but for now I have to leave. I have to go to the dentist :(

8:30 tdammers: Leonidas: why not?

8:30 troydm: how do I remove complety from mapping namespace?

8:30 tdammers: matter of convenient abstractions, I'd think

8:34 Leonidas: tdammers: Maybe you're right.

8:35 tdammers: CPS certainly isn't a silver bullet, but when it's appropriate for the problem at hand, performs well, and makes for readable code, I doubt anyone sane would oppose

8:36 Leonidas: well, readable code is arguable.

8:37 tdammers: arguably so :D

9:04 troydm: guys

9:04 let's say I have a function that I want to declare later

9:04 but I need to call it for a definition

9:04 how I can I somehow delay the evaluation of a function?

9:05 can I somehow make it lazy so the entire thing be evaluated only later?

9:05 namra: sounds like a promise

9:05 tdammers: wait

9:05 troydm: I'll try to write a simple example of a problem that I have

9:06 tdammers: do you want to delay the function evaluation, or do you want to use a function before it is defined?

9:06 i.o.w., are we talking runtime "before" here, or code-writing-time "before"?

9:11 troydm: tdammers: https://www.refheap.com/278e13f6d25ee28dee6a7287b

9:11 simply speaking I want to delay the evaluation of a variable definition until the function is defined

9:13 tdammers: uhm

9:14 I don't think that's how clojure's execution model works

9:14 best I can think of would be to wrap f in a promise

9:17 TEttinger: (doc delay)

9:17 clojurebot: "([& body]); Takes a body of expressions and yields a Delay object that will invoke the body only the first time it is forced (with force or deref/@), and will cache the result and return it on all subsequent force calls. See also - realized?"

9:21 TEttinger: ,(delay (bart-simpson))

9:21 clojurebot: #error {\n :cause "Unable to resolve symbol: bart-simpson in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: bart-simpson in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol:...

9:21 TEttinger: the bot might be dereferencing to print

9:22 ,(delay 5)

9:22 clojurebot: #object[clojure.lang.Delay 0x7c2e76a0 {:status :pending, :val nil}]

9:22 TEttinger: ,(def d (delay 5))

9:22 clojurebot: #'sandbox/d

9:22 TEttinger: ,@d

9:22 clojurebot: 5

9:22 TEttinger: ,(def d (delay (homer)))

9:22 clojurebot: #error {\n :cause "Unable to resolve symbol: homer in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: homer in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: homer in this...

9:22 TEttinger: you could maybe use declare

9:23 ,(declare bart-simpson)

9:23 clojurebot: #'sandbox/bart-simpson

9:23 TEttinger: ,(def d (delay (bart-simpson)))

9:23 clojurebot: #'sandbox/d

9:23 TEttinger: ,(defn bart-simpson [] "ay carumba")

9:23 clojurebot: #'sandbox/bart-simpson

9:23 TEttinger: ,@d

9:23 clojurebot: "ay carumba"

9:24 TEttinger: troydm: ^

9:26 borkdude: I have a println in my compojure end point. When I post only once, it's printing three times. I have checked this side effect by incrementing an atom, which is only happening one time. What could be wrong with my println?

9:38 troydm: TEttinger: another question

9:38 let's say I have not functions but just variable definitions

9:38 and I want another to reference one not yet declared

9:39 something like:

9:39 (declare f)

9:39 (def f2 (+ f 2))

9:39 (def f 13)

9:39 there is no other way than using delay?

9:40 tdammers: what's wrong with delay?

9:40 troydm: tdammers: u need to dereference it before using

9:41 opqdonut: troydm: that would require a smarter compiler

9:41 troydm: opqdonut: yeah, seems so

9:41 tdammers: opqdonut: not much smarter though

9:41 opqdonut: tdammers: yeah, only one toposort

9:41 but still

9:41 with macros it would be flaky

9:42 tdammers: I think the bigger tradeoff is that it would make laziness implicit, which is something that you can only really get away with when your language has no side effects at all

9:42 opqdonut: and also, a clojure file can interleave side-effectful things between defs

9:42 so yeah, what tdammers said

9:43 tdammers: fwiw, haskell does it, but this choice alone makes for a radically different language

9:43 troydm: seems something that Haskell is for

9:43 I guess I'll have to stick with references

9:52 btw is there a macro for delay?

9:52 like (defd f body) that would result in (def f (delay body)) ?

10:14 noncom: adding quil dependency to my current project makes leiningen fail to compile it

10:14 the error is "class "org.bouncycastle.crypto.digests.SHA3Digest"'s signer information does not match signer information of other classes in the same package"

10:15 i have run deps tree and found that quil requires these "bouncy" deps too, so does the buddy library that i use in my project

10:15 since quil uses them for PDF export and i don't need that, i thought i would exclude them

10:16 but after i add them to quil exclusions, the project breaks down again - now it fails to require the namespace that contains "buddy" requires

10:16 what do i do with that

10:55 np, solved

10:58 TMA: (inc rubberduck)

11:54 zxc: Hello! Can someone help me with vim fireplace, please? I can't connect to the nREPL server

11:57 I've tried to google it, but there was nothing

11:58 oddcully: zxc: you ran your `lein repl` and started vim in that same dir where the project.clj is? it should work out of the box

11:59 if you have started the lein repl later, you can do `:Connect` in vim and follow the instructions

12:01 zxc: Okay, I will try it

12:03 I still have to give a port

12:03 oddcully: Although I've started it in a dir with project.clj

12:04 oddcully: if there is no .nrepl-port file, then you have to use the port (or the whole url) the repl prints

12:04 zxc: Can you specify? I've never done magic things like that

12:04 oddcully: it's the first line the repl prints

12:04 zxc: kay, thanks!

12:05 oddcully: you can use the whole "uri" there `:Connect nrepl://localhost:666`

12:05 zxc: It works! Thanks a million

12:07 oddcully: Also, is there a way of deleting one curly bracket while using paredit?

12:10 oddcully: once in trillion parens, there is some inballance. i use `r<space>` to get rid of it

12:11 zxc: Thanks again!

13:14 cloj_dev: can you put println in a let statement?

13:17 hiredman: clojure has expressions, not statements

13:17 you can put an expression that is a call to the println function any place you can put an expression

13:23 triss: but note that println always returns nil!

13:23 sometimes I make a p fn that prints and returns so I don't have to move code about as much when printing

13:24 (defn p [x] (println x) x)

13:27 oddcully: ,(let [x {:a :b} y (doto x println)] y)

13:27 clojurebot: {:a :b}\n{:a :b}

13:30 triss: oddcully: that might come in handy. thanks!

13:40 TimMc: I have a unit test that tries to exercise a macro that emits a defonce. If I re-run those tests, i get failures, because state is accumulating in the object ref'd by the defonce.

13:40 Is there an easy way to just remove that var from the test ns?

13:41 rhg135: ns-unmap

13:46 TimMc: Thanks!

14:03 perrpell: I'm using [org.clojure/tools.namespace "0.2.11"] for auto reload in the repl of files modified in the project.

14:04 When I edit an existing function, the edits are picked up and all is good.

14:05 But if I add a new function to a namespace, the new function is not visible in the repl after (refresh). Can anyone help me understand why that is?

14:05 Thanks in advance.

14:06 rhg135: Are you by chance using aliases?

14:06 If so they point to the old namespace

14:07 perrpell: No am not using aliases. Just boring ole (require) at the repl.

14:36 justin_smith: perrpell: require with the :refer argument?

14:36 perrpell: @justin_smith sorry I should have said :as

14:37 justin_smith: perrpell: :refer and :as can be used together, I'm specifically asking if :refer was used at all

14:37 perrpell: Hold a second let me check.

14:39 The only :refer that is used is when requiring the repl tools - (require '[clojure.tools.namespace.repl :refer [refresh]])

14:39 That comes directly from their docs.

14:40 justin_smith: OK - yeah, that's optional - the reason I ask is refer needs to be re-run if you change stuff, because of how refer works (aliasing things), but if you did (require foo.bar :as bar) then define foo.bar/baz, bar/baz should work

14:40 whether that's done by doing a require :reload on foo.bar or switching to foo.bar and defining baz or whatever

14:41 perrpell: @justin_smith what do you use to auto reload all your files on the repl? Is there another tool set?

14:42 justin_smith: perrpell: I typically use (require 'foo.bar :reload) or (require 'foo.bar :reload-all), but sometimes use (refresh)

14:43 perrpell: oh! if you did the require :as outside the file's namespace def (eg. in the repl), refresh will obliterate that

14:43 perrpell: and you will need to redo your require in the repl if you used refresh in that case

14:44 perrpell: the difference with refresh is it actually destroys all the namespaces and their vars and rebuilds from scratch, so that can break mappings that are not defined in the source files (eg. repl mappings)

14:45 perrpell: justin_smith: yes the (refresh) succeeds when I edit an existing function in any given package (e.g. foo.bar).

14:45 But if I add a function to foo.bar and then do a (refresh) the new function doesn't get picked up in the refresh.

14:47 justin_smith: perrpell: are you adding it in the repl, or changing the source? because if you change the source it should exist after a refresh

14:49 perrpell: justin_smith: in the source for sure.

14:53 skeuomorf: ,(def x (.getBytes "test"))

14:53 clojurebot: #'sandbox/x

14:54 skeuomorf: ,(. x length)

14:54 clojurebot: #error {\n :cause "No matching field found: length for class [B"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No matching field found: length for class [B"\n :at [clojure.lang.Reflector getInstanceField "Reflector.java" 271]}]\n :trace\n [[clojure.lang.Reflector getInstanceField "Reflector.java" 271]\n [clojure.lang.Reflector invokeNoArgInstanceMember "Reflector.java" 315]\...

14:54 skeuomorf: hmm

14:58 justin_smith: ,(. x count)

14:58 clojurebot: #error {\n :cause "No matching field found: count for class [B"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No matching field found: count for class [B"\n :at [clojure.lang.Reflector getInstanceField "Reflector.java" 271]}]\n :trace\n [[clojure.lang.Reflector getInstanceField "Reflector.java" 271]\n [clojure.lang.Reflector invokeNoArgInstanceMember "Reflector.java" 315]\n ...

14:59 justin_smith: ,(alength x)

14:59 clojurebot: 4

14:59 justin_smith: skeuomorf: arrays don't have methods like classes do! it's super weird

14:59 skeuomorf: justin_smith: Yes!

14:59 justin_smith: skeuomorf: array.length in java is actually a weird pseudo-method-call syntax but not a real method

15:00 emauton: Oh, repeat from this morning just in case any awake-people have opinions: I'm curious whether there are any ongoing efforts to improve Clojure's REPL error output? I kind of get by, having some Java background, but I have a friend who's finding some of the obscure errors quite frustrating.

15:00 skeuomorf: justin_smith: interesting

15:01 justin_smith: emauton: there are unofficial projects but aviso/pretty, but it definitely is not a priority of the core team

15:01 emauton: I had a good look around the community wikis & JIRA and while there's a grab-bag tag "errormsgs" and some old design wiki notes from 2011-2013, there wasn't a lot.

15:01 justin_smith: I'll take a look at that, thanks

15:02 justin_smith: emauton: basically any improvement on error handling / messages that degrades performance even a little has historically been a no-go for the core language

15:02 emauton: That's useful context, thank you.

15:02 justin_smith: emauton: hlshipp also has other related projects to aviso/pretty, for example allowing you to push a "context" onto a custom stack so that things in core.async or such can give more informative errors

15:03 forgetting the name off the top of my head, maybe rook?

15:04 emauton: oh, rook is his router thing, which uses tracker, that's the one I was thinking of https://github.com/AvisoNovate/tracker

15:04 tracker is the one that helps provide better error context

15:04 emauton: Great, yes, having a look through their repos now.

15:07 I think "pretty" will already be a big improvement. Wonderful, thanks for the links.

16:17 arry: hi! i've got a question: when you use WebJars in a Ring application, where are the asset files actually served from? It seems like witchery to me :)

16:42 justin_smith: arry: the jar is a zip file, the assets typically are served out of the zip file itself (which means uncompressed from ram)

16:43 arry: of course extracting that jar/zip into a directory, and serving from the resulting files is also an option

16:44 arry: cool

16:45 i was wondering if the files were packaged with the app, or whether they were downloaded from a CDN at some point during app running (WebJars site mentions a CDN)

16:47 mgaare_: any way to alias things I'm importing? right now I'm doing (import foo.Bar biff.Bar) and getting a duplicate name problem

16:49 and by problem I naturally mean exception :D

16:49 amalloy: no

16:49 you just have to choose to use the fully-qualified name for one of them

16:51 mgaare_: ah, I see

17:12 phorse: What's the best way to include an anti-forgery token in a reagent form?

17:28 justin_smith: phorse: you can get it into the reagent state when the page data is sent, then have the form's component grab that data

17:28 phorse: so assuming you have some ajax json request, have the anti-forgery token be part of that payload?

17:35 phorse: justin_smith: I'm a little confused. I'

17:35 've got a basic compojure app that I'm adding reagent fanciness to, so all my pages are built server side.

17:36 Glenjamin: if you're doing json, you don't actually need a csrf token

17:36 phorse: I'm just dipping my toe in the water of clojurescript - will this require me to rework the server side to be more rest-ish?

17:36 Glenjamin: oh, the simplest thing to do would be to drop it into a hidden form field as normal, and use JS to read it out

17:37 phorse: Ok, so just have it in the response and then use js to copy it into the form?

17:38 Is this the usual way to handle sharing between server and client? Say, if I want to access the user session, I should embed it in the page?

17:48 Glenjamin: basically, yes

17:48 or you can make a little api thing

17:51 phorse: Just to make sure I understand the api point: Client sends request for resource (GET /home), then the server packages that up in JSON and sends it over?

17:52 justin_smith: phorse: that would be normal for reagent, yeah, since reagent is a tool for rendering on the client side

17:53 phorse: Ok, thanks. That should be enough to go on for a while.

20:34 zexperiment: evening friends

20:37 justin_smith: evening

Logging service provided by n01se.net