#clojure log - Nov 22 2014

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

0:00 justin_smith: marcuscreo: it's about midnight on a friday there, you may not find many people who are there on irc

0:00 cfleming: marcuscreo: I'm at the conj, but just about to go to bed.

0:01 ambrosebs: cfleming: great talk

0:01 cfleming: ambrosebs: Thanks!

0:01 ambrosebs: You're not at the conj, right?

0:01 ambrosebs: cfleming: right

0:02 cfleming: ambrosebs: Actually, I wondered if I'd find you at the Scheme workshop these days :-)

0:02 ambrosebs: cfleming: I had too many conferences lately to even consider it

0:03 cfleming: ambrosebs: Bummer, would have been cool to meet up.

0:03 ambrosebs: yea definitely

0:10 ffwacom: people not smiling in photos is going to be a trend

0:10 fuck wrong channel

0:22 holo: hi

0:23 jabba question: what's this {} in → 'new ConstraintMapping[] { cm }' and how to interop with it?

0:25 amalloy: jabbslad: that's a single-element array, whose only element is cm

0:25 er

0:25 sorry, holo

0:25 holo: amalloy, i see

0:28 I just noticed state of clojure didn't ask if programmer has any java background

0:30 (inc amalloy)

0:30 lazybot: ⇒ 198

0:30 holo: inc could have print side effects saying "thanks"

1:08 teajoe: Hey all! When I println, I'm seeing this: #<core$rsc_files boot.core$rsc_files@5401e235>

1:08 is this a java obj?

1:09 TEttinger: you are printing some object that doesn't have a toString implemented apparently

1:09 what are you passing to println?

1:10 teajoe: some object from boot-clj

1:11 they call a juxt with (memfn getPath) on it, so its probably some file object

1:11 but for future reference can i get type info on such a thing

1:17 marcuscreo_: (+ 1 2 3)

1:17 clojurebot: *suffusion of yellow*

1:17 marcuscreo_: (println ‘here")

1:18 marcuscreo: (+1 2 3)

1:18 (+ 1 2 3)

1:18 clojurebot: *suffusion of yellow*

1:18 justin_smith: http://stackoverflow.com/questions/3987428/what-is-an-initialization-block

1:19 err

1:19 http://www.urbandictionary.com/define.php?term=A%20Suffusion%20of%20Yellow that is the one I was looking for

2:05 rritoch: I'm not sure if this is a bug or not, but clojure regular expresions aren't matching #"\s+" to non-breaking spaces... Does anyone know how I can change this to match any whitespace including nonbreaking spaces?

2:09 ivan: rritoch: stackoverflow says 'It's a non-breaking space. According to the Pattern Javadocs, \\s matches [ \t\n\x0B\f\r], so you'll have to explicitly add \xA0 to your regex if you want to match it.'

2:10 rritoch: ivan: Ok, thanks.

2:11 ivan: Ok #"[\s\xA0]+" worked

2:12 (inc ivan)

2:12 lazybot: ⇒ 1

2:17 dysfun: wow. after fighting the swift build process for two days, i have a whole new appreciation for clojure

2:17 also leiningen

2:25 TEttinger: if you want to be really in-depth, rritoch:

2:25 ,(re-seq #"\pZ|[\f\t\r\n\u000b]" "good\u00a0job !\f\t\r\n\u000b\u3000\u200a")

2:25 clojurebot: (" " " " "\f" "\t" "\r" ...)

2:25 TEttinger: \pZ is the category of all unicode separator characters that aren't also control chars

2:26 so space, nbsp, ideographic space in the CJK asian character block

2:26 several others

2:27 \f form feed, \r carriage return, \n line feed, \t horizontal tab, \u000b vertical tab don't count for some reason

2:32 justin_smith: wow - first time ever, I think I deadlocked my repl

2:32 word of advice - using (locking *out* ...) inside pmap is probably a bad idea

2:32 mj-0: what is regex for separating words of any language?

2:33 rritoch: TEttinger: Thanks, that was helpful. I changed it to #"(\pZ|\s)+" which seems to be working

2:33 luxbock: I don't think there exists one for a lot of languages

2:33 TEttinger: ah, that works rritoch!

2:33 mj-0: I tried "\W+" but for other languages its not working.

2:33 TEttinger: mj-0: in chinese writing, you often don't have spaces at all between characters, right?

2:34 also, \w is not so good, it only recognizes latin script

2:34 you can use \b to get a word boundary using \w rules, IIRC

2:34 mj-0: TEttinger: yeah. it doesn't matter to me. I just want to split words.

2:34 justin_smith: some info here http://www.regular-expressions.info/unicode.html

2:35 luxbock: in Thai you separate sentences with a space, but there's nothing that tells you when a word ends other than recognizing what that word is and what its last character is

2:35 TEttinger: ah cool! Java supports Unicode for \b but not for \w.

2:35 http://www.regular-expressions.info/wordboundaries.html

2:35 justin_smith: nice, just a jump away from the one I found

2:36 TEttinger: I should bookmark regular-expressions.info's unicode page, it's so helpful

2:36 that and just DDG searching for stuff like "feff unicode"

2:37 https://duckduckgo.com/?q=feff+unicode

2:40 here's some sinhala that I can't read or print correctly

2:40 ,(re-seq #"\b" "බුදුරජාණන් වහන්සේගේ දන්තධාතූන්")

2:40 clojurebot: ("" "" "" "" "" ...)

2:40 TEttinger: err

2:41 &(re-seq #"\B+" "බුදුරජාණන් වහන්සේගේ දන්තධාතූන්")

2:41 lazybot: ⇒ ("" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "")

2:41 TEttinger: errrrrr

2:41 justin_smith: TEttinger: yeah, I was trying to make re-seq work with \B / \b and couldn't

2:41 even with ascii

2:41 TEttinger: &(re-seq #"\b.+\b" "බුදුරජාණන් වහන්සේගේ දන්තධාතූන්")

2:41 lazybot: ⇒ ("බුදුරජාණන් වහන්සේගේ දන්තධාතූන්")

2:41 TEttinger: &(re-seq #"\b.+?\b" "බුදුරජාණන් වහන්සේගේ දන්තධාතූන්")

2:41 lazybot: ⇒ ("බුදුරජ" "ා" "ණන්" " " "වහන්ස" "ේ" "ග" "ේ " "දන්තධ" "ා" "තූන්")

2:41 TEttinger: there we go

2:42 justin_smith: woah, black magic

2:42 TEttinger: &(re-seq #"\b.+?\b" "The Quick brown fox jump'd ov'r the lazy dog.")

2:42 lazybot: ⇒ ("The" " " "Quick" " " "brown" " " "fox" " " "jump" "'" "d" " " "ov" "'" "r" " " "the" " " "lazy" " " "dog")

2:42 justin_smith: TEttinger: speaking of black magic, did you see when SagiCZ1 had a problem with a dataset that got a huge number of boms inserted into the middle of files

2:43 he was trying to parse it and getting maddening bugs

2:43 TEttinger: but thanks to your foolery, I was quickly able to identify his problem

2:43 TEttinger: lol

2:43 I did remember that

2:43 justin_smith: "oh, that's just that thing TEttinger does"

2:43 TEttinger: haha

2:43 mj-0: (re-seq #"\W+\b" "බුදුරජාණන් වහන්සේගේ දන්තධාතූන්")

2:44 TEttinger: ,(let ["even number of forms, eh?" "let's make it even" "or not"])

2:44 clojurebot: "or not"

2:44 TEttinger: mj-0: \W won't work

2:44 justin_smith: mj-0: use , or & if you want a bot to evaluate it

2:44 TEttinger: it finds non-word chars but only knows ascii

2:44 mj-0: TEttinger: got it.

2:44 &(re-seq #"\W+\b" "බුදුරජාණන් වහන්සේගේ දන්තධාතූන්")

2:44 lazybot: ⇒ ("බුදුරජාණන් වහන්සේගේ දන්තධාතූන්")

2:45 mj-0: ohh this regex is working for some of the languages

2:45 * rritoch is so sick of dealing with dates!!!

2:45 rritoch: Someone should petition the international criminal courts to make it a crime to use anything other than UTC

2:45 justin_smith: haha

2:45 TEttinger: &(re-seq #"\b(\S|\PZ)+?\b" "The Quick brown fox jump'd ov'r the lazy dog.")

2:45 lazybot: ⇒ (["The" "e"] ["Quick" "k"] ["brown" "n"] ["fox" "x"] ["jump" "p"] ["'" "'"] ["d" "d"] ["ov" "v"] ["'" "'"] ["r" "r"] ["the" "e"] ["lazy" "y"] ["dog" "g"])

2:46 TEttinger: &(re-seq #"\b(?:\S|\PZ)+?\b" "The Quick brown fox jump'd ov'r the lazy dog.")

2:46 lazybot: ⇒ ("The" "Quick" "brown" "fox" "jump" "'" "d" "ov" "'" "r" "the" "lazy" "dog")

2:46 TEttinger: that looks good

2:46 justin_smith: rritoch: I was contracting for a company in England recently, and it was actually kind of cool to be keeping UTC hours. It felt authoritative :)

2:46 rritoch: I reset my computer clock to UTC and everything

2:46 TEttinger: &(re-seq #"\b(?:\S|\PZ)+?\b" "The Quick brown fox jump'd ov'r the lazy dog. බුදුරජාණන් වහන්සේගේ දන්තධාතූන්")

2:46 lazybot: ⇒ ("The" "Quick" "brown" "fox" "jump" "'" "d" "ov" "'" "r" "the" "lazy" "dog" "බුදුරජ" "ා" "ණන්" "වහන්ස" "ේ" "ග" "දන්තධ" "ා" "තූන්")

2:47 TEttinger: slick

2:47 justin_smith: ~unicode-wordsplit is #"\b(?:\S|\PZ)+?\b"

2:47 clojurebot: In Ordnung

2:47 justin_smith: ~unicode-wordsplit

2:47 clojurebot: unicode-wordsplit is #"\b(

2:47 TEttinger: awww

2:47 justin_smith: :P

2:47 TEttinger: it doesn't like facts with ?

2:48 ~unicode-wordsplit is just ask TEttinger

2:48 clojurebot: A nod, you know, is as good as a wink to a blind horse.

2:49 justin_smith: $learn unicode-wordsplit is #"\b(?:\S|\PZ)+?\b"

2:49 lazybot: My memory is more powerful than M-x butterfly. I won't forget it.

2:49 justin_smith: $whatis unicode-wordsplit

2:49 lazybot: unicode-wordsplit is is #"\b(?:\S|\PZ)+?\b"

2:49 justin_smith: (inc lazybot)

2:49 lazybot: ⇒ 36

2:49 rritoch: justin_smith: Thats cool, I'm in SGT (GMT+8) So at least my development machine has a stable time to work with. I saw in the news that Russia just changed their time system again and I swear they're doing it just to cause trouble for programmers.

2:50 Either way, any code dealing with dates properly is virtually incomprehensible now.

2:51 mj-0: TEttinger: #"\b.+?\b" this also returns spaces, special characters. How can I get only words?

2:51 &(re-seq #"\b.+?\b" " Çarşi En büyük BEŞİKTAŞ gerisi yalan oyunda. super, otesi inanilmaz sariyor Yorumun Tamamı")

2:51 lazybot: ⇒ ("Çarşi" " " "En" " " "büyük" " " "BEŞİKTAŞ" " " "gerisi" " " "yalan" " " "oyunda" ". " "super" ", " "otesi" " " "inanilmaz" " " "sariyor" " " "Yorumun" " " "Tamamı")

2:52 TEttinger: &(re-seq #"\b(?:\S|\PZ)+?\b" " Çarşi En büyük BEŞİKTAŞ gerisi yalan oyunda. super, otesi inanilmaz sariyor Yorumun Tamamı")

2:52 lazybot: ⇒ ("Çarşi" "En" "büyük" "BEŞİKTAŞ" "gerisi" "yalan" "oyunda" "super" "otesi" "inanilmaz" "sariyor" "Yorumun" "Tamamı")

2:52 TEttinger: better?

2:52 mj-0: TEttinger: Yep. Looks better now. Thanks!

2:52 TEttinger: it will still return apostrophes as a separate thing

2:53 the meaning of that particular regex: word boundary, followed by at least one non-space, non-separator character, then another word boundary

2:54 also, do not store the group of non-space chars, that's what (?:) does

2:54 mj-0: TEttinger: Okay. I'll look into it.

2:55 TEttinger: hope it helps!

3:05 rritoch: ,(as-> (java.util.Calendar/getInstance) c (.setTime (int 0)) c)

3:05 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: setTime for class java.lang.Integer>

3:05 rritoch: ,(as-> (java.util.Calendar/getInstance) c (.setTime c (int 0)) c)

3:05 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.Date>

3:06 rritoch: ,(as-> (java.util.Calendar/getInstance) c (.setTime (java.util.Date 0)) c)

3:06 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn>

3:06 rritoch: ,(as-> (java.util.Calendar/getInstance) c (.setTime (java.util.Date. 0)) c)

3:06 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: setTime for class java.util.Date>

3:06 rritoch: Ba, I just can't win this one

3:08 ,(as-> (java.util.Calendar/getInstance) c (.setTime c (java.util.Date. 0)) c)

3:08 clojurebot: nil

3:08 TEttinger: ,(doto (java.util.Calendar/getInstance) (.setTime (java.util.Date 0)))

3:08 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn>

3:09 rritoch: Ok, thats better, how do I get this to return the modified calendar object?

3:09 TEttinger: ,(doto (java.util.Calendar/getInstance) (.setTime (java.util.Date. 0)))

3:09 clojurebot: #inst "1970-01-01T00:00:00.000+00:00"

3:09 TEttinger: there we go

3:09 clojurebot: Huh?

3:09 rritoch: aah, doto, cool

3:13 ,(doto (java.util.Calendar/getInstance) (.setTime (.parse (java.text.SimpleDateFormat. "MM/dd/yyyy") "11/22/2014")))

3:13 clojurebot: #inst "2014-11-22T00:00:00.000+00:00"

3:13 rritoch: Cool, exactly what I need

3:19 Does clojure automatically compare calendar dates correctly?

3:21 ,(> (doto (java.util.Calendar/getInstance) (.setTime (java.util.Date. 1))) (doto (java.util.Calendar/getInstance) (.setTime (java.util.Date 0))))

3:21 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn>

3:21 rritoch: ,(> (doto (java.util.Calendar/getInstance) (.setTime (java.util.Date. 1))) (doto (java.util.Calendar/getInstance) (.setTime (java.util.Date. 0))))

3:21 clojurebot: #<ClassCastException java.lang.ClassCastException: java.util.GregorianCalendar cannot be cast to java.lang.Number>

3:21 rritoch: Hmm, guess not

3:23 TEttinger: ,(compare (doto (java.util.Calendar/getInstance) (.setTime (java.util.Date. 1))) (doto (java.util.Calendar/getInstance) (.setTime (java.util.Date. 0))))

3:23 clojurebot: 1

3:24 TEttinger: ,(compare (doto (java.util.Calendar/getInstance) (.setTime (java.util.Date. 1))) (doto (java.util.Calendar/getInstance) (.setTime (java.util.Date. 2))))

3:24 clojurebot: -1

3:24 TEttinger: so compare works

3:25 rritoch: TEttinger: Cool, I've never run into compare before, but that's a better option than where I was heading :)

3:25 TEttinger: (doc compare)

3:25 clojurebot: "([x y]); Comparator. Returns a negative number, zero, or a positive number when x is logically 'less than', 'equal to', or 'greater than' y. Same as Java x.compareTo(y) except it also works for nil, and compares numbers and collections in a type-independent manner. x must implement Comparable"

3:28 rritoch: doto + compare almost makes this code readable :)

3:32 ,(as-> 1 n (min (compare n 5) (compare 10 n))

3:32 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

3:33 rritoch: ,(as-> 1 n (min (compare n 5) (compare 10 n)))

3:33 clojurebot: -1

3:33 rritoch: ,(as-> 5 n (min (compare n 5) (compare 10 n)))

3:33 clojurebot: 0

3:33 rritoch: ,(as-> 10 n (min (compare n 5) (compare 10 n)))

3:33 clojurebot: 0

3:33 rritoch: ,(as-> 20 n (min (compare n 5) (compare 10 n)))

3:33 clojurebot: -1

3:33 justin_smith: ,(compare [1 2] [1 3])

3:33 clojurebot: -1

3:33 justin_smith: :)

3:33 rritoch: I want to check if a date is in a range

3:34 justin_smith: yeah, compare should work directly on date

3:34 ,(compare (java.util.Date.) (java.util.Date.))

3:34 clojurebot: 0

3:34 rritoch: Yeah, I just used numbers to test with because it was simpler.

3:34 justin_smith: right

3:34 now I see the scrollback

3:46 amalloy: rritoch: i bet clj-time compares dates better than some hand-rolled code you or i would write

3:48 rritoch: amalloy: I ended up with (defn in-range [from to item] (< -1 (min (compare item from) (compare to item)))) which is pretty good and more general purpose than just dates.

3:48 amalloy: rritoch: that is like super-wrong, though

3:49 (< -1 x) is a very bad way to write (neg? x), because it returns false for -1

3:49 rritoch: 1 is the fail case so it should return false

3:49 err, -1 is the fail case

3:50 It's cleaner than (not (neg? x))

3:51 amalloy: you're writing (< -1 x) instead of (>= x 0)? in that case it's not wrong, just confusingly hard to read

3:52 rritoch: Yes, basically

3:54 amalloy: so my point re clj-time is that, whether your code is right or not, there are a number of edge cases, and you've had to write code that is not obviously correct at first glance. i have no idea what (min (compare x y) (compare z x)) actually computes, whereas if you used some pre-existing library it's already written, tested, and credible

3:56 rritoch: amalloy: This works, its fast, and doesn't require importing code I don't need, so it's more efficient

3:58 amalloy: I'm developing OSGi modules, so bringing in additional code is non-trivial and increases the load time of the OSGi module significantly.

3:59 TEttinger: I see your point, rritoch. I think this solution isn't bad and if documented well could be fine

4:01 rritoch: Well, I do see amalloy's point also, but while developing these OSGi modules I find myself re-inventing the wheel often to maintain efficiency. It's a nessisary evil.

4:01 err, necessary

4:03 amalloy: i don't understand osgi. i get the promise behind it: basically it's about saving you from dependency hell, right? because you can have multiple versions of whatever modules on your classpath at once? but it seems to me like the people who use it are even sadder than the people who don't

4:04 rritoch: amalloy: It is about modularization, not only do you avoid conflicts between modules since they have separate classloaders, but they can also export functionality as services to provide shared resources.

4:05 amalloy: With OSGi you can load and unload modules at runtime, you can't unload namespaces in a single classloader environment so it is useful.

4:06 amalloy: But it does require a lot of additional framework code to keep things working properly and efficiently

4:07 amalloy: Getting it to work with clojure also requires jumping through a lot of additional "hoops" but once it's functional it tends to be very stable.

4:33 daGrevis: hi! i have a vector and i want to make a hash-map from it that contains all possibilities how items can map to other items in it. like [:a :b :c] would be {:a :b, :a :c, :b :a, :b :c, :c :a, :c :b}. where do i look?

4:35 TEttinger: there may be a combinatorics lib somewhere

4:35 daGrevis: https://github.com/clojure/math.combinatorics/blob/67b2e2a38be69fa25e713594c6da74303d52042c/src/main/clojure/clojure/math/combinatorics.clj

4:35 sure

4:36 opqdonut: ,(let [v [:a :b :c]] (into {} (for [x v y v] [x y])))

4:36 clojurebot: #<CompilerException clojure.lang.ArityException: Wrong number of args (3) passed to: core/for, compiling:(NO_SOURCE_PATH:0:0)>

4:37 opqdonut: ah, right, had a weird nbsp there

4:37 ,(let [v [:a :b :c]] (for [x v y v] [x y]))

4:37 clojurebot: ([:a :a] [:a :b] [:a :c] [:b :a] [:b :b] ...)

4:37 opqdonut: anyway, maps can't have repeated keys

4:38 so you can't have {:a :b, :a :c ... }

4:38 daGrevis: ahh right

4:38 i can go for tuples in vectors then

4:38 TEttinger: you are probably after a sequence of sequences yeah

4:38 daGrevis: *vector

4:39 TEttinger: &(let [v [:a :b :c]] (for [x v y v :when (not= x y)] [x y]))

4:39 lazybot: ⇒ ([:a :b] [:a :c] [:b :a] [:b :c] [:c :a] [:c :b])

4:39 TEttinger: if you don't want :a :a

4:39 daGrevis: thanks!

4:40 any way that i can use function from math.combinatorics to look cooler?

4:40 :D

4:40 aren't these permutations?

4:42 opqdonut: nope, cartesian product

4:43 daGrevis: opqdonut, ty

5:39 hellofunk: why can you (conj {} [:k :v]) but not (conj {} '(:k :v)) ? a list satisfies seq? so wouldn't they both work?

5:46 donbonifacio: anyone sharing clj in java and js? cljx is the way to go?

6:46 hellofunk: donbonifacio a lot of people think quite highly of cljx and it seems quite stable

6:54 daGrevis: which style is more idiomatic? https://gist.github.com/30d4aba120a475ba7662

6:58 hellofunk: daGrevis having closing parens on a line by themselves us not idiomatic

6:58 *is

6:59 daGrevis: so v2 is better, right, hellofunk?

6:59 hellofunk: yes, though whether the opening outside vector is on the top line or not is a stylistic choice, but the closing should not be on its own line, creates more whitespace than most prefer to look at

7:01 daGrevis: if I put opening paren of vector on the same level as def is, my Vim indents it like this https://gist.github.com/dc420498b93e38b0e720

7:01 is it okay?

7:02 hellofunk: daGrevis: "okay" is really subjective, here. i prefer your secret santa over the others, personally.

7:07 daGrevis: hellofunk, thanks and thanks :D

7:07 hellofunk: daGrevis if your pairs-banned is really so small then i'd probably just put the whole thing on one line anyway

7:08 daGrevis: that's an possibility too

7:08 puppeh: in a bit string mutation mutation (genetic algorithm), the "probability" the chance that *one* of the digits will be flipped? or is it applied to every digit?

7:08 daGrevis: but it can change and get it bigger

7:09 hellofunk: daGrevis yes but will those changes happen due to program logic, or are they bigger at the time you define the structure initially?

7:09 daGrevis: hellofunk, people may change it by hand before script is run

7:10 is it 'by hand' or 'with hand', by the way?

7:11 TEttinger: puppeh, I could see it either way, but the generations would make the most sense if it is one bit

7:11 hellofunk: why can you (conj {} [:k :v]) but not (conj {} '(:k :v)) ? a list satisfies seq? so wouldn't they both work?

7:12 rurumate: can I give an alias to current namespace using require?

7:12 so I can refer to vars within it the same way I would from other namespaces

7:12 puppeh: TEttinger: so when Implementing such a function, which accepts a bitstring and a probability, what would that probability be about? kinda confused :S

7:13 TEttinger: it would be for ex. that at a chance of 20%, at most 1 of the bits will be flipped?

7:14 TEttinger: do you have a link to a question that you're trying to solve?

7:14 rurumate: say I have a namespace com.foo and I use it in my other namespaces like this (require '[com.foo :as foo]) (foo/bar)

7:15 and bar is also used in other functions in com.foo, is it possible to also refer to com.foo/bar as foo/bar within com.foo

7:15 puppeh: it's a code kata actually, that doesn't give much information, and I'm reading about mutation in order to understand how it works

7:15 I only have the function signature and input values

7:16 I think I've found the answer though: http://stackoverflow.com/a/5444676/1242778

7:20 TEttinger: ok, this is a bit confusing

7:21 ,(reduce #(if (= %2 42) (reduced %1) (inc %1)) (iterate #(bit-xor % (bit-shift-left 1 (rand-int 8))) 12))

7:21 clojurebot: 670

7:21 TEttinger: that works fine, but when I change to reductions to see how it did it...

7:21 ,(reductions #(if (= %2 42) (reduced %1) (inc %1)) (iterate #(bit-xor % (bit-shift-left 1 (rand-int 8))) 12))

7:21 clojurebot: (12 13 14 15 16 ...)

7:21 TEttinger: &(reductions #(if (= %2 42) (reduced %1) (inc %1)) (iterate #(bit-xor % (bit-shift-left 1 (rand-int 8))) 12))

7:21 lazybot: java.lang.ClassCastException: clojure.lang.Reduced cannot be cast to java.lang.Number

7:22 Bronsa: TEttinger reductions still doens't handle reduced

7:22 daGrevis: why isn't this working? :( https://gist.github.com/0050af6586e7f2d05e70

7:23 TEttinger: daGrevis, your #() fn accepts two args

7:23 Bronsa: daGrevis: replace [[.. ] [..]] with [..] [..]

7:23 TEttinger: but it's getting one, a collection

7:24 daGrevis: ahh, right :@

7:25 TEttinger: ,(map inc nil)

7:25 clojurebot: ()

7:25 TEttinger: <3 clojure

7:26 daGrevis: TEttinger, is that a good thing?

7:26 TEttinger: clojure treats nil as an empty seq if it ends up where it shouldn't

7:26 it counts as falsy for truthiness tests

7:28 daGrevis: TEttinger, but I mean... is that a good thing? you know, javascript treats number as string in some cases and vice-versa and it is terrible :)

7:28 TEttinger: it seems to be, nullpointerexceptions are probably more common in java than clojure

7:29 daGrevis: ahh, yes.

7:29 ,(> 42 nil)

7:29 clojurebot: #<NullPointerException java.lang.NullPointerException>

7:29 Bronsa: &*clojure-version*

7:29 lazybot: ⇒ {:major 1, :minor 7, :incremental 0, :qualifier "alpha1"}

7:29 Bronsa: TEttinger reductions supports reduced since alpha2/3

7:29 TEttinger: lol

7:30 ,*clojure-version*

7:30 clojurebot: {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}

7:30 arav93: Hi, does anybody know what miniKanren is?

7:30 TEttinger: &(clojure.string/join " " (take 40 (reductions #(if (= %2 42) (reduced %1) (inc %1)) (iterate #(bit-xor % (bit-shift-left 1 (rand-int 8))) 12))))

7:30 lazybot: ⇒ "12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51"

7:31 TEttinger: hm

7:31 broquaint: arav93: http://minikanren.org/ ?

7:32 arav93: I saw that link, but could you please tell me what it is? broquaint

7:32 TEttinger: &(clojure.string/join " " (take 40 (reductions (fn [[ctr oldval] newval] (if (= %2 42) (reduced [ctr oldval]) [(inc ctr) newval])) (iterate #(bit-xor % (bit-shift-left 1 (rand-int 8))) 12))))

7:32 lazybot: java.lang.RuntimeException: Unable to resolve symbol: %2 in this context

7:33 TEttinger: &(clojure.string/join " " (take 40 (reductions (fn [[ctr oldval] newval] (if (= newval 42) (reduced [ctr oldval]) [(inc ctr) oldval])) (iterate #(bit-xor % (bit-shift-left 1 (rand-int 8))) 12))))

7:33 lazybot: java.lang.UnsupportedOperationException: nth not supported on this type: Long

7:34 broquaint: arav93: It provides logic programming facilities, see also core.logic for clojure.

7:35 arav93: broquaint: Thanks :-)

7:35 broquaint: np

7:36 hellofunk: why does (conj {} [:k :v]) work but not (conj {} '(:k :v)) ? a list satisfies seq? so wouldn't they both work?

7:37 Bronsa: hellofunk: vectors are mapentry, seqs aren't

7:37 TEttinger: ah cool, but puppeh quit

7:37 [0 12] [1 12] [2 13] [3 141] [4 140] [5 132] [6 164] [7 180] [8 182] [9 150] [10 182] [11 166] [12 38] [13 34] [14 162] [15 170] [16 174] [17 172] [18 140] [19 136] [20 200] [21 202] [22 200] [23 202] [24 206] [25 238] [26 254] [27 222] [28 94] [29 222] [30 94] [31 86] [32 214] [33 246] [34 214] [35 246] [36 182] [37 166] [38 164] [39 36] [40 44] [41 40] [41 42]

7:37 hellofunk: Bronsa, oh I thought all maps were seqs over their keys and values Bronsa, thus any seq could also be used to go the other direction. i guess not, only vectors can become kv pairs?

7:38 Bronsa: hellofunk: correct

7:38 TEttinger: that is a sample bit mutation thing that finds 42

7:38 hellofunk: Bronsa I wonder what the reason for restricting map entry into vectors is, when the seq abstraction would seem to make more sense in general

7:39 Bronsa: actually nevermind about vectors being mapentries, the code for conj explicitely tests for IPersistentVector

7:40 hellofunk: Bronsa and since into uses conj, then making a map out of a seq, whether using conj or into, is only possible if that seq is a vector?

7:41 i guess this is possible (apply hash-map (list 1 2))

7:41 i would think conj would test not for a vector but for a seq in general

7:52 rurumate: ,*ns*

7:52 clojurebot: #<Namespace sandbox>

7:53 rurumate: ,(alias 'socks 'sandbox)

7:53 clojurebot: nil

7:53 rritoch: One step forward... two steps back... I finally have a servlet that serves clj files selected by the URL, but for some reason nothing short of restarting tomcat will update my changes, even with my src folder on the classpath

7:54 rurumate: ,d an alias in the current namespace to another

7:54 namespace. Arguments are two symbols: the alias to be used, and

7:54 the symbolic name of the target namespace. Use :as in the ns macro in preference

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

7:54 rurumate: whooops

7:54 ,(count (ns-publics *ns*))

7:54 clojurebot: 0

7:54 rurumate: ,(def a 1)

7:54 clojurebot: #'sandbox/a

7:54 rurumate: ,(count (ns-publics *ns*))

7:54 clojurebot: 1

7:55 rurumate: will the vars in public be cleared periodically?

7:55 *in sandbox

7:55 TEttinger: yes

7:55 every 10 min or something

7:56 rurumate: so it can happen that I define something and it gets cleared a second later, because there are fixed intervals?

7:57 or are the 10 minutes a real TTL of each individual var

7:58 nvm I found the source on github

8:01 ,(:status (clj-http.client/get "http://www.google.com"))

8:01 clojurebot: #<CompilerException java.lang.ClassNotFoundException: clj-http.client, compiling:(NO_SOURCE_PATH:0:0)>

8:01 rurumate: ,(require '[clj-http.client :as client])

8:01 clojurebot: #<FileNotFoundException java.io.FileNotFoundException: Could not locate clj_http/client__init.class or clj_http/client.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.>

8:41 rurumate: I just watched Tim Baldrige's "Data all the ASTs" video. Apparently ioc/state-machine now uses tools.analyzer for initial AST parsing. But then in ioc/parse-to-state-machine transforms the map-AST to a mix of maps and records. Would it be wrong to say that only some ASTs in core.async were "data'ed"?

8:43 hiredman: depends who you ask, I suspect tim would be in the camp that considers records to be data as well

8:45 rurumate: hiredman: so there are camps on this? can you elaborate what the camps disagree on?

8:46 or point to some resource

9:05 SagiCZ1: in regex, how do i match "everything until ," ?

9:06 (re-find #"match" "some-string45821:.,hello") --> "some-string45821:.,"

9:07 TEttinger: ,(re-find #".+," "some-string45821:.,hello")

9:07 clojurebot: "some-string45821:.,"

9:07 TEttinger: ,(re-find #".+," "some-string45821:.,hello,")

9:07 clojurebot: "some-string45821:.,hello,"

9:07 TEttinger: ,(re-find #".+?," "some-string45821:.,hello,")

9:07 clojurebot: "some-string45821:.,"

9:07 schrotti: greetings

9:07 TEttinger: so you want #".+?," to stop just after reaching a comma

9:07 hey schrotti

9:07 SagiCZ1: TEttinger yeah

9:07 +?

9:08 schrotti: i'm trying to create a simple tcp socket and a writer: (def socket (Socket. "hostname" 1234)) and for the writer (def out (io/writer (.getOutputStream socket)))

9:08 TEttinger: was that a question, or the actual term?

9:09 schrotti: but i get an exception: CompilerException java.lang.IllegalArgumentException: No matching method found: getOutputStream for class java.net.Socket

9:09 ok my bad :/

9:09 TEttinger: hm?

9:09 schrotti: actually had (def out (io/writer (.getOutputStream socket true)))

9:09 TEttinger: oh ok

9:09 schrotti: -true works

9:31 _segfault: Hello ! Is anybody there ?

9:32 SagiCZ1: _segfault: yup

9:32 TimMc: _segfault: There are like 500 people in the channel. I bet some of them are at their keyboards. :-)

9:33 SagiCZ1: we are not sleeping, just merely dozing

9:33 _segfault: SagiCZ1: Do use emacs ? I needed some help with respect to emacs ! :)

9:33 SagiCZ1: SagiCZ1: it's a coincidence that i don't but it seems that everyone else here does

9:33 why am i talking to myself

9:34 _segfault: TimMc: Do you use emacs ? :)

9:34 boyscared: i do. ask your question

9:34 TimMc: Actually, 750.

9:35 _segfault: boyscared: Oh thanks ! I'm on windows & and on emacs 24.3

9:35 I wanted to use monore repl

9:35 TimMc: _segfault: Just ask your question, you don't need to find someone to ask it of.

9:35 _segfault: instead of Cider

9:35 But Monroe doesnt seem to be able to connect to the repl

9:36 boyscared: i use cider, so can't help with that one

9:37 _segfault: Here's the steps : I manually start the repl (lein repl in the root of the project), switch to emacs and M-x monroe, I put in host:port and it says "Unable to Connect"

9:39 supersymmetry: I don't use emacs either.. havent had the time yet to learn :P

9:40 did you provide a host port? else the nrepl is bound to local sockets only

9:41 yeahnoob: Tools is the tool ,not the Target.

9:41 _segfault: supersymmetry: yeah !

9:41 supersymmetry: not sure if this was a remote connection or on the same machine, but that had me puzzled for a bit trying to hook up Light Table remote nrepl

9:41 kk, just checking ;)

9:49 rurumate: watching rich hickey's "Transducers" video, at 13:10 there's this example: (transduce (comp process-bag (mapping weigh-bag)) + 0 pallets)

9:49 afhammad: how do you escape characters in a string?

9:50 rurumate: shouldn't it rather be (transduce (comp (mapping weigh-bag) process-bag) + 0 pallets) ?

9:50 afhammad: same as in java?

9:51 afhammad: rurumate: i probably should be asking this on the appropriate channel but in clojurescript (str "\"") returns "\""

9:51 rurumate: also not everyone comes from java

9:52 rurumate: sorry. have you tried writing like you would in javascript?

9:52 afhammad: rurumate: in js "\"" returns """

9:53 rurumate: looks like a bug to me, but such a severe bug should have been found earlier

9:54 afhammad: rurumate: actually it looks like its a eval bug in lighttable, when i print it to the browser console its fine.

9:54 rurumate: oh, that's a different story then

9:55 afhammad: yes, i put too much trust in it

9:57 rurumate: back to transducers question

10:00 my intuition about comp would say that (comp process-bag (mapping weigh-bag)) applies process-bag to the result of (mapping weigh-bag), which would not work because (mapping weigh-bag) produces numbers, not bags

10:00 how can I test the transducers stuff?

10:01 it's not in clojure 1.6 afaik

10:01 luxbock: rurumate: is this the Strange Loop or the conj talk?

10:02 rurumate: strange loop, here's the link: https://www.youtube.com/watch?v=6mTbuzafcII&t=13m10s

10:02 luxbock: I think he talks about the ordering of transducers in comp a bit later

10:03 * rurumate grabs popcorn

10:03 luxbock: yep, at 25:31

10:03 hold onto your seat

10:03 rurumate: so when will scala get transducers

10:04 luxbock: there's https://github.com/knutwalker/transducers-scala

10:04 rurumate: this is really funny: https://www.youtube.com/watch?v=6mTbuzafcII&t=9m11s

10:05 amazing. where is this transducers idea coming from? did rich just think this up?

10:06 luxbock: I think so, in his hammock I'm sure

10:06 n0n3such: its an obvious abstraction

10:07 mavbozo: evolution of reducers

10:10 n0n3such: yeah, It takes a very unusual mind to undertake analysis of the obvious -Whitehead

10:10 clojer: Using Yesql and Cheshire to generated some JSON from a Postgres query, ip addresses are returned as :ip #<PGobject> which Cheshire doesn't like. What's the best way of dealing with these objects?

10:12 legittalon: My main editor is VIM, are there any convincing arguments for switching to Nightcode to do clojure work? I'm not entirely opposed to it. (I'm also new to clojure)

10:12 mavbozo: clojure: create custom encoder

10:12 clojer: create custom encoder for cheshire

10:12 n0n3such: “In all affairs it's a healthy thing now and then to hang a question mark on the things you have long taken for granted.”

10:12 ― Bertrand Russell

10:13 clojer: mavbozo: Ah, just noticed this at the bottom of the docs. Missed it first time round.

10:17 mavbozo: legittalon: a coworker of mine who's new to clojure and using Windows decided to use Nightcode and still going good

10:18 clojure_beginner: hello I have some trouble understandign this function http://pastebin.com/R5N2u8Ne

10:18 it's recursive. But i want to start at the let binding. It looks unusuall to me

10:19 legittalon1: I have qualms about switching to an IDE, that I'm willing to question. That and I'm stuck in a Stockholm situation with vim commands I guess I'll just try it out and see what happens.

10:20 clojure_beginner: or is the order in let binding not important is this the same (let [a [1 2 3]...) (let [ [1 2 3] a..)

10:22 i know that [x & xs] n should say like x is the head and xs is the tail of sequence n

10:22 mavbozo: legittalon1: why don't you use vim? do you find clojure integration very poor there?

10:22 clojure_beginner: but it looks weird to me.

10:22 legittalon, use fireplace plugin for vim

10:23 mavbozo: clojure_beginner: it's clojure's destructuring argument

10:24 legittalon1: Oh right, plugins!

10:24 clojure_beginner: mavbozo..Ahh, I totaly forgot about destructuring.

10:24 I've beend doing exercises on 4clojure.com and didn't have to use destructuring yet, so i forgot all about it

10:25 I didn't know zou can use destructuring in let expressions I thought only in fn arguments

10:27 mavbozo: clojure_beginner: I learn clojure through Clojure Programming book and the authors introduce destructuring through let.

10:28 rurumate: will transducers be compatible to reducers framework also?

10:29 clojure_beginner: mavbozo: I am also using this book. :) Now I need to wrap my head around recursion in this function

10:30 I think i got it now. The base clause returns empty list

10:31 and to that list the function compositions "roll out" :)

10:32 so all the work is done in the :else part

10:32 god, this thing is beutiful

10:32 But I am wondering, is it a clojure way to write recursive functions, or is this not the best practice ?

10:33 As I can see so far, you can live without recursion just fine in clojure.

10:34 rurumate: clojure_beginner: the way it's done in the example you gave is probably not idea

10:34 have a look at clojure.core/flatten

10:35 clojure_beginner: rurumate, I am aware of the flatten function, this was just an exercise from 4clojure :)

10:36 rurumate: clojure_beginner: writing a recursion can often be avoided by using map or reduce, but these use recursion internally

10:36 clojure_beginner: rurumate, could I create a flatten alternative only with for list comprehension ?

10:36 rurumate: clojure_beginner: when you find you have to recurse, consider using (recur) instead of having the function call itself by name. that way you get tail recursiveness

10:37 clojer: mavbozo: I tried: (add-encoder org.postgresql.util.PGobject encode-str)

10:37 clojure_beginner: rurumate, tnx, will do that. I heared about tail recursion not being supported on jvm

10:37 rurumate: clojure_beginner: no I don't think it can be done with for alone

10:37 clojer: mavbozo: ... but this failed: (encode org.postgresql.util.PGobject. (:ip (first (recent-logs conn "2014-09-16 00:00:00"))))

10:37 clojure_beginner: I see.

10:38 rurumate: clojure_beginner: tail recursion is just a fancy way to write a loop, which sure is supported

10:38 clojure_beginner: rurumate: Sorry I meant tail call optimisations.

10:39 rurumate: isn't that the same thing?

10:39 clojer: rurumate: I think tail call elimination is different

10:39 jaaqo: There's no tail call optimisation. Recursive functions consume stack space like mad. Provided loop/recur forms are exception, which consume static space.

10:40 rurumate: anyway just remember to try use a (recur) to avoid stack overflow. the other way to avoid stack overflow in a recursion is to use lazy-seq buiit that's kind of advanced

10:41 clojure_beginner: rurumate: Yes it's the optimisation of tail recursion, I am not a compiler guy, so I don't know much about this. It's more low level stuff, what jvm enables you and what not.

10:41 rurumate: also you don't need a loop to go with the recur. it will recurse to the (defn [...] ) above it by default

10:42 clojure_beginner: yes, so just (recur with_args_of_defn)

10:42 rurumate: yes. a good way to think about (recur) is: the compiler will make a while loop out of this. it's really not more than that. nothhing scary :D

10:43 and the compiler will tell you if it can't compile the thing into a while loop

10:44 clojure_beginner: rurumate: I know lazy seqs, that is in my opinion one of the best things in clojure i encountered so far.

10:44 rurumate: because you didn't use the (recur) in "tail position"

10:44 yes lazy seqs can be really cool

10:56 mavbozo: clojer: here's my encoder

10:56 (add-encoder org.postgresql.util.PGobject

10:56 (fn [c jsonGenerator]

10:56 (.writeString jsonGenerator (.toString c))))

10:57 (encode #<PGobject>) returns "\"\""

10:58 clojer: mavbozo: thanks. Will try it.

11:02 mavbozo: Still no luck: (encode (:ip (first (recent-logs conn "2014-09-16 00:00:00"))))

11:02 clojurebot: Excuse me?

11:02 clojer: 1. Unhandled com.fasterxml.jackson.core.JsonGenerationException Cannot JSON encode object of class: class org.postgresql.util.PGobject:

11:03 mavbozo: clojer: i have a table web_address which has column named ip

11:04 clojer: i query it (jdbc/query pgdb ["SELECT ip FROM web_address"])

11:04 clojer: returns ({:ip #<PGobject>})

11:05 clojer: suppose i def the result to a var named res (def res *1) in my repl

11:05 clojer: mavbozo: Sorry, real problem is: Unable to resolve symbol: add-encoder in this context

11:06 mavbozo: clojer: (encode (:ip (first res))) returns "\"\""

11:06 clojer: But I have this added to :require [cheshire.generate :refer [add-encoder encode-str remove-encoder]]

11:08 mavbozo: clojer: different cheshire version?

11:10 clojer: mavbozo: Required repl reboot. Working now.

11:10 mavbozo: clojer: great

11:11 sdegutis: I'm using this function in production: https://gist.github.com/sdegutis/b376cf100e337941d826

11:11 clojer: mavbozo: this simpler version now works: (add-encoder org.postgresql.util.PGobject encode-str)

11:12 mavbozo: clojer: that's greater!

11:14 sdegutis: It's very useful, it should be part of clojure.core

11:28 justin_smith: sdegutis: you should really be doing arglist matching by count. I mean that's what clojure does, matches the arglist by count.

11:28 sdegutis: justin_smith: You're right. This is a rough draft of the function, that's why it doesn't have that.

11:28 justin_smith: Once I add that in, it should be added to clojure.core for its usefulness.

11:32 clojer: Why does the Used Heap size of a dormant app gradually increase? In jvisualvm I hit "Perform GC" and Used Heap drops to next to nothing but not it's over 200MB RAM while the single page app is doing nothing, ie. dev mode on my laptop.

11:33 sdegutis: Any guesses on what https://github.com/weavejester/clofor/blob/master/src/clofor/core.clj is for yet?

11:33 clojer: Now at almost 250Mb RAM

11:33 Heap size is 1,750Mb

11:51 justin_smith: clojer: I know the jvm will ask for RAM preemptively (within its limit) so that when it needs it it can utilize it quickly

11:51 clojer: are you seeing any unexpected growth in used memory?

11:52 or only in the amount allocated/

11:53 clojer: justin_smith: I'm aware that the JVM allocates total heap size but curious as to why used heap increases when nothing is happening to the app

11:53 emacs: how do you change nick

11:54 clojer: justin_smith: I thought total heap size (orange in jvisualvm) was the pre-allocated ram?

11:54 justin_smith: clojer: look at the threads that are running. There are maintinance loops, that allocate small amounts of memory that is quickly freed. That freed memory is being put back in the pool, not freed from the app.

11:54 clojer: justin_smith: It's the increasing (blue) used heap that perplexes me

11:54 Guest34275: hey, why don't records follow the lispy syntax in examples?

11:55 justin_smith: clojer: OK. Your answer is in one of those threads, I think I misenterpreted you above.

11:55 Guest34275: what lispy syntax?

11:55 and which examples?

11:56 Guest34275: or naming convetions rather

11:56 clojer: I notice now, the blue approached the heap size limit then dropped by about 150Mb

11:56 justin_smith: Guest34275: they create objects that are usable from java

11:56 Guest34275: http://clojuredocs.org/clojure.core/defrecord

11:56 clojer: I set a 500Mb limit in this example

11:56 justin_smith: Guest34275: so they should hve names that make sense from java

11:56 Guest34275: oh, so thats why they use camelcase

11:56 justin_smith: ,(munge "my-record")

11:56 clojurebot: "my_record"

11:57 justin_smith: that's what the java class name is for my-record

11:57 Guest34275: oh yeah, java doesn't support dashes and stuff

11:57 justin_smith: right

11:57 ,(munge "my-record'")

11:57 clojurebot: "my_record_SINGLEQUOTE_"

11:57 clojer: justin_smith: 69 threads started, live: 53, live peak: 64, daemon: 8

11:57 justin_smith: I'd love to see java code accessing that :P

11:59 Guest34275: :justin_smith

11:59 sharms: /allchan chanopt confmode on

11:59 clojer: justin_smith: I was running: wrk -c 100 -d 60s -t 2 http://localhost:3000

11:59 Guest34275: justin_smith: records should be used over structs, right?

12:00 justin_smith: yeah, structs are depricated I think

12:01 clojer: oh, so wrk is what was doing it?

12:02 (well, the request handling that was spawned by wrk)

12:03 d0ky: hello how can i read file by 2 lines ? i need read file and if i find proper line i need read values from next line but im using line-seq and dont know how to get on next line in cycle ... can someone help ?

12:04 justin_smith: d0ky: maybe (partition 2 1 (line-seq src))

12:04 that gives you every pair of lines

12:04 ,(partition 2 1 (range 10))

12:04 clojurebot: ((0 1) (1 2) (2 3) (3 4) (4 5) ...)

12:04 luxbock: there's something demoralizing about solving a tough 4clojure puzzle and then seeing that all the other solutions are 1/3 as short

12:04 d0ky: (inc justin_smith)

12:04 lazybot: ⇒ 144

12:05 d0ky: thanks it works :)

12:05 justin_smith: luxbock: that's where half the learning happens :) many of my 4clojure answers are much too long

12:05 luxbock: though personally, I think the more intelligible answer is better

12:06 if only "intelligibility" had as clear a metric as "byte count"

12:06 luxbock: I have yet to come to a solution where my answer would be unique and elegant at the same time

12:07 justin_smith: luxbock: there are some extremely smart people on 4clojure, treating it as a competition may not be as productive as treating it as a chance to learn...

12:07 luxbock: yeah, I was just joking around :)

12:07 justin_smith: luxbock: I will have a sense of humor after I get my coffee, sorry :)

12:08 luxbock: it's just funny how in that moment I click to see the link for other solutions my feelings go from feeling proud to being humbled

12:08 justin_smith: it's funny, but also humility can be an important part of learning

12:10 luxbock: https://gist.github.com/luxbock/deebf89b83feaa3fa9e3

12:10 this is the one I just did

12:13 justin_smith: eww, regex

12:14 luxbock: though clearly your loop could be a reduce, and that would be much clearer

12:15 luxbock: true, at first I was toying around with having one more loop-local variable

12:16 justin_smith: luxbock: you can have a map or vec as an accumulator, in order to effectively have multiple accumulators in a reduce

12:17 luxbock: is that cleaner? I often wonder about that and end up using a loop in those cases

12:17 justin_smith: ,(reduce (fn [[o e] v] (if (even? v) [o (conj e v)] [(conj o v) e])) [[] []] (range 10))

12:17 clojurebot: [[1 3 5 7 9] [0 2 4 6 8]]

12:17 justin_smith: two accumulators

12:17 destructuring makes it work nicely

12:18 luxbock: I actually only recently learned about `reduced` from the most recent Hickey transducers talk

12:18 justin_smith: luxbock: reduced is what makes reduce a general replacement for loops that iterate across a collection

12:18 luxbock: which would make writing most of my loops as reduce-operations more appealing

12:19 justin_smith: right

12:24 luxbock: justin_smith: tried to translate this to using reduce, but got stuck with trying to get the first letter of the next grouping so use with `cmp`

12:25 justin_smith: luxbock: see my above suggestion of (partion 2 1 col) to d0ky :)

12:25 luxbock: ah hmm

12:26 justin_smith: (reduce f (partition 2 1 ...))

12:32 or, more generally (reduce f (take-while not-empty (iterate rest coll)))

12:32 ,(take-while not-empty (iterate rest (range 4)))

12:32 clojurebot: ((0 1 2 3) (1 2 3) (2 3) (3))

12:33 justin_smith: in fact, that is useful enough to give a name like rests

12:33 tails?

12:45 luxbock: pfft, finally: https://gist.github.com/luxbock/deebf89b83feaa3fa9e3

12:46 justin_smith: yeah that looks cleaner

12:47 sdegutis: $ lein repl

12:47 Retrieving org/clojure/clojure/1.3.0/clojure-1.3.0.jar from central

12:47 UHHH.....

12:48 wat

12:49 luxbock: sdegutis: you have a dependency somewhere that was written using 1.3.0, and you don't have it on your machine yet

12:49 it's not a big deal

12:49 sdegutis: Oh.

12:49 Dang.

12:49 surrealanalysis: Does anyone know if there is an easy way to pass a variable number of arguments to another function?

12:49 For example (defn function1 [a & bs] ...)

12:49 (defn function2 [a & bs]

12:49 (function1 a bs)

12:49 )

12:50 luxbock: surrealanalysis: apply works

12:51 surrealanalysis: Ah, thanks. I misread it last night, but reading it now makes more sense. Thanks

12:51 luxbock: ,(letfn [(f1 [a & bs] [a bs]) (f2 [a & bs] (apply f1 a bs))] (f2 1 2 3))

12:51 clojurebot: [1 (2 3)]

12:52 surrealanalysis: Yeah, that worked. Don't know why I missed that. Thanks again luxbock

12:52 luxbock: np :)

13:04 justin_smith: luxbock: just got back from grabbing coffee - did you forget to update the gist?

13:04 luxbock: it's there but I added it as a new file to the same gist

13:04 * justin_smith remembers how to use his scroll wheel

13:05 justin_smith: luxbock: as a minor style thing, if you know order is a hash-map by context, (order a) can be better than (get order a)

13:06 but that's something not everyone agrees on

13:06 ,(map {:a 0 :b 1 :c 2} (range))

13:06 clojurebot: (nil nil nil nil nil ...)

13:06 justin_smith: err

13:06 ,(map {0 :a 1 :b 2 :c} (range))

13:06 clojurebot: (:a :b :c nil nil ...)

13:06 luxbock: I like the explicit get

13:06 Bronsa: it's also safer.

13:07 ,((fn [a] (a :foo)) nil)

13:07 clojurebot: #<NullPointerException java.lang.NullPointerException>

13:07 justin_smith: Bronsa: the hash map is defined on the preceding line, I did mention context

13:07 Bronsa: right, I missed that

13:07 * justin_smith makes a meta-joke about context.

13:07 Bronsa: then +1 for not using get

13:08 luxbock: hmm true, here it's not so needed, but I wrote it there out of habit

13:08 justin_smith: right, it's not a correctness thing at all

13:08 luxbock: I just like to be able to tell at a glance when I'm using a function and when I'm retrieving something from a map

13:10 justin_smith: luxbock: something that changed my mind on this front was reading some higher math, where functions were defined in terms of maps

13:10 in that sense, a clojure map is more like a real function than most of our functions are

13:11 "real function" meaning "function as talked about in mathematics" here of course

13:11 luxbock: right

13:11 justin_smith: and when I say "functions were defined in terms of maps" I don't mean particular function instances, I mean the very concept of a function started with the concept of a map, and evolved from that.

13:13 luxbock: I'd definitely like to learn some more high level math, but I need a problem where I can apply it to grok it

13:13 I quit school when I was 19 so there's definitely a lot for me to learn

13:13 justin_smith: luxbock: I found my clojure experience definitely helped me with category theory

13:13 luxbock: doing the Cryptography and Machien Learning courses on Coursera helped quite a bit on that front

13:13 justin_smith: luxbock: I quit school at 18, and my last real math class was algebra II :)

13:14 luxbock: nice

13:14 justin_smith: but I was a stubborn kid who refused to learn from others, and spent a lot of time teaching myself

13:15 but recent stuff I have read about eg. cramming and memory retention makes me think I didn't have it so bad

13:16 skimmed a book three times over a course of years ~= crammed really hard, took a test, and never thought about it again

13:16 luxbock: yeah, that's why I think it's important to have a practical problem to work out with the theory for it to stick

13:17 give those ideas some neural pathways to hold on to

13:17 justin_smith: luxbock: I found the mental models for category theory very applicable to program design in general.

13:17 the general domain / mapping concepts (this is low hanging fruit in that domain, it goes so much further of course)

13:18 luxbock: I think learning some Haskell might be a good step towards that direction

13:18 justin_smith: also, it was nice to know how far haskell is from normal category theory

13:18 hehe

13:18 though maybe if I learned more of both I would see more direct connections

13:19 monoids / endofunctors were these quick asides in the ct books I found (though to be fair, functors come up a lot and are used in haskell a lot too)

13:20 luxbock: there's a functional programming course that uses Haskell that's running now on edX I believe

13:20 I'd like to take that but I'm a bit too busy at the moment, so will have to leave that for later

13:23 engblom: Haskell is one of the most nice languages you can learn. Of all languages I have coded in, I have least problem reading other peoples Haskell code.

13:24 However, there is a big problem: Cabal and hackage. The libraries are changing way to often and whatever you want to take into use by cabal and hackage might not compile because something changed.

13:24 Lein is so much more robust.

13:25 justin_smith: engblom: have you tried cabal sandboxes? I have only briefly played with them, but they seem to eliminate most of these issues (maybe all?)

13:25 engblom: agreed global installs are stupid (hell, at this point I think even shared libraries are a bad idea - RAM is cheaper to come by than my sanity)

13:25 engblom: justin_smith: No, I have not been hearing about the sandboxes. I should look it up

13:26 justin_smith: engblom: my only problem with cabal sandboxes is that they are not the only option available :)

13:26 (so far...)

13:26 engblom: it is similar to the lein paradigm, where deps are per-project, as they should be

13:32 So I am considering using a template to build the static part of a query (before getting any user input) and then using that as a prepared statement with the user input provided args following (clojure.java.jdbc/query [(build-format) user-arg-a user-b user-c])

13:32 is this reasonable?

13:33 build-format has embedded loops based on data about the table structure and the fields defined, queried from the db

13:33 (realistically it would not be called for every query)

13:34 if only sql were a query api rather than a textual language...

13:36 engblom: I have not done anything with SQL together with clojure so far... But in all other languages I have used template system. I do not know if it is good or not though. But I would probably do as you are thinking to do, justin_smith

13:39 justin_smith: engblom: thanks. I know there are a lot of pitfalls with this stuff.

13:39 (in terms of code correctness and maintainability too, not to mention security)

13:43 kenrestivo: for implementing a state machine for a network protocol, what's the current best practice? just do it all in a core.async go-loop?

13:44 justin_smith: kenrestivo: I think ztellman has a nice lib for this

13:45 engblom: He seem to have very much of useful libraries. I often stumble upon recommendations to his repositories.

13:45 kenrestivo: i fear zach's libs. every time i dive in i disappear for days trying to understand them.

13:45 engblom: Yes, documentation seem to not be the strong side for his libraries.

13:45 kenrestivo: and i eventually discover that what i was trying to do was so straightforward i could have found a much simpler alternative

13:46 justin_smith: kenrestivo: maybe one of these? https://github.com/ztellman/manifold https://github.com/ztellman/manifold

13:46 err

13:46 kenrestivo: guy's brilliant, just, i'm wary.

13:46 justin_smith: https://github.com/ztellman/lamina

13:46 kenrestivo: yeah those in particular :-P

13:46 justin_smith: hehe

13:47 kenrestivo: core.async makes sense to me. manifold makes my brain melt

13:49 engblom: A couple of week ago, as an introduction project to Clojure I made it possible to fly Flightgear with two mice. It was a simple program parsing the mouse devices and then controlling flightgear by telnet. Gloss was a good library by ztellman, but his network library (I do not remember the name) was too difficult to get working as the documentation lagged. It was easier to do in other ways.

13:52 justin_smith: engblom: thanks for the feedback on that - did you end up successfully parsing the event structures with gloss?

13:52 engblom: iirc I may have even suggested that

13:52 engblom: justin_smith: Yes, I got that fully to work. And thanks for recommending gloss!

13:53 Now I can use one mouse for ailerons and elevators and the other for rudder, if I want so.

13:53 justin_smith: sweet!

13:53 years ago I wrote a small c program so I could attach N mice, and use one mouse to control each pair of parameters in a puredata audio patch

14:11 gfredericks: lein plugin idea

14:11 `lein repl-uberjar` creates an uberjar with all your user/repl deps, and that does something similar to `lein repl` when you run it.

14:12 arrdem: hum...

14:12 not convinced that'd ever be useful

14:12 gfredericks: for running repls in contexts where leiningen is inconvenient

14:13 justin_smith: gfredericks: nice idea - doesn't the LEIN_FAST_TRAMPONOLINE option do something effectively similar?

14:13 gfredericks: I don't know what it does

14:13 justin_smith: ahh, but your idea doesn't use lein at all when run

14:13 gfredericks: exactly

14:13 justin_smith: gfredericks: https://github.com/technomancy/leiningen/wiki/Faster

14:14 "Setting the LEIN_FAST_TRAMPOLINE environment variable causes the bin/lein script to memoize all trampoline calls by saving off the java process invocation to disk upon the first run."

14:14 it means 'lein now runs really fast (until you change your project.clj)

14:14 '

14:14 luxbock: damnit, 4Clojure seems to be runnning Clojure version < 1.5

14:14 can't use reduced

14:14 justin_smith: luxbock: how about take-while and reductions?

14:15 (not as nice, admittedly)

14:15 luxbock: yeah that works, I was just excited to use reduced for the first time

14:15 justin_smith: :)

14:16 gfredericks: ,(nth (iterate reduced 42) 10)

14:16 clojurebot: #<Reduced@429664: #<Reduced@19fa96d: #<Reduced@12c3c25: #<Reduced@120a5d7: #<Reduced@67e287: #<Reduced@492e19: #<Reduced@719ebf: #<Reduced@16d0dd3: #<Reduced@a6a9d0: #<Reduced@1d6be00: 42>>>>>>>>>>

14:16 gfredericks: ^ protip

14:16 justin_smith: rofl

14:17 gfredericks: ~protipping is a marginally weirder variant of cowtipping

14:17 clojurebot: Ok.

14:17 justin_smith: &@@@@@@@@@@(nth (iterate reduced 42) 10)

14:17 lazybot: ⇒ 42

14:18 justin_smith: that @ chain tho

14:18 gfredericks: lightning talk idea: implementing church numerals with reduced

14:19 probably titled "You won't believe what this man did with clojure.core/reduced"

14:19 * gfredericks tries to remember to use linkbait next time he proposes a talk

14:20 justin_smith: & (first (drop-while reduced? (iterate deref (nth (iterate reduced 42) 10))))

14:20 lazybot: ⇒ 42

14:20 morfeen: (+ 1 1)

14:20 clojurebot: 2

14:20 morfeen: cool

14:21 gfredericks: was that a clojurebot magic trick?

14:21 justin_smith: gfredericks: repl is magic

14:21 gfredericks: (+ 1 1)

14:21 clojurebot: 2

14:21 gfredericks: (+ 1 1 1)

14:21 clojurebot: 3

14:21 gfredericks: (* 2 3 7)

14:21 clojurebot: *suffusion of yellow*

14:21 Bronsa: lol

14:22 (inc clojurebot)

14:22 lazybot: ⇒ 47

14:22 gfredericks: (+ 1 1 1 1 1 2 1 1 1 1 1 1 1)

14:22 clojurebot: *suffusion of yellow*

14:22 gfredericks: oooookay.

14:22 Bronsa: that made me laugh way too much

14:22 justin_smith: gfredericks: the urban dictionary for suffusion of yellow is actually useful and not at all obscene

14:22 imagine that

14:23 gfredericks: I was just injesting it

14:23 (- 2 50)

14:23 clojurebot: -48

14:23 gfredericks: ((fn [x] x) -3)

14:23 (- (+ 3 5) 20)

14:23 (- 2 8888888888888888888888888888888)

14:23 (- 2 8888888)

14:23 clojurebot: -8888886

14:24 gfredericks: (* 2 -3 7)

14:24 well this has been an educational experience yet again in #clojure

14:25 mavbozo: (reduced? [])

14:25 justin_smith: gfredericks: I think I showed you that super low level clojure code in the pink audio engine - the Steven Yi talk was good, and helped me make a bit more sense of all of it

14:26 mavbozo: try & or , or ##

14:26 mavbozo: ##(reduced? [])

14:26 lazybot: ⇒ false

14:26 mavbozo: &(reduced? (seq []))

14:26 lazybot: ⇒ false

14:27 justin_smith: ,(reduced? (reduced []))

14:27 clojurebot: true

14:27 justin_smith: ,(reduced? @(reduced []))

14:27 clojurebot: false

14:27 justin_smith: the deref gets the value from the reduced

14:28 @(reduced [])

14:28 ,@(reduced [])

14:28 clojurebot: []

14:28 justin_smith: ,(reduced [])

14:28 clojurebot: #<Reduced@8d9915: []>

14:28 gfredericks: justin_smith: pink? what?

14:29 mavbozo: &(reduced? 1)

14:29 lazybot: ⇒ false

14:29 kenrestivo: (tan 74)

14:29 justin_smith: gfredericks: oh, I thought I had shared it with you. pink is Steven Yi's synthesis engine, made in pure clojure. Like overtone without the external supercollider program.

14:29 kenrestivo: ##(Math/tan 74)

14:29 lazybot: ⇒ -5.737022539278999

14:31 gfredericks: justin_smith: interesting

14:31 justin_smith: gfredericks: Yi is one of the core csound devs, and pink is highly informed by that expertise

14:32 it's interesting to see super low level / real time code in clojure

14:32 (and also weird in many places)

14:37 rurumate: ,(reduce ((map inc) conj) () [1 2 3])

14:37 clojurebot: (4 3 2)

14:38 justin_smith: (inc transducers)

14:38 lazybot: ⇒ 1

15:18 sveri: Hi, how can I generate sequential uuids in clojure?

15:23 justin_smith: sveri: isn't sequential contradictory to the point of UUID?

15:23 jeremyheiler: sveri: you can use java.util.UUID and generate the bits yourself

15:24 noncom: hi! what is the current recommended clojure web stack? i want to deploy a little free webserver on heroku...

15:24 justin_smith: "Since the identifiers have a finite size, it is possible for two differing items to share the same identifier. The identifier size and generation process need to be selected so as to make this sufficiently improbable in practice. Anyone can create a UUID and use it to identify something with reasonable confidence that the same identifier will never be unintentionally created by anyone to identify something else."

15:24 sequential generation violates that

15:25 jeremyheiler: justin_smith: i think sequential for uuids means there's an order, not that the bits are incremented by one each time

15:25 for example, time based uuids give you an order so you can sort

15:25 justin_smith: jeremyheiler: ahh - new concept for me, thanks

15:28 jeremyheiler: sveri: you can also look here: http://commons.apache.org/sandbox/commons-id/uuid.html

15:28 justin_smith: np

15:33 justin_smith: I guess I was underinformed, partly because java doesn't support creating the time-sequence based uuids directly

15:33 (you can construct one from the right bits, but nothing in the java standard libs specifically generates those bits)

15:34 SagiCZ1: how do i do t his? i want it to return [true false true true]

15:34 ,(drop-while #(%) [false false false true false true true])

15:35 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn>

15:35 ambrosebs: SagiCZ1: #(%) is (fn [%] (%))

15:35 justin_smith: SagiCZ1: idenitty

15:35 SagiCZ1: ambrosebs: i know, i just didnt know how to do it

15:35 justin_smith: thanks

15:36 justin_smith: *identity, of course

15:36 SagiCZ1: ,(drop-while identity [false false false true false true true])

15:36 clojurebot: (false false false true false ...)

15:36 hyPiRion: justin_smith: isn't that the opposite?

15:36 gfredericks: ,(drop-while #(do %) [false false false true false true true])

15:36 clojurebot: (false false false true false ...)

15:36 gfredericks: ^ or for golfing

15:36 SagiCZ1: identity seems to do the opposite

15:36 hyPiRion: ,(drop-while false? [false false false true false true true]) ; is completely fine

15:36 clojurebot: (true false true true)

15:36 SagiCZ1: hyPiRion: thanks

15:37 justin_smith: (inc hyPiRion)

15:37 lazybot: ⇒ 55

15:41 gfredericks: drop-while-not-non-positive-or-twelve

16:04 andyf: Bronsa: Looking through tools.reader some more, and had some questions about possible small simplifications of code. I can file tickets if you like. These lines look like they could be removed, leaving only the ?else? part of the if: https://github.com/clojure/tools.reader/blob/master/src/main/clojure/clojure/tools/reader.clj#L159-L162

16:05 And this line looks like it is already covered by the comment reader in the ?;? key of the map ?macros?: https://github.com/clojure/tools.reader/blob/master/src/main/clojure/clojure/tools/reader.clj#L747

16:05 dang smart quotes

16:05 sveri: justin_smith: I think its nice to have semi sequential uuids like this: http://docs.datomic.com/javadoc/datomic/Peer.html#squuid%28%29

16:07 arrdem: &(java.net.uuid/Uuid. 1 1)

16:07 lazybot: java.lang.ClassNotFoundException: java.net.uuid

16:07 justin_smith: sveri: yeah, that concept was new to me

16:07 arrdem: UUID

16:07 and it's util

16:08 arrdem: &(java.util.uuid/UUID. 1 1)

16:08 lazybot: java.lang.ClassNotFoundException: java.util.uuid

16:08 arrdem: third times' a charm...

16:08 &(java.util.UUID/UUID. 1 1)

16:08 lazybot: java.lang.IllegalArgumentException: No matching method: UUID.

16:08 arrdem: fuckit

16:09 hyPiRion: ,(java.util.UUID. 1 1)

16:10 clojurebot: #uuid "00000000-0000-0001-0000-000000000001"

16:10 justin_smith: (inc hyPiRion)

16:10 lazybot: ⇒ 56

16:11 hyPiRion: Seems like I'm harvesting karma today

16:12 justin_smith: hyPiRion: you keep having the clear answer to things I try and fail at :)

16:12 Bronsa: andyf: it's possible that those are fast-paths there for performance reasons, it's been a while since I've worked on t.reader and I honestly don't remember what that does, I'll take a look though

16:13 andyf: ok. There is definitely no bug here that I've found. I can do some performance testing to see if it makes any difference.

16:14 Bronsa: andyf: looks like the comment-prefix? line can go, let's see the other one

16:15 dcunit3d: hey whats up guys

16:17 finally got irssi configured again, using the OSX Terminal app for my IRC app and iTerm for my terminal

16:18 Bronsa: andyf: yeah the read-delimited line looks like it's a microoptimization to avoid an useless unread+read, not sure if that has an actual performance impact though

16:19 andyf: The other change might be bad, according to a test case I just found, e.g. "(defn [x ;comment\n ])"

16:22 Bronsa: andyf: ah right. we can't use read there because `read` needs to read a value and read-comment doesn't return any

16:24 andyf: good to know. I won't be filing any tickets :)

16:24 well, unless it is to add test cases for things like that.

16:25 justin_smith: this Goetz talk is awesome, and gets me excited for value types

16:35 pdurbin: justin_smith: sorry, which talk?

16:36 justin_smith: brian goetz talk from the conj

16:37 https://www.youtube.com/watch?v=ADUrGfINXdI from yesterday I think

16:38 he ended with "allowing tail recursion in the vm is on the radar, is not a priority but it will happen"

16:45 andyf: arrdem: It might be nice to get another dump from ClojureDocs.org every few months or so for the parts of Grimoire that originally came from there. I don't think they have the web API set up to pull the new examples from there in an automated fashion yet. I can let you know if/when that happens.

16:46 Not sure if that was part of your plans.

16:49 arrdem: andyf: hum... that's not a bad idea but I should take a look at the legal on ClojureDocs before I continue straight up stealing their data

16:49 andyf: sure

16:49 explicit permission and/or attribution is good

16:50 arrdem: yeah. I'll throw that on the todo list for post-0.4.0, but right now getting the API and the new datastore online is the top priority

16:50 a friend of mine has a cleaned UI in the works as well

16:50 sveri: justin_smith: I like it, however, in a "normal" database you ahve id's and timestamps and maybe a UUID column, which together are some kind of a semi sequential UUID pattern

16:51 pdurbin: justin_smith: thanks!

16:53 justin_smith: sveri: we added UUID columns to caribou so that migrations that have to happen in both directions between production / staging could stay sane (we still have timestamps and incremental ids, but content going from one db to another drops the incremental id, and keeps the UUID)

16:54 sveri: if development stays active, I may even experiment with doing the joins based on UUID rather than numeric incremental id

16:58 arrdem: andyf: if you've got a minute, I realized earlier today that someday god willing Grimoire will go multi-lingual and that the lib-grimoire API should have lang in there somewhere. Commentary on where would be appreciated.

16:59 andyf: Just because thalia has a placeholder for lang in there does not mean I have thought deeply about the problem, nor have any experience with multi-lingual apps :)

16:59 arrdem: hehe

17:00 andyf: Most of my job coding work never even touches Unicode, believe it or not.

17:00 arrdem: I mean.. neither does mine. I just thought it'd be a good idea to have it in there somewhere :P

17:03 justin_smith: arrdem: easter egg idea: provide a hidden Zalgo localization option

17:04 arrdem: justin_smith: depending on when I have time to drink and work on Grimoire, text/zalgo may or may not become a supported content type

20:05 justin_smith: $ping

20:05 lazybot: justin_smith: Ping completed in 0 seconds.

20:07 kenrestivo: finally found what i was looking for http://crossclj.info/ns/com.gearswithingears/async-sockets/0.1.0/project.clj.html tho i might mod it to remove dependency on tools.logging and use timbre instead.

20:08 justin_smith: kenrestivo: timbre uses tools.logging

20:08 https://github.com/ptaoussanis/timbre/blob/master/project.clj#L28

20:09 err wait that's a test time config...

20:09 kenrestivo: yeah, i was gonna say

20:10 justin_smith: clearly that indicates they can at least coexist if they have to

20:10 kenrestivo: the disadvantage to catching exceptions in a library is then logging becomes your problem.

20:10 instead of letting the user choose which logging substrate they want to use

20:10 justin_smith: kenrestivo: the README for timbre mentions tools.logging support

20:11 kenrestivo: i vaguely remember it having the ability to use different back-ends

20:11 justin_smith: kenrestivo: that, and users deal with all sorts of insanity because they don't find out about their basic errors except through odd symptoms

20:12 kenrestivo: not sure if timbre intercepts tools.logging calls tho. will look into it. if i can avoid hacking/forking someone else's library i'll do that.

20:12 justin_smith: kenrestivo: someone was having an issue with an environment wrapper lib, and nothing was making sense until we saw a try/catch/nil hiding the fact that their config file was unparsible (and simply returning empty config, with no message)

20:12 kenrestivo: well, since timbre advertises tools.logging compatibility, I would assume you can start using timbre without removing tools.logging

20:13 kenrestivo: this crossclj is amazing though. i think i've already said that, but i'm still amazed at how useful it is.

20:13 rkneufeld_: Feel like I'm going crazy, clj-http is raising a "java.lang.IllegalStateException: Attempting to call unbound fn: #'clj-http.client/update" exception for me when I make a get. Anyone ever run into this?

20:13 justin_smith: kenrestivo: yeah, it is great

20:14 rkneufeld_: did you change your project.clj recently? that sounds like a weird interaction between compiled bytecode and a new version of a lib

20:14 rkneufeld_: can't hurt to exit, run lein clean, and run things again

20:14 rkneufeld_: justin_smith: it's certainly possible its changed since the last time I made a get. I'll clean (thanks for reminding me)

20:14 kenrestivo: +1 for lein clean. also lein deps :tree

20:15 justin_smith: yeah, that is the kind of bizarro symptom old compiled files have (calling code in it's own package that doesn't exist)

20:16 rkneufeld_: Fixed. Thanks for rubber-ducky-ing with me ;)

20:17 justin_smith: rkneufeld_: the first 10 times I dealt with that I was totally stumped

20:17 but the symptoms are very clear once you know them :)

21:42 rritoch: Is potemkin a viable alternative to gen-class to provide inheritance in clojure?c

22:01 kenrestivo: why, other than showing off use of squiggly macro-y things, would one do `(~@path :foo) instead of (-> path vec (conj :foo))

22:02 justin_smith: or (concat path [foo])

22:02 kenrestivo: even better, yeah

22:03 amalloy: kenrestivo: i don't find (-> path vec (conj :foo)) terribly easy to read

22:03 kenrestivo: i agree. (concat path [foo]) is much better

22:03 amalloy: `(~@path :foo) is pretty clear about what it's building, because it looks like what it is

22:04 (concat path [:foo]) is fine too

22:04 kenrestivo: my point is, why would one use swear characters in something like that instead of easy-to-read functions like concat?

22:05 is there some other good reason i'm missing?

22:05 amalloy: because why not? you're starting from this weird assumption that using ~@ is hard to read; from that perspective, of course using it looks dumb

22:07 kenrestivo: i just find it jarring to see splicing and unquoting occurring in places other than macros. yes it's a personal preference.

22:08 amalloy: kenrestivo: that's a fine personal preference to have, although my advice is that when there's a style that you find hard to read, the answer is to work on that, rather than to request that nobody use it

22:09 ` is a great tool for building lists, and it can sometimes yield code that's easier to read than masses of concat and vector literals

22:09 kenrestivo: wasn't requesting that. was asking if my preference is going to get me into trouble, i.e. if using the macro characters is better

22:09 amalloy: kenrestivo: not at all, except that sometimes ~@ is more readable

22:09 kenrestivo: gotcha, thanks.

22:10 amalloy: kenrestivo: after all, the reader converts `(~@x :foo) to (seq (concat x (list ':foo))) or something similar to that

22:10 ,'`(~@x :foo)

22:10 clojurebot: (clojure.core/seq (clojure.core/concat x (clojure.core/list :foo)))

22:11 yguan: Hi, there, get a question about defprotocol. How can I use deftype in another namespace? (ns this.ns (:require [nnss :refer :all])) seems not working

22:11 kenrestivo: hah, cool. it's doing the concat thing under the hood anyway.

22:11 amalloy: so you can't really be making a technical error by writing it out longhand

22:12 yguan: deftype creates a java class, which you have to import like any other java class (ie, with import)

22:12 yguan: I see, thanks, amalloy

22:16 amalloy: i wonder if it would be better for `[~x ~@y ~z] to produce something like (conj (into [x] y) z), instead of (vec (concat [x] y [z])). is there much expense in building those intermediate sequences?

22:17 presumably it doesn't matter because ` is mostly used for macros, but it looks like a free improvement for any runtime uses

22:19 i suppose vec and into aren't available early enough in the bootstrapping phase

22:21 kenrestivo: on the topic of "get better at code you find hard to read": years ago, i had trouble thinking of 'if as a statement rather than an expression: writing (f x (if foo y z)) confused me. so, i decided to make an effort to do the confusing thing myself until i had it handled. i think i actually did the same thing with using ` ~ ~@ in non-macro contexts, but i don't recall for sure

22:22 kenrestivo: thanks. macroexpand-1 is helpful, as is '. also i find it helpful when dealing with swear characters to translate them, i.e. (quote (unquote (splice x)))

22:28 still takes me extra effort to puzzle the stuff out sometimes though.

23:11 any advice for mnemonics to remember which direction <! is versus >! ? keep getting 'em confused, kind of wish they'd been called "put" and "take"

23:11 (on the topic of my mental block on special chars)

23:12 justin_smith: kenrestivo: one comes from the thing on the left, the other goes to it

23:12 think about how it looks in a let block

23:13 (let [received (<! c)] (>! recieved outc))

23:13 err I messed up the arg orders on that last one

23:13 kenrestivo: see what i mean

23:13 justin_smith: heh

23:13 I got the syms right, just not the arg order

23:14 anyway - with <! expect a binding to the left (that's where the data goes)

23:14 with >! expect a channel to the right (that's where the data goes)(

23:15 kenrestivo: ok, arrow is pointing towards or away from the channel (1st arg), that works.

23:15 justin_smith: right

23:15 it's pointing in direction of data's flow

23:15 kenrestivo: i think i need to watch the talk on swearjure in a loop until i just don't care anymore :-)

23:16 justin_smith: haha

23:23 amalloy: kenrestivo: i think of the ! as the channel, and > as drawing a picture: !> looks like taking something out of the channel, and !< like putting something into it

23:24 kenrestivo: that works too, thanks.

23:24 amalloy: although maybe it's actually >! and <!? i don't actually use core.async; my mnemonic helps me read it, not write it :P

23:25 justin_smith: amalloy: you mean >! and <! right?

23:25 heh

23:27 kenrestivo: ,(+ (*) (*))

23:27 clojurebot: 2

23:27 kenrestivo: who needs numbers. swearjure is amusing.

23:28 at some point i will seriously walk through swearjure until my aversion to weird symbols is gone

23:32 justin_smith: &@@@@@@@@@@(nth (iterate reduced 42) 10)

23:32 lazybot: ⇒ 42

23:34 kenrestivo: i saw that the other day and lol'ed

23:35 back to core.async. is there some way to check if there's anything available, without blocking?

23:35 justin_smith: speaking of usage of symbols that approach meaninglessness :)

23:35 kenrestivo: i'm thinking about a kill-chan, at the top of a go-loop, before doing things, and before recurring, that'll shut down the loop if anything is available in the kill-chan

23:35 but obviously i don't want to block.

23:36 justin_smith: kenrestivo: why not alts on a kill chan and your input at the top of the loop?

23:36 I think that's the typical way to do it

23:36 kenrestivo: i guess an alt and a channel that returns immediately would do the trick

23:40 justin_smith: a typical go loop will have input from a channel at the top anyway, so you just alt that with a poison channel... no need to make a special immediately returning channel for that to work

23:41 kenrestivo: sadly, crossclj has failed me for the first time: "No usages found for clojure.core.async/alts!"

23:49 justin_smith: yeah, we need to start submitting everything that gets used to crossclj.info

23:55 kenrestivo: oddly, i think it does spider, since my utility lib got added somehow.

Logging service provided by n01se.net