#clojure log - Apr 24 2014

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

0:04 oinksoft: akhudek: hm, ok, yea, tbh i do not like the korma structure, but i ignored that feeling

0:04 akhudek: i'll take a look at the jdbc pattern

0:25 danlamanna: maybe i have a huge hole in my understanding, i can conf/disj to a set but still need to define it somehow

0:26 TEttinger: ,(def here-you-go #{1 2 3})

0:26 clojurebot: #'sandbox/here-you-go

0:26 TEttinger: ,here-you-go

0:26 clojurebot: #{1 3 2}

0:28 danlamanna: yeah sorry - i was referring to guns' comment (a while ago) about me using def within a function when i should do some local binding

0:31 TEttinger: ,(let [set-thing #{1 2 3}] (conj set-thing 5))

0:31 clojurebot: #{1 3 2 5}

0:32 danlamanna: suppose i have a loop within that let block though, there's no way to append to that set-thing each iteration, is there?

0:33 TEttinger: do you mean the macro called loop, or something loop-like?

0:33 danlamanna: something loop-like, it happens to be doseq in this case

0:34 https://gist.github.com/11241529 to be precise, mentioned-files being the culprit

0:34 TEttinger: it seems like that's the wrong looping thing to use to me, but I'll check

0:36 yeah that won't do what you intend I think

0:36 the defs will either overwrite a global value or not overwrite anything, I can't remember which

0:37 beamso: it seems weird to use def instead of let in that code

0:37 danlamanna: it works correctly, i'm just talking in the interest of best practice

0:37 beamso: that's what i mean, let seems to be the consensus - but i don't see how since the value would be unable to be appended to each iteration

0:39 TEttinger: you can also let an atom

0:40 gtuckerkellogg: hmm, i upgraded leiningen to 2.3.4, and now it's complaining about cider-nrepl

0:40 beamso: mentioned-files could be a ref or an atom.

0:40 you could even have mentioned-files as a dynamic def outside main

0:41 danlamanna: i feel like this would be a pretty common scenario

0:42 beamso: actually, given that mentioned-files appears to be intended to be a set, you could just initialise it with all the files from --apply-options

0:44 the number of duplicates is the difference in size between what is returned from --apply-options and the size of the set

0:52 amalloy: danlamanna: the idea is to not use a for-side-effects looping construct like doseq at all

0:53 danlamanna: amalloy: i'm starting to realize that. based on http://stackoverflow.com/questions/940712/redefining-a-letd-variable-in-clojure-loop and http://en.wikibooks.org/wiki/Clojure_Programming/By_Example#Immutable_data

0:53 amalloy: instead, you reduce over files, with an accumulator that's building up a duplicates list

0:53 or mentioned files, rather

0:53 danlamanna: amalloy: these are the functional programming-esque things i'm trying to get better at.

0:54 amalloy: in your example, it's not even clear what mentioned-files is for: you only write it, never read it!

0:54 so it's hard to replace the code that builds it - why is it even there?

0:54 oh, no, it's in the when

0:54 danlamanna: amalloy: i use it to check if the file has been mentioned before

0:55 amalloy: i'm not *totally* fargone :P

0:56 gtuckerkellogg: is there a way to force leiningen to reinstall a jar?

0:56 a dependency, that is

0:57 beamso: delete the .jar and run lein deps again?

0:57 Frozenlo`: gtuckerkellogg: delete it from .m2

0:58 amalloy: danlamanna: https://gist.github.com/amalloy/11241974 is the most obvious rewrite of your main loop

0:58 gtuckerkellogg: ty.

0:59 amalloy: the function that's reducing is in charge of taking the mentioned-file list and a file, and producing a new mentioned-file list

1:00 danlamanna: amalloy: i see

1:00 amalloy: are you coming from C? (printf "%s\n" x) is a weird way to write (println x)

1:01 danlamanna: amalloy: yes

1:01 amalloy: i mean, i love printf, and find it usually much more readable than combining strings with str. but here it's a bit silly

1:01 danlamanna: amalloy: i tend to err on the side of caution, i was doing something in python the other day and it decided to print a newline for me as well

1:04 bitemyapp: arrdem: really?

1:06 TEttinger: heyy it's everybody's favorite haskell spammer

1:07 bitemyapp: TEttinger: https://twitter.com/bitemyapi

1:07 TEttinger: how goes bitemyapp

1:07 bitemyapp: TEttinger: it goes very well...typed.

1:08 TEttinger: what is that, bitemyapp?

1:08 that API

1:08 bitemyapp: I think it's a poorly tuned markov chain fed bot

1:14 amalloy: speaking of gibberish-generating bots, http://git-man-page-generator.lokaltog.net/ is pretty convincing

1:15 bbloom: amalloy: i wonder how many ppl were WTF-ing hard before he put that warning banner up

1:16 technomancy: aww--there's a banner now?

1:16 lame

1:16 that site is masterful

1:17 gtuckerkellogg: so I upgraded lein, and cider-nrepl 0.1.0-SNAPSHOT is breaking the repl even on a new project with the default template.

1:17 Has anyone else seen this?

1:18 my profiles.clj contains [cider/cider-nrepl "0.1.0-SNAPSHOT"] as a :plugin

1:21 beamso: https://github.com/clojure-emacs/cider-nrepl/issues/37

1:25 seangrove: Ahk, scoped css limits CSS to a given element, *and* its descendants. So close, yet so far...

1:26 bbloom: seangrove: yeah, that scoped thing is wildly wrong

1:27 seangrove: bbloom: Something about inmates and the asylum...

1:27 bbloom: seangrove: the DOM inherently lacks the necessary separation between a source template and the expanded result

1:27 seangrove: logical vs visual tree, etc

1:28 seangrove: bbloom: Yeah, I think about the amount of work that could be used across libraries if there were a better common denominator

1:28 bbloom: you don't want to scope to a sub tree, you want to scope to a node set by the component that produced those nodes

1:29 seangrove: Instead, the best we can do is, "store some state and styles on some dom nodes, and expect that you probably own the subtree, so you can rip it apart if you need to. If you need to share, well, good luck."

1:31 bbloom: react.js is like an assembler. it's the last reasonable stage you want to deal with, but it's still awkward and complex b/c the architecture is awkward and complex

1:32 seangrove: bbloom: If you're looking to grind your teeth http://oksoclap.com/p/P3aS4GtR2L

1:33 I'm not sure who's on this panel, but they need to have a long think about things.

1:33 bbloom: seangrove: i can't make sense of these notes & i probably don't want to

1:34 seangrove: bbloom: No, it's all just madness

1:49 beamso: do people use clojure/data.xml for xml or something else?

2:08 dissipate: does anyone know of a way to run tests in parallel?

2:12 beamso: my googling says that you can't :/

2:27 oinksoft: is there a way to call a function dynamically

2:27 like clojure.core / 'map ...

2:28 where 'map is variable

2:28 beamso: apply

2:29 oinksoft: ?

2:29 beamso: ,(max [1 2 3])

2:29 clojurebot: [1 2 3]

2:29 beamso: ,(apply max [1 2 3])

2:29 clojurebot: 3

2:29 oinksoft: ...

2:29 i want to dynamically access members in a namespace

2:29 beamso: i was just using the worked examples from http://clojuredocs.org/clojure_core/clojure.core/apply

2:30 how you get your dynamic function is up to you, but apply will let you execute that function with arguments that you give ti

2:30 *it.

2:30 oinksoft: yes, i know that

2:31 my question was about the how you get your function

2:32 let's say i want to define a function (call-in-core map - (range 10))

2:33 or (call-in-core 'map - (range 10))

2:33 the improtant part is the 'map being variable, ignore that this brekas maps being lazy

2:35 i see functions like ns-publics, but not ones to access the ns

2:35 pyrtsa: oinksoft: See resolve or ns-resolve

2:35 oinksoft: pyrtsa: thanks!

2:36 pyrtsa: They return the Var, which you can either call directly or access with @x or (deref x).

2:37 dissipate: clojurecheck hasn't been updated in 2 years. is it abandonware? https://github.com/jbondeson/clojurecheck

2:37 oinksoft: pyrtsa: this is what i needed, thanks

2:40 dissipate: nevermind, found test.check

2:40 https://github.com/clojure/test.check

2:51 oinksoft: lack of pattern matching is a pain when writing an api

2:51 what do you do?

2:51 beamso: pattern matching?

2:52 oinksoft: it's easier to munge this stuff in a lang like python, but in a functional language guards and real pattern matching like in erlang are nice

2:52 i'm not sure how to avoid writing lots of -type variants

2:53 (foo 1 2) ... (foo-with-vec 1 [2 3])

2:53 because of the restirction on mutliple overloads w/ same arity

2:54 noidi: oinksoft, have you tried https://github.com/clojure/core.match and https://github.com/jamii/strucjure ?

2:54 oinksoft: doing (if (vector? 2nd-param ... seems ugggly

2:56 noidi: yea but seems like lipstick on a pig for simple type switching

2:56 noidi: you would have to do (match [(vector? arg2)] [true] ... [false ....

2:56 akhudek: oinksoft: you could look at multimethods

2:57 oinksoft: yea, i just wish there were a less verbose way :( that is probably the cleanest, thanks!

3:11 wunki: how would I catch an error based on the `:type` supplied here: https://github.com/Prismatic/fnhouse/blob/master/src/fnhouse/middleware.clj#L55-L63

3:17 ivan: wunki: maybe https://github.com/fredericksgary/catch-data but haven't tried this

3:19 or just use a single catch block and use (ex-data e) to decide what to do

3:23 badlambda: I have implemented Donald Knuth's algorithm X in Clojure. I am looking to improve on my implementation and value your feedback. https://www.refheap.com/79579

3:29 sm0ke: sounds like a sales pitch

3:39 wunki: ivan: thanks, will try `ex-data`!

3:40 Glenjamin: wunki: you might be able to use slingshot - although i'm unsure if that works on generic ex-info calls

3:40 dbasch: badlambda: it looks like your code would be cleaner if you were using 1s and 0s instead of true/false

3:41 wunki: Glenjamin: I tried using slingshot, but wasn't able to get it to work

3:41 Glenjamin: but that's probably my incompetence

3:41 dbasch: badlambda: also, (range 0 n) = (range n)

3:43 badlambda: get-indices-where-true should be implemented with for

3:46 badlambda: (if (nil? something) nill some-code) = (when-not something some-code)

3:51 badlambda: if you’re removing things at specific locations, look into using vectors instead of lists

3:51 badlambda: there’s little reason to use pure lists. Check out subvec

3:53 clgv: badlambda: you got a lot of nested maps there. you should break them up in several functions or at least use threading via ->> and some comments in-between

3:55 badlambda: (if (nil? x) nil (something ...)) is better written as (when x (something ...))

3:56 dbasch: badlambda: more importantly, your code doesn’t compile :)

4:02 badlambda: (filter #(not (in? % l2)) l1) = (remove #(in? % l2) l1)

4:05 rolfb: are there any exciting ways to use #() to build an anonomyous function and make it recursive?

4:06 clgv: rolfb: no. you need to use the verbose form

4:07 rolf: oh wait. recur should work^^

4:07 rolfb: clgv: checking

4:08 clgv: ,(#(if (zero? %1) %2 (recur (dec %1) (* %1 %2))) 5 1)

4:08 clojurebot: 120

4:08 clgv: rolfb: factorial ^^

4:08 rolfb: % and %1 is the same?

4:08 clgv: yes

4:08 rolfb: clgv: where can i read up on syntatic sugars like % in short form?

4:08 clgv: use %1 if you have more than one param

4:09 rolfb: I guess most books should include it. some info is here as well http://clojure.org/reader

4:10 rolfb: clgv: perfect, thanks

4:14 dbasch: ,(#(recur))

4:14 clojurebot: Execution Timed Out

4:14 clgv: dbasch: bad boy ;)

4:14 dbasch: :)

4:14 clgv: clojurebot: poor bot. botsnack!

4:14 clojurebot: Pardon?

4:15 clgv: clojurebot: botsnack

4:15 clojurebot: thanks; that was delicious. (nom nom nom)

4:16 locks: snacks won’t save you come the skynet revolution

4:19 rolfb: locks, you are everywhere

4:20 locks: rolfb: it’s part of my “learn by osmosis” approach. so far haven’t had much success.

4:20 rolfb: locks: smart, i'm trying learn by 4clojure and asphyr

4:20 seems to be working ok

4:21 locks: asphyr?

4:21 rolfb: aphyr

4:21 sorry

4:21 http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome

4:22 locks: oh

4:22 I did a chunk of 4clojure too, and I have joy of clojure on my kindle

4:22 rolfb: haven't gotten to joy of clojure yet as the back says you need some familiarity with clojure before reading it

4:22 locks: curiously, I’m watching this https://www.youtube.com/watch?v=XeWP60DK6O0&feature=youtube_gdata

4:23 rolfb: interesting, thanks

4:23 locks: related to aphyr; https://twitter.com/fogus/status/459015590112681984

4:23 locks: JOY’s pacing isn’t a walk in the park, for sure

4:23 I saw it, I’m following fogus :]

4:24 rolfb: i'm at problem 39 in 4clojure, but feeling a tiny bit stuck on a good way to solve it

4:24 clgv: a student of mine said that he learned much faster with "programming clojure (2nd edition)" than with "clojure programming (O'Reilly)"

4:25 rolfb: clgv; oh really? i started the latter one

4:25 locks: those titles aren’t confusing at all

4:26 rolfb: holloway vs emerick?

4:26 clgv: right

4:26 locks: speaking of, I also got this http://shop.oreilly.com/product/0636920030409.do?intcmp=il-prog-books-videos-cat-intsrch_clojure_ct

4:27 clgv: oh whats that?

4:27 rolfb: halloway, not holloway

4:28 locks: it’s kind of the video equivalent to JOY

4:28 rolfb: locks, interesting as well :)

4:28 locks: they blitz through the hows and whys of clojure

4:32 rolfb: is there a way to pretty print vectors and such in the repl?

4:33 like in APL

4:33 *ducks*

4:33 clgv: clojure.pprint/pprint is a built-in function to do that

4:33 pretty printing I mean, dont know about APL ;)

4:34 rolfb: (clojure.pprint/pprint (vector [1 2 3] [:a :b :c])) doesn't do much in terms of formatting

4:35 * rolfb it

4:35 rolfb: whoops

4:35 clgv: rolfb: maybe I did not understand what you mean. do you mean something like clojure.core/format?

4:35 rolfb: clgv; i would love to get ... the above to print like

4:35 [[1 2 3]

4:36 [:a :b :c]]

4:36 on two lines

4:36 that's what I feel is a pretty print

4:41 noidi: rolfb, http://richhickey.github.io/clojure/clojure.pprint-api.html#clojure.pprint/*print-right-margin*

4:41 http://richhickey.github.io/clojure/clojure.pprint-api.html#clojure.pprint/*print-miser-width*

4:53 rolfb: noidi; thanks

5:18 badlambda: clgv, dbasch: thanks for the feedback

5:53 irctc_: hey.... can anyone help me ny telling how to hide a properties file in clojure

5:54 i am using leiningen framework for my clojure web application and there is no private folder.. where to keep the properties file??

5:54 lazybot: irctc_: Definitely not.

6:15 clgv: irctc_: what do you want to do? what is "hiding" supposed to mean in this context? what is you reason to "hide" that file?

6:22 sm0ke: :D

6:23 clgv: lazybot: you'd ask the same, right???

6:23 lazybot: clgv: How could that be wrong?

6:23 sm0ke: may be he is packaging passwords with code, interesting question though

6:23 irctc_: you can not hide it but you can obfuscate it

6:24 DRM sucks brother, nothing will be hidden ultimately

6:31 clgv: sm0ke: yeah, I also think that he want to package passwords or something similar...

6:33 sm0ke: now wonder there is no "licencing" frameworks

6:33 at least i havent seen any

6:36 rolfb: ,(format "testing")

6:36 clojurebot: "testing"

6:40 sm0ke: ,(prn \♥)

6:40 clojurebot: \♥\n

6:40 sm0ke: hmm

6:40 ,(prn "♥")

6:40 clojurebot: "♥"\n

6:40 sm0ke: ,(pr \1)

6:40 clojurebot: \1

6:41 clgv: (char "♥")

6:41 ,(char "♥")

6:41 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>

6:41 clgv: ,(map char "♥")

6:41 clojurebot: (\♥)

6:41 clgv: lol^^

6:42 ,(-> "♥" first long)

6:42 clojurebot: 9829

6:42 sm0ke: ,'

6:42 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

6:42 sm0ke: ugh

6:42 ,(pr '♥)

6:42 clojurebot:

6:43 sm0ke: yes!

6:43 clgv: clojurebot: smoke |is| ♥

6:43 clojurebot: Alles klar

6:43 sm0ke: hmm weird, ##(defn ♥ [] (pr '♥))

6:43 lazybot: java.lang.SecurityException: You tripped the alarm! def is bad!

6:43 clgv: oops ;)

6:44 clojurebot: sm0ke |is| ♥

6:44 clojurebot: Alles klar

6:44 clgv: sm0ke?

6:44 clojurebot: sm0ke is smoke

6:44 rolfb: def is bad?

6:44 clgv: weird

6:44 sm0ke: hmm weird, ##(defn foo [] (pr '♥))

6:44 lazybot: java.lang.SecurityException: You tripped the alarm! def is bad!

6:44 clgv: rolfb: for lazybot yes ;)

6:44 sm0ke: wth is wrong

6:44 clgv: ,(defn ♥ [] (pr '♥))

6:44 clojurebot: #'sandbox/♥

6:44 sm0ke: ,(♥)

6:44 clojurebot:

6:44 clgv: ,(♥)

6:44 clojurebot:

6:44 clgv: ^^

6:45 rolfb: interesting

6:45 jballanc: clgv: doesn't clojurebot take a while to learn something new?

6:45 sm0ke: wow clojure is nice

6:45 clgv: clojurebot is more liberal ;)

6:45 jballanc: clojurebot: sm0ke |is| ♥

6:45 clojurebot: In Ordnung

6:45 clgv: jballanc: no it should associate that immediately

6:45 sm0ke?

6:45 jballanc: sm0ke?

6:45 clojurebot: sm0ke is ♥

6:45 sm0ke is </3

6:45 jballanc: :P

6:45 clgv: roflmao

6:46 sm0ke: weird

6:46 clgv: it seems to pick facts randomly now?

6:46 owl-v-: ,()

6:46 luxbock: need some help with a macro: https://gist.github.com/luxbock/11249913

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

6:46 jballanc: oh, I was under the impression he had some elementary ML implementation

6:46 owl-v-: ,

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

6:46 clgv: jballanc: not that I know.

6:46 sm0ke: ML is a heavy term

6:46 jballanc: owl-v-: that character is a weird spot in the unicode plane

6:46 luxbock: why does the macro return the gensym'd symbol name when I use it with map?

6:47 sm0ke: clojurebot: |is| |is| equality

6:47 clojurebot: excusez-moi

6:47 owl-v-:

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

6:47 sm0ke: ,'π

6:47 clojurebot: π

6:48 owl-v-: ,'

6:48 clojurebot:

6:48 owl-v-: :)

6:48 wink: ,(def π 3.14)

6:48 clojurebot: #'sandbox/π

6:48 clgv: luxbock: because %1 and %2 are gensyms

6:48 owl-v-:

6:48 clojurebot: 3.14

6:48 clgv: luxbock: you can not map macros

6:48 owl-v-: :)

6:48 clgv: at least not as you intended

6:48 sm0ke: clojurebot: π |is| 3.14

6:48 luxbock: hmm ok

6:48 clojurebot: You don't have to tell me twice.

6:49 owl-v-: lol

6:49 sm0ke: clojurebot: π?

6:49 clojurebot: π is 3.14

6:49 sm0ke: clojurebot: pi |is| π

6:49 clojurebot: Ack. Ack.

6:49 sm0ke: clojurebot: pi?

6:49 clojurebot: pi is 3.14

6:49 sm0ke: whoa!

6:49 owl-v-: clojurebot: :smart?

6:49 clojurebot: excusez-moi

6:50 owl-v-: clojurebot: clojurebot |is| :french

6:50 clojurebot: Roger.

6:50 clgv: luxbock: you can use 'map at macroexpansion time within a macro to reach that goal

6:51 clojurebot: are you tired of all these requests??

6:51 lazybot: clgv: What are you, crazy? Of course not!

6:51 clojurebot: Titim gan éirí ort.

6:51 luxbock: clgv: can you elaborate on how that would work?

6:51 clgv: oops wrong bot :D

6:52 luxbock: I have a list of numbers of whose values I don't know beforehand, and I'd like to generate a function from each of them and store that to be used later

6:52 so I could just use anonymous functions, but I think it would be cleaner if every function would get its name from the number it was created from

6:52 clgv: luxbock: use something similar to `(do ~@(map (fn [a b] `(fundef ~a ~b)) ...))

6:53 ssideris: how about storing them in a map with the keys being the numbers

6:53 luxbock: ok, so in this case I would have one macro for creating the function, and then another macro that calls the other macro on a collection?

6:54 ssideris: when do you get access to the numbers? at runtime?

6:54 clgv: yeah one macro to generate multiple definitions with the definition macro

6:54 luxbock: yeah, at runtime

6:54 ssideris: macros run at compile time

6:54 clgv: but if you do not know the values at compiletime that wont work

6:55 luxbock: my heuristic tells me that you are on the wron path

6:55 luxbock: err, actually I get to access them at compile time, as in they are defined in the code

6:55 hehe it's quite possible, my initial approach was much simpler but then I got stuck trying to figure this out as a puzzle

6:55 clgv: luxbock: cant you use partial at runtime?

6:56 luxbock: well here's what I'm trying to do: I'm generating a game-tree from a set of rules which are stored in a nested map

6:56 so inside this nested map are a list of numbers which represent allowed bet-sizes in the game

6:57 so at first I had them be just numbers, but then I thought since all the bet sizes are used with in realtion to the size of a pot at some point in the game, then I could just make them functions that take the pot size as the argument and return the bet-size

6:58 but it might be better to have them be just numbers and have a separate function that calculates the bet size for a given pot size

6:58 I often end up over thinking these things

6:59 clgv: luxbock: choose the simplest approach ;)

7:26 kras: ,(tree-seq coll? #(if (false? %) '() (identity %)) [1 2 [3 4 false]])

7:26 clojurebot: ([1 2 [3 4 false]] 1 2 [3 4 false] 3 ...)

7:26 kras: Hi help with the above

7:27 I am expecting it to insert '() as a child node wherever there is false

7:28 clgv: kras: tree-seq returns a seq and not a tree. you need something like clojure.walk/prewalk

7:28 kras: clgv: I just need a seq but the children function is inserting a '() for false

7:29 that is not happening

7:29 ,(doc tree-seq)

7:29 clojurebot: "([branch? children root]); Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). children must be a fn of one arg that returns a sequence of the children. Will only be called on nodes for which branch? returns true. Root is the root node of the tree."

7:29 kras: pasting it with a shorter input

7:29 clgv: kras: well an empty list of children wont occur in the seq ;)

7:29 kras: ,(tree-seq coll? #(if (false? %) '() (identity %)) [3 4 false])

7:30 clojurebot: ([3 4 false] 3 4 false)

7:30 clgv: kras: try '(())

7:30 ,(tree-seq coll? #(if (false? %) '(()) (identity %)) [1 2 [3 4 false]])

7:30 clojurebot: ([1 2 [3 4 false]] 1 2 [3 4 false] 3 ...)

7:30 clgv: ah lol "false" has no children

7:30 since it is not a collection due to "coll?"

7:31 why dont you just map over the seq after it is constructed to replace those false values?

7:32 ,(map #(if (false? %) '() %) (tree-seq coll? #(if (false? %) '(()) (identity %)) [1 2 [3 4 false]]))

7:32 clojurebot: ([1 2 [3 4 false]] 1 2 [3 4 false] 3 ...)

7:32 kras: I could do that but thought if it works it would be elegant

7:33 clgv: ,(map #(if (false? %) '() %) (tree-seq coll? seq [1 2 [3 4 false]]))

7:33 clojurebot: ([1 2 [3 4 false]] 1 2 [3 4 false] 3 ...)

7:33 kras: ,(map #(if (false? %) '() %) (tree-seq coll? seq [3 4 false]))

7:33 clojurebot: ([3 4 false] 3 4 ())

7:34 clgv: kras: in this case it is only complicated to integrate it

7:34 kras: yeah this is what I need but still can't understand why the children function is not working

7:42 okay got it now

7:43 ,(tree-seq coll? (fn [x] (map #(if (false? %) '() (identity %)) x)) [3 4 false])

7:43 clojurebot: ([3 4 false] 3 4 ())

7:44 gfredericks: ,(tree-seq coll? (partial map #(if (false %) () %)) [3 4 false])

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

7:45 gfredericks: ,(tree-seq coll? (partial map #(if (false? %) () %)) [3 4 false])

7:45 clojurebot: ([3 4 false] 3 4 ())

7:47 kras: gfredericks: I tried with partial but switched back to fn

7:47 but after seeing this its more readable

7:50 clgv: kras: the children function is only called on data the returned true for branch?

7:51 ,(coll? false)

7:51 clojurebot: false

7:52 clgv: ;)

7:52 kras: clgv: yep I realized it and modified it above

8:21 wunki: I'm doing something wrong with destructuring an Exception with slingshot. Anyone see what it is? https://gist.github.com/wunki/11252574

8:31 or does slingshot not deal with `ex-info` exception, only with it's own `throw+`

8:38 pjstadig: wunki: hmm i thought it handled ex-info, too, but i don't see anything particularly wrong with your code

8:39 wunki: do you have control over the code that throws? could it just use throw+ instead?

8:40 ah https://github.com/scgilardi/slingshot/issues/35

8:40 ^wunki

8:41 wunki: pjstadig: thanks, great find

8:41 pjstadig: will resort to basic catch all exception and destructure it with `ex-data`

8:41 pjstadig: yeah that should work

8:43 wunki: pjstadig: result (works!) https://gist.github.com/wunki/11253195

8:43 pjstadig: wunki: cool! though it might be a tad safer to catch ExceptionInfo instead of Exception

8:44 i mean i guess ex-data returns nil for non ExceptionInfo exceptions so maybe that comports with the behavior you want

8:44 clgv: wunki: well now you can steal the slingshot code to write your own try+ that deals with exceptioninfo in a similar concise way ;)

8:45 mpenet: https://github.com/fredericksgary/catch-data is nice

8:45 simpler

8:45 clgv: mpenet: ah well that gfredericks guy did that already ;)

8:46 mpenet: :)

8:47 clgv: but why not patch the slingshot library?

8:47 pjstadig: slingshot predates ex-info, so it may be that a simpler lib based on ex-info is in order

8:48 hadn't heard of catch-data

8:48 clgv: a patch could still be sent to slingshot

8:48 clgv: well you could simply use ex-info when it is available and otherwise slingshot.ExceptionInfo

8:49 pjstadig: sure, but if you're writing new code why not use ex-info?

8:49 clgv: did I suggest that?

8:50 pjstadig: looks to me as if slingshot is the parent of exceptioninfo looking at the source of both

8:51 I wonder why Clojure did not add more support for ex-info in terms of catching ^^

8:51 pjstadig: it is now since ex-info is available on clojure 1.3+ (i think?)

8:51 clgv: 1.4

8:54 gfredericks: clgv: github.com/fredericksgary/catch-data

8:55 mpenet: gfredericks: I beat you to it :) still a fan btw

8:55 clgv: gfredericks: yes, that was the reason for my comment ;)

8:56 gfredericks: oh ha

8:56 apparently I didn't scroll up very far :)

8:56 clgv: happens to all of use ;)

8:57 gfredericks: btw is there an error in the Readme? I'd expected :ex on the right side "{bar :foo, :ex the-exception}"

8:57 gfredericks: nope!

8:58 it's analogous to :keys, :as, and other special destructuring things

8:58 * gfredericks felt terribly clever when he realized it could be done that way

8:58 clgv: oh. not so intuitive since there is no vector or something similar to hint that

8:59 gfredericks: yeah, I'm not sure how I feel about vectors for single bindings

8:59 ssideris: deciding on the syntax of macros is one of the hardest problems in lisps I think

8:59 gfredericks: I wonder how many data points we could find on existing macros

8:59 compojure is +vector

8:59 well nevermind

9:00 clgv: gfredericks: no I did not want to suggest adding a vector. it's just the thing that distinguish :keys syntax from usual bindings and it's missing there ;)

9:00 gfredericks: clgv: ooh you mean _inside_ the map?

9:00 :as isn't followed by a vector

9:01 clgv: gfredericks: humm right. why not use :as here? ;)

9:02 distinction between content map and exception?

9:02 gfredericks: right

9:02 you can still use :as, you just get the map

9:03 the trouble is that for most use cases you just care about the map, but only making the map available for binding makes it impossible to get the actual exception when you need it

9:03 hey I could add more destructuring keys for msg, cause, etc :) that'd be...obnoxious?

9:05 clgv: gfredericks: :cause would be awe some. saves you getting the exception via :ea and cal .getCause on it

9:06 maybe :message as well

9:07 maybe we should a ticket to Jira to get this into core ;)

9:07 mpenet: +1

9:13 gfredericks: the weakest reason to put something in core is "I don't want to bother getting it from a library"

9:13 and I think that's all that applies here

9:15 wink: include ALL the batteries</meme>

9:15 ssideris: what's a good reason to put something in core?

9:16 wink: if it gets reimplemented on a daily base and is non-composable with a low number of builtins, imo

9:17 ssideris: in that case, I find it weird that we don't have a map-keys and a map-vals in core

9:20 stuartsierra: ssideris: I've brought it up, along with other stuff from the old contrib library map-utils.

9:21 ssideris: stuartsierra: oh great, thanks :-)

9:21 stuartsierra: No promises though.:-)

9:22 ssideris: I understand, and it's good that it's hard to introduce new things into core

9:22 mpenet: I never had the need for these personnaly, when it's a comp+2args away... same goes for filter+first, I think it got rejected a few times as well

9:22 catch-data is a bit more subtile imho

9:23 ssideris: mpenet: so how do you implement "map-keys"?

9:23 stuartsierra: Yeah, I loop over maps with reduce-kv. The one I'm more interested in is deep-merge.

9:24 mpenet: ssideris: if you mean something that preserves the map type reduce-kw, if proper map (comp map keys). in anyway it's stuff that maybe is not worth growing core (which is quite huge already)

9:25 reduce-kv*

9:25 I guess spliting core in many namespaces couldn't hurt one day... hopefully

9:28 ssideris: sorry for being slow, could you give me a quick example of how to use reduce-kv for transforming the keys of a map?

9:29 Bronsa: ssideris: (reduce-kv (fn [m k v] (assoc m (f k) v)) {} the-map)

9:29 mpenet: ,(reduce-kv (fn [m k v] (assoc m (str k) v)) {} {:a 1 :b 2})

9:29 clojurebot: {":a" 1, ":b" 2}

9:29 stuartsierra: ,(reduce-kv (fn [m k v] (assoc m (str k) v)) {} {:a 1 :b 2})

9:29 clojurebot: {":a" 1, ":b" 2}

9:29 stuartsierra: mpenet: Ha! We wrote the same example.

9:29 ssideris: thanks a lot!

9:29 mpenet: :)

9:29 hyPiRion: great minds think alike

9:30 stuartsierra: And so do we.

9:30 mpenet: we should make a wish now I guess

9:33 kras: is tree-seq overkill for 4clojure #95

9:33 http://pastebin.com/mdEGU3tQ

9:33 checking for binary-tree?

9:57 clgv: kree: yeah

9:58 kree: a recursive function suffices

10:19 zeeshanlakhani: reiddraper: around for a quick test.check q?

10:19 or anyone really, working w/ test.check

10:20 hyPiRion: zeeshanlakhani: go ahead

10:21 zeeshanlakhani: what would be the best approach compose two separate generators of gen/elements

10:21 being the same type of data

10:21 was trying to use gen/bind to make a new gen of the combined elements

10:22 hyPiRion: zeeshanlakhani: (gen/one-of [first-gen second-gen]) would create a new generator which uses the first gen 50% of the time, second gen 50% of the time

10:23 zeeshanlakhani: ah, right, duh on my part

10:23 hyPiRion: you could also use gen/frequency if you want to scew the probabilities

10:23 zeeshanlakhani: one-of right on, derp, thanks hyPiRion

10:23 hyPiRion: np

10:23 zeeshanlakhani: yeah, i was about to go that route, but one-of should suffice

10:26 sandbags: I'm trying to use CLJX at the function level, I assumed the annotation worked at the s-exp level (like #_) but my .clj file ends up with the #+cljs (defn ...) in it, do I have this wrong somehow? The docs are a bit vague on how #+xxx operates

10:28 for ref, this is what I have https://gist.github.com/mmower/a43b150391d74f5af421

10:29 i'd expect only one of the functions to appear in the resulting .clj/.cljs files

10:31 ack... unbalanced parens

10:31 works fine

10:39 dabbelingincloju: hello, i have a simple question I want to write a function which gives me the most frequent strings out of a given string

10:40 cbp: the most frequent substrings?

10:41 dabbelingincloju: yes

10:42 this is what I got so far : (defn topten [x] ((map count (map val (group-by identity (clojure.string/split x #"\s+"))))))

10:42 CookedGryphon: dabbelingincloju: have you seen the function frequencies?

10:43 cbp: oh separated by spaces

10:43 so the most common words?

10:43 dabbelingincloju: yes exactly

10:43 cbp: just split them and then use frequencies then

10:43 xsyn: isn't that exactly frequencies

10:43 dabbelingincloju: ha

10:43 ok

10:46 ashish: hello is there is any method to read file without given relative path

10:47 CookedGryphon: ashish: ... you'll have to be more specific, what path *do* you have?

10:51 gwz: hey does clojure allow unrestricted mutation

10:52 hyPiRion: gwz: as unrestricted as you can be in Java, but it's pretty clumsy to do so in Clojure.

10:53 It's easier to be immutable by design

11:08 dabbelingincloju: found a nice one

11:08 (defn map-count [amap key] (assoc amap key (inc (get amap key 0))))

11:11 devn: ,(defn foo-agent [x] (agent (-> 1 inc inc)))

11:11 clojurebot: #'sandbox/foo-agent

11:13 luxbock: is there a better way to do this: (fn one-two-or-three [x] (some #{:one :two :three} [x]))?

11:13 devn: ,(foo-agent 'whatever)

11:13 clojurebot: #<Agent@1ec9818: 3>

11:14 devn: ,(#{:one :two :three} [:x :one :y :z])

11:14 clojurebot: nil

11:14 devn: derp

11:14 luxbock: I'm looking to test just one variable

11:14 devn: short answer, no

11:14 what you're doing looks good

11:14 luxbock: k, thanks

11:22 mzarella: Has anyone here played with promises within node.js? Has your code become unruly? If not, how did you get around it!

11:26 arrdem: mzarella: wrong chan?

11:27 mzarella: I guess, I'm looking at clojure's away of handling async and it's appealing

11:30 yedi: wut, what is this datomicscript foolishness

11:30 gtrak: mzarella: yes

11:31 yedi: (after reading some) whoa that is sweet

11:34 arrdem: yedi: lunk?

11:38 Mandar: arrdem, http://tonsky.me/blog/decomposing-web-app-development/

11:46 tolitius: is there a name convention for lein template arguments? just upgraded to lein 2.3.4, and I see it brought this commit along: https://github.com/technomancy/leiningen/commit/c575b7b82b0d0fc8a5de2168f81679aa0f685d8a#diff-d9b21eee7e79dbee2062d1cae55d8a74 which will ignore template arguments that start with ":". before I could do "lein new [template name] [project name] :with-xyz", where ":with-xyz" was treated as an argument, but

11:51 justin_smith: but...

12:02 tolitius: did not realize I lost connection in the middle of the sentence… talking about network partitions :)

12:02 so here it is in full:

12:02 is there a name convention for lein template arguments? just upgraded to lein 2.3.4, and I see it brought this commit along: https://github.com/technomancy/leiningen/commit/c575b7b82b0d0fc8a5de2168f81679aa0f685d8a#diff-d9b21eee7e79dbee2062d1cae55d8a74 which will ignore template arguments that start with ":". before I could do "lein new [template name] [project name] :with-xyz", where ":with-xyz" was treated as an argument, but

12:03 clgv: haha

12:03 justin_smith: but...

12:03 tolitius: I think you need to either link to a pastebin or break it up into smaller sentences

12:04 tolitius: shoot, ok, let's refactor then

12:04 is there a name convention for lein template arguments? just upgraded to lein 2.3.4, and I see it brought this commit along: https://github.com/technomancy/leiningen/commit/c575b7b82b0d0fc8a5de2168f81679aa0f685d8a#diff-d9b21eee7e79dbee2062d1cae55d8a74 which will ignore template arguments that start with ":".

12:04 before I could do "lein new [template name] [project name] :with-xyz", where ":with-xyz" was treated as an argument, but now  neither "--with-xyz" nor ":with-xyz" are good, is there a convention? should it be just: "lein new [template name] [project name] with-xyz"?

12:05 justin_smith: tolitius: I think templates have free reign on how they interpret the arguments they see

12:05 that said, you need to provide arguments in such a way that the template ends up seeing them

12:05 nDuff: While core.async has a few dropping channel types, I'd ideally like to have a channel where I can fail rather than blocking or dropping data when the buffer is full. (Alternately, dropping data and setting a flag would work too). Will I be building this myself, or are any of y'all aware of such a thing existing?

12:06 justin_smith: templates have the full power of clojure, to interpret your "new" request plus args however they like

12:06 tolitius: justin_smith: yes, besides when the args start from "--" and now ":"

12:06 hence just wanted to check what else is coming..

12:07 or there is a convention to not use prefixes at all..

12:07 justin_smith: I don't see why you would need prefixes

12:07 though something like key:value or key=value seems intuitive enough, and easy to parse

12:08 but I am not a lein dev, they may have more nuanced advice

12:08 (and they are on this channel)

12:08 * justin_smith flashes the technomancy signal.

12:08 tolitius: well, usually options intuitively are provided with ":" e.g. you-app :with-something

12:09 justin_smith: I would not have intuited that, personally

12:09 tolitius: but in this case there is a collision of options for lein new vs. options for a template

12:16 technomancy: tolitius: we intercept a few things but the intent is that everything the new task doesn't use itself gets passed to the template function.

12:16 tolitius: it sounds like that's not happening in your case?

12:18 tolitius: technomancy: yea, I think what happens it just treats ":template-arg-1" as a "lein new" options vs. a custom template option

12:19 technomancy: could you open a bug report?

12:19 that logic is really awful iirc; kind of regretting having lein new take args itself

12:19 tolitius: and does not pass it along to (defn "template name" …. )

12:19 technomancy: sure, will do

12:40 yedi_: in secretary, is there a way to trigger the history on some state changes / routes, but not on others?

12:47 coventry`: nDuff: I don't know of such a thing, but custom buffers aren't too mysterious. Check out async/impl/buffers.clj

13:08 dnolen_: big changes landed in Om 0.6.1, please test https://groups.google.com/forum/#!topic/clojurescript/Yhysh2HDb_w

13:15 seangrove: dnolen_: Cool stuff, thanks

13:34 danneu: I'm writing a toy cryptocoin miner that connects to a mining pool, listens for the workload, and starts a miner in its own thread. `(start-miner! workload)`. I need to be able to halt the miner when, say, the pool tells me to crunch a new workload. And spin a new miner up with the new workload.

13:35 core.async with a control/poison channel comes to mind but i'm not sure how to listen for poison within a tight loop

13:40 of course now it's obvious that i shouldn't be checking this sort of thing in a tight loop and instead maybe process calculation batches and check after every batch...

13:43 arrdem: danneu: are you just trying to explore the protocol or what? 'cause you're gonna get something hillariously cute like 1KH/s with a Java miner.

13:46 danneu: arrdem: b-b-but my toy bitcoin implementation needs a toy miner for its toy mining pool

13:47 arrdem: danneu: http://hugelolcdn.com/i/240652.gif

13:47 rasmusto: is that a 290?

13:47 arrdem: rasmusto: I think so

13:47 (dec so)

13:48 lazybot: ⇒ -8

13:48 rasmusto: arrdem: er, I think I meant r9

13:48 numbering is so confusing nowadays, it's looped around and intersected across manufacturers :p

13:49 arrdem: nVidia's isn't too bad, but ATI's is silly

13:49 Intel just uses ungoogleable codenames...

13:49 rasmusto: hd40000

13:49 "dusty tunnel"

13:53 justin_smith: hardware version numberwang

13:53 rem7: I have a pretty simple function that parses a ~250mb json file and returns a count for one of the elements... the problem is that once this function finishes it looks like my java app using 1.5GBs after the function call. https://gist.github.com/rem7/4ada6ff9c57eed997cdc normaly I wouldn't care, but this function is a plugin in a server, and the server is not reporting its using all of this memory, Am I missing something? all I need back form this function is an

13:53 integer, I don't know why its still consuming 1.5GBs after running.

13:53 dbasch: btw, that git is from https://www.youtube.com/watch?v=000al7ru3ms

13:53 arrdem: dbasch: hahahahaha

13:54 dbasch: rem7: you’re reading everything into memory at once

13:54 arrdem: (ind dbasch) ;; laughing uncontrollably

13:54 (inc dbasch)

13:54 lazybot: ⇒ 3

13:55 dbasch: rem7: also, how do you measure java’s memory usage? for all you know it’s been garbage-collected and not really in use

13:56 rem7: but still, you should do the count lazily

13:56 rem7: dbasch: yeah, that's fine, I don't mind if it reads the whole file, I just want it to get it clear after

13:56 arrdem: rem7: if all you're doing is streaming data and counting one field, you could probably do that with jq and a bash script :P

13:56 dbasch: rem7: it probably does, you just can’t know from looking at process memory usage

13:56 arrdem: $google github jq

13:56 lazybot: [stedolan/jq · GitHub] https://github.com/stedolan/jq

13:57 justin_smith: often the jvm will have a max mem usage, and starting - it will allocate more as it needs it (up to max) but it won't neccessarily let it go when it is done

13:57 rem7: dbasch: the problem is that java is using all those resources, now other services in the box don't have that memory available

13:58 arrdem: simplified version of the problem (there's a lot more going on) :p

13:58 arrdem: but I can replicate my issue with that

13:58 justin_smith: rem7: also, you can use jvisualvm, which comes with the jdk, to look at what the memory in your jvm is being used for

13:58 hiredman: rem7: you need to set the max heap on your jvm lower

13:58 justin_smith: and to track allocation and freeing over time

14:00 dbasch: rem7: do you have one single json objectin that file, or can you read them one at a time?

14:01 rem7: dbasch: how can I read them one at a time? I don't mind doing that… the file is pretty formatted, so one object takes multiple lines

14:01 dbasch: hiredman: but if he sets the max heap lower, it might blow up

14:01 hiredman: dbasch: that is another problem

14:01 shiranaihito: what are the pros and cons of http-kit, aleph (+lamina) and netty? i'm trying to scrape together a "standard platform" for my future web apps, but i'm having a hard time figuring out "the right tools".. i'd like to be prepared for async stuff as well, even though most things will still be synchronous like usual

14:02 rem7: setting the max heap lower isn't an option as I do want ~2GB used by java… the server can use all it wants, but the plugin it calls shouldn't hoard all of that memory

14:02 hiredman: rem7: how have you decided the plugin is using all of it?

14:03 stuartsierra: rem7: that's going to be really hard to guarantee. The JVM cannot partition or set quotas on its heap.

14:03 rem7: the server runs fine without my plugin at around 600MBs

14:03 once I use my plugin it goes up to ~2GBs

14:03 hiredman: rem7: I suggest googling and reading up and determining jvm memory usage

14:03 rem7: have to run a new instance, more pricy :p

14:03 dbasch: rem7: what does your json look like? can you refhreap a sample?

14:03 danneu: shiranaihito: i use jetty and drop in core.async if i need async stuff. it's straight forward. i use aleph/lamina for more complex things like, say, running a tcp-server/client.

14:04 hiredman: rem7: the jvm is just not returning the memory to the os

14:04 shiranaihito: danneu: are you handing off web sockets to core.async somehow, or.. ?

14:05 justin_smith: shiranaihito: aleph is really cool and well designed, http-kit is lightweight and fast. They are the best bets for async http stuff (websockets especially) that I know of

14:05 danneu: shiranaihito: oh, i see. for websocket work i use aleph.

14:05 shiranaihito: hmm

14:05 hiredman: I'd suggest googling/reading up on check the jvm memory usage, tools like top and ps can be very misleading

14:06 danneu: rem7: GSON looks like the 'SAX parser for json' http://stackoverflow.com/questions/10657725/parser-for-json-in-servlet-just-like-sax-for-xml

14:06 shiranaihito: justin_smith, danneu .. but which one should i choose? i've seen some nice-looking benchmarks for http-kit, but.. does that stuff matter in the real world? :P

14:06 danneu: or maybe even parsed-seq would work for you https://github.com/dakrone/cheshire#decoding

14:06 arrdem: justin_smith: aleph is just a http-kit wrapper AFAIK

14:07 shiranaihito: arrdem: oh? i thought it was based on netty somehow

14:07 justin_smith: shiranaihito: I go with the lightest thing / best performing thing that does the job, until feature needs force me to chose otherwise. So I use http-kit and I like it

14:07 shiranaihito: justin_smith: sounds sensible

14:07 justin_smith: arrdem: makes sense

14:07 danneu: shiranaihito: you aren't gonna get bottlenecked on perf. use the abstraction that you like and the one that makes it easy for you.

14:07 stuartsierra: Aleph wraps Netty, not http-kit.

14:07 hiredman: rem7: http://www.juhonkoti.net/2010/10/19/crash-course-to-java-jvm-memory-issues-to-sysadmins

14:08 shiranaihito: danneu: i guess you like aleph's abstraction better then?

14:09 hmm.. i wish there was an obvious choice for a web platform, like there's Datomic for a database :P

14:09 Tekhne: Can anyone recommend some videos to watch which show someone coding something in Clojure and Emacs? I'm trying to get a sense of people's workflow so that I can go read up on the components of that workflow.

14:10 justin_smith: shiranaihito: clojure hates "platforms" and "frameworks" generally - people like to compose small things that do one job

14:10 Tekhne: (I just finished my first Clojure book and I'm now trying to learn Emacs while I go through the www.4clojure.com exercises)

14:10 justin_smith: shiranaihito: unless I misunderstand what you mean by platform

14:10 technomancy: Tekhne: learning Emacs while learning Clojure isn't really a good idea

14:10 shiranaihito: justin_smith: well, maybe that was a bad choice of words.. i'm not exactly hankering for some bloated enterprisey J2EE monstrosity either :P

14:11 rasmusto: Tekhne: try lighttable if you're just getting started with 4clojure

14:11 technomancy: I recommend coming back to Emacs after you're comfortable with Clojure tooling

14:11 Tekhne: technomancy: yea, I realize it can be frustrating, but I'm okay with that.

14:11 rasmusto: I tried lighttable, but I didn't like it. I may revisit that later when more development has been completed.

14:12 danneu: shiranaihito: i already have experience with the libs that aleph is composed of (lamina, gloss) and it's just a higher level of abstraction. core.async is low level in comparison. never tried http-kit. you can't really lose by giving them all a shot.

14:12 shiranaihito: Tekhne: sorry to not answer your actual question, but i'd recommend looking into IntelliJ IDEA + Cursive Clojure.. IDEA is just hands down the best IDE out there, and it's great for editing just about anything you'd need in a web app

14:12 rasmusto: Tekhne: did you not like the clojure integration? or the editor itself?

14:12 technomancy: Tekhne: I don't know of any videos, bit the clojure-doc.org tutorial on emacs is pretty good

14:12 Tekhne: shiranaihito: No worries. Thanks for the suggestion. I will definitely be checking out IntelliJ later, but for now I really want to learn Emacs.

14:13 technomancy: http://clojure-doc.org/articles/tutorials/emacs.html

14:13 rasmusto: Tekhne: and learn emacs by all means, a basic setup isn't too bad. I just had trouble doing vim->emacs personally, hence my suggestion

14:13 Tekhne: rasmusto: the editor itself, but I expect that I'll like it more as more features are built, and as it becomes more stable.

14:13 technomancy: tl;dr: use better-defaults, cider, paredit, and magit

14:14 shiranaihito: Tekhne: i'd say that whenever there's a JetBrains IDE for the language you're working with, it's the best tool for the job

14:14 dbasch: the one thing that I wish existed is a friend plug-in for persistent user management

14:14 danneu: Tekhne: i think the most important workflow to get setup in Emacs is to use Cider so you can eval code within the editor itself (and use Paredit-mode). `C-c C-k` evals entire buffer, `C-c C-e` evals previous sexpr. i don't use a whole lot else

14:14 dbasch: e.g create-user, set-password, stuff like that

14:15 Tekhne: technomancy: I installed someone's variation on the starter kit, and so far so good.

14:15 arrdem: eeeeeeh starter kits...

14:15 I give you a week before you throw it out, take it appart, steal what you like and roll your own config

14:15 technomancy: aw crap; the tutorial still recommends the starter xit

14:16 kit

14:16 rasmusto: Tekhne: /minimal/ starter kits are fine

14:16 Tekhne: I guess what I'm really looking for now is how to people do interactive development effectively, especially things like debugging, reloading changes, etc.

14:16 rasmusto: Tekhne: clojure.tools.namespace.repl/refresh is a good thing for reloading

14:16 Tekhne: shiranaihito: yea, they have good stuff.

14:17 rasmusto: Tekhne: https://github.com/clojure/tools.trace is useful in certain situations

14:17 Tekhne: danneu: Yea, cool. I'm using Cider and Paredit now. I like it...just trying to get better.

14:17 I found a cool debugging macro that someone was using. That's been helpful for printing out the results of intermediate forms.

14:18 shiranaihito: Tekhne: they really do.. and it's extremely powerful straight out of the box, as opposed to emacs or vim where you have to scrape together various plugins and (afaik) still won't reach the same level of productivity as with a JB IDE

14:18 justin_smith: Tekhne: small pure functions that are easy to verify because they don't care about state, plus the repl for interactive exploration

14:18 bonus if the repl is in your browser for easy copy / paste to the code

14:18 technomancy: Tekhne: tools.trace is pretty rad

14:18 danneu: Tekhne: my approach for fast/exporatory coding in Emacs is to put (func-im-working-on "some sample input") at the bottom of the file and spam `C-c C-k` as I work on `func-im-workin-on`'s implementation. Cider's buffer eval returns the last expression in the file.

14:18 Tekhne: rasmusto, technomancy: cool, i'll check out trace.

14:18 arrdem: Tekhne: tracer is pretty groovy too if you don't mind huge prints.

14:18 Tekhne: danneu: oh, cool. that's a good idea.

14:19 danneu: Another approach is to drop a bunch of (assert (= ... (func-im-working-on ...)) at the bottom of the file as I spam C-c C-k to get instead assertion feedback if i break something. and i can eventually move the assertions into a test file.

14:19 arrdem: one window with "watch 'lein clean;lein test'", one window of Emacs, and a pre-commit hook that ensures all test pass :P, debugging done at a Cider repl.

14:19 Tekhne: So, one thing about clojure that was confusing me with interactive coding was that I had it in my head that vars, etc. couldn't be redefined, so I didn't understand how I could reload things in the repl.

14:20 I think I get it now, though, but I'm not sure all the things can be "reloaded" or not.

14:20 technomancy: Tekhne: redefinition is exactly the whole point of vars =)

14:20 only during development though

14:20 Tekhne: technomancy: yea, well, I'm still groking Clojure. I think I thought the immutability thing went further than it does.

14:20 technomancy: arrdem: dude

14:21 arrdem: technomancy: wat do

14:21 technomancy: lein clean =(

14:21 if you have to clean, at least do it in the same jvm

14:21 lein do clean, test

14:21 arrdem: technomancy: noted <3

14:21 technomancy: but you shouldn't need to clean, because you shouldn't ever do AOT during development

14:22 Tekhne: danneu: I like your suggestion about spamming `C-c C-k` on a temp fn at the bottom, though. That's exactly the kind of tip I'm looking for and was hoping to spot in videos of people coding.

14:22 technomancy: [1] - unfortunate gen-class requirements excepted

14:23 danneu: Tekhne: bindings are mutable, but the values they hold are generally immutable

14:23 nDuff: I'm trying to start a HTTP server to share some application state. Using http-kit, I find that (defn run-server [state-atom] (binding [*serve-this-atom* state-atom] (httpkit/run-server (site my-routes))) doesn't quite work -- it looks like the bindings aren't propagated to the thread running the server. Is there a better-practices approach?

14:23 Tekhne: danneu: Yea :-), I think I get that now, after coding for a bit.

14:24 shiranaihito: btw, has some kind of standard emerged for working with ring and web sockets? .. or is that a confused question? :p

14:25 justin_smith: nDuff: dynamic bindings don't play well with things that use multiple threads, never have

14:25 at least in clojure

14:25 danneu: Tekhne: what tends you bite you though is that the state of your repl gets dirty over time. for example, you might define function `foo` and later delete it. but `foo` is still defined in the namespace and you don't notice that you still have calls to `foo` in your code. and you don't get "foo is not defined" until you restart your repl.

14:25 nDuff: shiranaihito, ...I'd consider (or, rather, I'm actively using) http-kit rather than ring's Jetty adapter.

14:25 Tekhne: rasmusto: (doc clojure.tools.namespace.repl/refresh) doesn't seem to do the trick and Googling doesn't seem to be too helpful.

14:26 rasmusto: n/m

14:26 I found something.

14:26 nDuff: justin_smith, indeed, though there are often workarounds -- bound-fn and kin. Just not sure whether any of them are particularly usable with ring.

14:26 justin_smith: nDuff: it could be argued that one of http-kit's benefits is exposing code that doesn't quite behave right under some async conditions :)

14:26 shiranaihito: nDuff: and it Just Works etc?

14:26 :P

14:26 TravisD: Does the clojure compiler inline simple functions?

14:26 shiranaihito: justin_smith: what are you referring to?

14:27 justin_smith: shiranaihito: binding / dynamic vars don't behave nicely with things that spawn multiple threads

14:27 arrdem: TravisD: the existing Clojure compiler does _nothing_

14:27 TravisD: the JVM may play tricks, but the Clojure compiler will not.

14:27 justin_smith: shiranaihito: that is the source of his problem

14:27 TravisD: arrdem: Ah, cool. How clever is the JVM?

14:28 justin_smith: TravisD: it is kind of legendary in its field actually

14:28 arrdem: TravisD: the HotSpot JIT is pretty friggin cleaver, but it's limited in some respects by lack of static type information and static properties of the code it's working on.

14:28 nDuff: TravisD, quite clever, though it typically does expensive operations only after code has been running for a while, so you see performance improve over the course of runtime.

14:28 Tekhne: rasmusto, technomancy: tools.trace does look very cool.

14:29 arrdem: justin_smith: however there are other JITs that are more specialized, much more aggressive and arguably higher performance :P

14:29 Tekhne: danneu: so, how do you go about cleaning up the repl? Do you just restart it occasionally?

14:29 TravisD: That's also pretty cool - is it possible to make the JVM more eager to optimize?

14:29 justin_smith: arrdem: sure - I didn't claim it was the best, but it is definitely well known for performing well, and considered a reference point

14:29 arrdem: TravisD: there are JVM options for tuning the JIT, but I can't claim any familiarity with them.

14:30 danneu: Tekhne: it usually isn't a problem. and when i mess up, i just `M-x cider-restart`. i don't need to do it often enough for it to be painful.

14:30 TravisD: Hehe, thanks. I'll read up on it if it becomes important :)

14:30 rasmusto: Tekhne: c.t.n.r/refresh will clean up old vars

14:30 martinklepsch: I want to convert something like this [:name [:first-name :last-name]] to this [[:name :first-name] [:name :last-name]] — any ideomatic/simple ways to do this?

14:30 amalloy: TravisD: the jvm jit is pretty sensible as-is. attempts to tinker with it generally end in ruins

14:30 Tekhne: danneu: ah, okay.

14:30 rasmusto: oh, that's good.

14:30 arrdem: TravisD: I doubt that tweaking the JIT with command line options will ever save you if you get performance woes.

14:30 justin_smith: TravisD: turning on server mode helps (to be done in production of course) - lein puts things in a different mode that is optimized for startup rather than throughput during dev time, by default

14:30 danneu: But i'm really good at hanging the repl when i use unbuffered core.async channels and borked `go` loops... :(

14:30 arrdem: TravisD: what amalloy said :P

14:31 TravisD: amalloy: Ah, too bad. I'm thinking that almost all of my code will only run for a short time. So, if the JIT only optimizes code after some time, then maybe I wouldn't get any benefit at all

14:31 amalloy: ,(let [[first more] [:name [:first-name :last-name]]] (for [x more] [first x]))

14:31 clojurebot: ([:name :first-name] [:name :last-name])

14:31 amalloy: TravisD: but that's just what you want

14:31 justin_smith: TravisD: if it only runs for a short time, and actually completes on time, what needs optimizing?

14:31 TravisD: hm, good point

14:31 amalloy: if your code only runs a few times, then spending cycles figuring out how to optimize it is a waste

14:32 justin_smith: TravisD: timing sensitive stuff?

14:33 TravisD: Ah, no, some experiments. I guess if I leave the jvm running things that can be optimized will be optimized

14:33 over multiple runs of the experiment

14:33 and timing is not so essential

14:33 anyways, I'm running a bit late :( I will talk to you later!

14:34 justin_smith: timing not essential, running late... the irony

14:34 amalloy: (inc justin_smith)

14:34 lazybot: ⇒ 35

14:34 stuartsierra: In -server mode the JVM usually needs at least 10,000 iterations before it starts optimizing.

14:36 sritchie: any core.async users in the room?

14:36 I want to go from a sequence of channels to a channel with a single sequence of results

14:36 (->> channel-seq (a/merge) (a/into [])) seems to be the way

14:36 is there a function shortcut for this?

14:37 alejandro: sritchie: I've used (async/mapcat< identity ch)

14:37 actually, I don't think that necessarily does what you want

Logging service provided by n01se.net