#clojure log - Nov 29 2012

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

0:00 jyfl987: like {:jyf1987 {:name "jyf" :age 26 :brothers [{:alien ...} ...]}}

0:00 wil change :age every year, or add brothers when i have :]

0:01 dont want to change the whole record, that's the differences between redis and memcached

0:11 seangrove: yep like firebase, but i dont want to use a 3rd party host webservices, i need local service

0:16 seangrove: Interestingly, I want something like firebase in local memory

0:16 Is there a way to tell if a variable is an atom? Something like (when (atom? var) ...)

0:20 brainproxy: seangrove: maybe check whether its class is clojure.lang.Atom

0:20 iirc...

0:21 jyfl987: seangrove: just like me

0:21 brainproxy: (instance? clojure.lang.Atom your-var)

0:21 jyfl987: seangrove: wow, the same like me !!!

0:21 seangrove: brainproxy: That's perfect, thanks!

0:21 brainproxy: &(instance? clojure.lang.Atom (atom {}))

0:21 lazybot: ⇒ true

0:21 jyfl987: i'd like to know if a data in a tree struct or in its nested struct

0:29 seangrove: Ah, damn it

0:29 clojure.lang.Atom doesn't work in cljs

0:29 Maybe cljs.core.Atom will work

0:38 TimMc: holy shit I think I'm actually getting the hang of enlive

0:41 muhoo: scary :-)

0:45 TimMc: It seems a bit like point-free programming.

0:45 I'm passing all these transformers around and not actually seeing the node arguments at any point.

0:46 solussd: anyone know how to compile the current sexp in emacs using 'nrepl' ?

0:46 i used c-c c-c when I used clojure-jack-in

0:47 ChongLi: https://github.com/kingtim/nrepl.el#keys

0:48 C-x C-e looks to be what you want

0:48 Raynes: TimMc: It feels a bit like ,3mvirtwunvgiruetngiuenqfiu programming.

0:48 TimMc: I didn't know you knew Norwegian.

0:48 solussd: ChongLi: thanks

0:49 Raynes: TimMc: I didn't know you were dumb, but today's events make me wonder.

0:49 :P

0:52 solussd: TimMc: Enlive is awesome

0:52 jyfl987: so is there anyguys using vim here?

0:53 TimMc: solussd: I keep running into this impedence problem of node vs nodes. Do you find that to be a problem too?

0:53 Sgeo__: Enlive + monads + ??? = PROFIT

0:54 Raynes: TimMc: I'm sure he'll hear that, wherever he is.

0:54 TimMc: :-(

0:54 Raynes: Sgeo__ >>= monadistic

0:55 seangrove: A js library of cljs helper functions would be nice

0:55 jyfl987: Sgeo__: i like enlive's way

0:56 Sgeo__: I think do-> is just syntax for using some particular monad. I need to look at it again

0:57 All these library authors keep reinventing the monad wheel.

1:00 seangrove: A few shortcuts for inspecting cljs objs as js objects, auto-deref-ing atoms, etc.

1:00 TimMc: Well, here's my first working enlive code: https://github.com/timmc/pellucida/blob/master/src/org/timmc/pellucida/listing.clj#L23

1:02 * Sgeo__ looks for the docs for do->

1:10 ynniv: ok, last time I needed something specific but simple #clojure pointed me to a core function

1:11 so this time I need a foo such that (foo { :x { :a 1 } } { :x { : b 2 }) -> { :x { :a 1 :b 2 } }

1:12 and i already forgot about colloquy's funny smileys. :x is (keyword 'x)

1:12 any takers?

1:13 hyPiRion: ,(merge-with merge {:x {:a 1}} {:x {:b 2}})

1:13 clojurebot: {:x {:b 2, :a 1}}

1:15 hyPiRion: You didn't specify what to do if a keyword appears twice though. This one will only keep the last key-value pair, as in, from the last map you send in

1:15 ,(merge-with merge {:x {:a 1}} {:x {:b 2}} {:x {:a 2}}) ; e.g.

1:15 clojurebot: {:x {:b 2, :a 2}}

1:15 ynniv: that only works with the first nesting

1:15 but perhaps a simple modification will nest indefinitely

1:15 hyPiRion: hm

1:16 ynniv: ,(merge-with merge {:x {:a {:m 1}}} {:x {:a {:n 2}}})

1:16 clojurebot: {:x {:a {:n 2}}}

1:18 hyPiRion: ,(letfn [(mw [& r] (apply merge-with mw r))] (mw {:x {:a {:m 1}}} {:x {:a {:n 2}}}))

1:18 clojurebot: {:x {:a {:n 2, :m 1}}}

1:18 hyPiRion: ,(letfn [(mw [& r] (apply merge-with mw r))] (mw {:x {:a 1}} {:x {:b 2}}))

1:18 clojurebot: {:x {:b 2, :a 1}}

1:19 hyPiRion: So (defn foo [& r] (apply merge-with foo r)) is what you want.

1:20 muhoo: what's the difference between merge and merge-with?

1:20 oic, nm. f.

1:20 Sgeo__: o.O

1:20 For some reason I failed to process how easy that function would be to write

1:21 My nested maps are easy to decompose into an unnested one, so was consdering doing that then merge

1:22 ynniv: hyPiRion: that is most excellent. I'm trying to build something with partial, but self-referencing isn't working there

1:22 (inc #clojure)

1:22 lazybot: ⇒ 1

1:22 muhoo: (inc inc)

1:22 lazybot: ⇒ 2

1:22 ynniv: (inc hyPiRion )

1:22 lazybot: ⇒ 3

1:22 muhoo: (inc dec)

1:22 lazybot: ⇒ 1

1:22 muhoo: (dec inc)

1:22 lazybot: You want me to leave karma the same? Fine, I will.

1:22 Sgeo__: (dec lazybot0

1:22 (dec lazybot)

1:22 lazybot: ⇒ 8

1:23 Sgeo__: (inc lazybot)

1:23 lazybot: ⇒ 9

1:23 muhoo: (inc lazybong)

1:23 lazybot: ⇒ 1

1:23 muhoo: o_0

1:23 Sgeo__: I should just go ahead and keep lazybot dec'd

1:23 For its wrong behavior.

1:25 hyPiRion: ynniv: self-referencing is possible there too!

1:25 ,(let [mw (fn mw [& r] (apply merge-with mw r))] (mw {:a {:b 2}} {:a {:c 3}}))

1:25 clojurebot: {:a {:c 3, :b 2}}

1:26 hyPiRion: Just put in the name of the function right after "(fn"

1:28 ynniv: ,?

1:28 I think I killed lazybot

1:28 I asked it for a list of help topics

1:28 ,(+ 1 2)

1:28 awesome

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

1:28 3

1:29 muhoo: &(identity :foo)

1:29 lazybot: ⇒ :foo

1:29 muhoo: it's alive

1:29 ynniv: hmm, looks like I was just lagging for a couple of minutes

1:29 I just got a burst of backlog

1:30 muhoo: well it is LAZYbot.

1:30 (realized? lazybot)

1:30 ynniv: (dec muhoo)

1:30 lazybot: ⇒ 0

1:30 ynniv: (inc muhoo)

1:30 lazybot: You want me to leave karma the same? Fine, I will.

1:30 ynniv: just kidding

1:32 is there no way to print current karma?

1:33 nightfly_: (str muhoo)

1:33 ynniv: hyPiRion: I meant (def recursive-merge (partial merge-with recursive-merge)). It can't self-reference because partial needs to evaluate before it can def recursive-merge

1:33 i assume

1:34 hyPiRion: ah, right

1:35 ynniv: well… your expr macroexpands into (def foo (fn* ([& r] (apply merge-with foo r))))

1:35 not sure how that's different from partial

1:38 k, asked lazybot for help again, seeing the same lag

1:40 Sgeo__: partial isn't a body, all its arguments get evaluated

1:40 Incidentally, try using the Y combinator or some other fixed-point thing?

1:40 ynniv: oh, fn is a special form that pre binds the function name to allow self referencing

1:40 bluegray: howdy all

1:41 I'm trying to get his going: https://github.com/hugoduncan/hornetq-clj

1:41 is that yours hugod?

1:41 ynniv: Sgeo__: why does partial not being a body matter? wouldn't it only matter if it were part of a special form that wasn't evaluated?

1:42 Sgeo__: (partial f (+ 1 1))

1:42 (+ 1 1) gets evaluated before partial ever sees it

1:42 clojurebot: 2

1:42 Sgeo__: o.O

1:43 (fn [] (+ 1 1)) (+ 1 1) doesn't get evaluated unless the function is called

1:43 ynniv: yes, but symbols are bound on compilation

1:43 ,(fn [] undefined)

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

1:45 Sgeo__: Maybe the def form allows use of the name it's defining within it?

1:45 ynniv: http://clojure.org/special_forms says this is because fn does magic to allow it

1:45 and defn expands to (def (fn name

1:46 Sgeo__: http://ideone.com/BqgXcu

1:46 ynniv: err, actually it doesn't… hmm

1:46 Sgeo__: Not getting an error about unresolved name, but about unbound var

1:47 Which indicates that when you're in a def's body, you can in fact use what is currently being def'd

1:47 Hmm, "use"? Lemme se

1:48 http://ideone.com/Yneg8Z

1:48 Guess that doesn't strictly speaking prove it, could look like weird fn magic

1:48 bluegray: I'm having trouble running the example code - can't figure out how to create the queues

1:49 Sgeo__: I hope I didn't crash IdeOne

1:50 Now, how to use this knowledge for evil instead of good...

1:51 ynniv: ~(+ 1 1)

1:51 clojurebot: ,(let [testar (fn [x y] (cond (= (reduce + (filter odd? (range 0 x))) y) (str y " is a")) )] (testar 11 25))

1:53 Sgeo__: o.O what?

1:53 ~(inc 5)

1:53 clojurebot: see Subject Computing, Inc

1:53 Sgeo__: wat

1:53 ~(dec 0)

1:53 clojurebot: (+ 2 10) reply 12

1:53 Sgeo__: ...what?

1:54 ~()

1:54 clojurebot: () is awesome

1:54 Sgeo__: ~(do)

1:54 clojurebot: It's greek to me.

1:54 ynniv: doesn't ~ talk to lazybot?

1:54 and , to clojurebot?

1:54 ,1

1:54 ~1

1:54 clojurebot: 1 is marg

1:54 1

1:54 Sgeo__: ~HoNk

1:54 clojurebot: I don't understand.

1:54 Sgeo__: ~(+ 346 126)

1:54 clojurebot: ,(let [testar (fn [x y] (if (= (reduce + (filter odd? (range 0 x))) y) (str y " is an square perfect")) )] (testar 10 25))

1:55 Sgeo__: ~(+ 346 126)

1:55 ynniv: clojurebot: foo?

1:55 clojurebot: ,(let [testar (fn [x y] (if (= (reduce + (filter odd? (range 0 x))) y) (str y " is an")) )] (testar 10 25))

1:55 Foo is is Short, Self Contained, Correct (Compilable), Example http://sscce.org/

1:55 ynniv: dunno

1:55 ,(+ 1 1)

1:55 clojurebot: 2

1:56 ynniv: (inc clojurebot)

1:56 lazybot: ⇒ 15

1:56 ynniv: i guess the bots have changed since the last time I was here

2:33 Raynes: $mail ynniv Lazybot is triggered with &

2:33 lazybot: Message saved.

2:34 Raynes: Sgeo__: http://dl.dropbox.com/u/23745600/Screenshots/32ba.png You should use refheap. At least it can keep text in bounds.

2:35 Sgeo__: Can refheap evaluate code that I paste in?

2:44 As soon as I finish my long overdue math homework I must sleep

2:49 abp: Sgeo__, so, quite a few hours to go? Sleepy brain and math sounds like an unforgiving combination.

2:49 Sgeo__: I'm actually doing these a lot faster than I thought I would

2:49 But I did make a few dumb mistakes

2:50 A lot of these questions are requiring minimal thinking though, so that's good

2:53 " (If a value does not exist, enter NONE.)"

2:53 I vaguely decided that the value did not exist, put DNE down, and was saddened by the wrong mark.

2:53 (I get multiple tries)

3:01 abp: Sgeo__ uh I know that feeling.

3:02 Sgeo__ but I've got absilutely no math skills. You would laugh for hours, would you know what I program, considering how absent my maths are.

3:20 Sgeo__: I am now distracted by a recreation math thought I've had for a while and now feel closer to solving

3:47 tomoj: hmm

4:16 clj_newb_234: on linux, are there any wms that can be scripted via clojure?

4:16 (wms = window managers)

4:18 jyfl987: havnt saw anyone , but heard of any other list dialect driven wm

4:19 mpenet: there is stumpwm

4:19 but its common lisp

4:19 you can script gnome with js I think now, but its not a wm

4:20 p_l: clj_newb_234: wmii can be scripted through anything that can use file i/o

4:21 Sgeo__: Liskell/Lisk with xmonad?

4:21 Licenser: and I thought wms = weapons of mass sausage

4:22 p_l: Licenser: ... sausagefests?

4:22 Licenser: yap

4:22 p_l are you stalking me?

4:22 p_l: Licenser: nope

4:22 but I'

4:22 Licenser: I start to get the feeling whenever I say something somewhere you pop up :P

4:22 p_l: *I'm trying to rewrite tests from HP QTP into Selenium

4:23 and I went with Clojure for driving Selenium

4:23 Licenser: HP QTP?

4:24 algernon: /20/16

4:25 p_l: QuickTest Professional

4:26 jyfl987: maybe you could worte by yourself

4:26 tagrudev: lein : The plugin task has been removed.

4:27 how do I install plugins via lein now :( ?

4:28 ucb: tagrudev: lein2?

4:28 tagrudev: yup

4:28 ucb: tagrudev: https://github.com/technomancy/leiningen/wiki/Upgrading

4:28 the-kenny: tagrudev: Add them to ~/.lein/profiles.clj

4:28 ucb: first hit on google for "leiningen 2 plugins" ;)

4:28 (at least for me)

4:29 tagrudev: the-kenny, yeah I've added them to profiles but how do I install them :) ?

4:30 the-kenny: You don't need to. The profiles.clj will be merged with the local project.clj of your project and lein will fetch the plugins

4:31 {:user {:plugins [[foo/bar "0.1-SNAPSHOT"]]}}

4:31 tagrudev: seem legit

4:31 let me try it

4:31 the-kenny: If the project depends on the plugin, add it to the project.clj itself

4:33 tagrudev: if it is not a project and just a file, I am starting with clojure now

4:36 i am trying to jack-in in emacs but it is searching for a project.

4:36 clj

4:38 the-kenny: tagrudev: Using nrepl?

4:38 Or slime?

4:42 nrepl is much easier to setup/use, especially when using leiningen 2 :)

4:42 nrepl is the future!

4:42 tagrudev: neither I guess

4:42 trying to get emacs + slime + swank working

4:43 the-kenny: Okay, you should really try nrepl :)

4:43 swank-clojure is more or less deprecated. Many people switch to nrepl nowadays, as it's easier to setup and written from the ground up for Clojure

4:43 Do you use a recent emacs? (23+)

4:43 tagrudev: 24

4:44 the-kenny: M-x package-install nrepl RET

4:44 tagrudev: done

4:44 p_l: the-kenny: most importantly, nrepl isn't for unknowable reasons bound to ancient releases :)

4:44 the-kenny: This will install nrepl and clojure-mode. Then you can M-x nrepl-jack-in wherever you want

4:45 tagrudev: OR you can run "lein repl" anywhere and in Emacs run M-x nrepl RET localhost RET <port> RET

4:45 The latter will connect to the repl running at <port>, the forer will run lein-repl as a subprocess and connect to it

4:46 leiningen 2's repl has an integrated nrepl server

4:46 tagrudev: that's cool but my idea is is there a way to run it

4:46 with the current context

4:46 the-kenny: Which context?

4:46 * maleghast tips his hat to the room

4:46 maleghast: Morning:-)

4:46 tagrudev: the-kenny, lets say i have dir/file.clj and it is loaded in buffer in emacs

4:47 zoldar: by the way, anybody successfully using ritz-nrepl along with current stable nrepl.el? last time I've tried it, on every attempt of evaluating/compiling a form it failed for me

4:47 tagrudev: there are some functions in it and I want to run repl with this file loaded so I can test it

4:47 the-kenny: tagrudev: Ah, ok. Just run nrepl anywhere or use nrepl-jack-in. Then do C-c C-l to load the file

4:47 C-c C-k might work too

4:48 tagrudev: ty that is what I was looking for

4:48 :)

6:22 Anderkent: Anyone know where deftype* comes from? I see it used by the defrecord macro, but can't find it anywhere. Is it a special form?

6:28 Foxboron: Any people using/used TextMate here?

6:31 maleghast: Foxboron: I use Textmate for lots of things, and have done for Clojure… What can I help you with?

6:31 Foxboron: maleghast, does (+ 1N 2N) turn out as valid syntax with TextMate?

6:32 Sublime uses the same Syntax files, and it is considered invalid code. But its totally valid :P

6:34 maleghast: Foxboron: Yeah it's fine in Textmate

6:36 Foxboron: Yeah, then i'll find TextMates syntax files :) Thanks maleghast

6:36 Anderkent: (okay it does seem it's a special form, but it's not in the special form list)

6:37 maleghast: Foxboron: NP :-)

6:37 Anderkent: Is this what you are looking for…? -> http://clojuredocs.org/clojure_core/clojure.core/deftype

6:38 Anderkent: maleghast: if you look at the source of that, it expands into `(deftype*

6:38 and the deftype* is not defined anywhere, so I had to look at the compiler sources to make sure it's a special form

6:39 maleghast: Anderkent: Ah I see - sorry I did not see the "*" in your original Q.

7:02 clgv: Anderkent: it is a special form

7:03 Anderkent: see here: ##(keys (clojure.lang.Compiler/specials))

7:03 lazybot: java.lang.SecurityException: You tripped the alarm! class clojure.lang.Compiler is bad!

7:03 clgv: ,(keys (clojure.lang.Compiler/specials))

7:03 clojurebot: (deftype* new quote & var ...)

7:09 Anderkent: yeah, i was looking at http://clojure.org/special_forms but it's apparently not complete :)

7:11 clgv: Anderkent: ah that one documents only specialforms you are supposed to use

7:11 Anderkent: you should not use deftype* yourself

7:11 Anderkent: I'm not, but I'm writing a code walker and need to be aware of what cannot be evaluated

7:11 anyway, thanks for the Compiler/specials

7:11 that will help

7:12 clgv: &(apropos "special")

7:12 lazybot: ⇒ (special-symbol?)

7:12 clgv: &(special-symbol? 'deftype*)

7:12 lazybot: ⇒ true

7:12 Anderkent: cheers

7:13 Foxboron: Weee, patched the 1N problem in Sublime.

7:13 maleghast: Foxboron: Nice job! :-)

7:13 (paste please)

7:13 Foxboron: find constant.numeric.integer.clojure

7:13 correct regex: (-|\+)?\b[0-9](|N)+\b

7:14 (Only added (|N) there)

7:14 maleghast: *nods* nice

7:14 Foxboron: Limited exp with regex, so was a funny task ^^

7:15 Also, was condering making a few Clojure plugins for Sublime. If anyone got any suggestions or what not, please tell me and i'll see what i can do.

7:15 Was considering a little CLojureDoc search for a start.

7:15 maleghast: Foxboron: That sounds like it would be very useful.

7:16 Foxboron: Yeah i know. havent decided if its better to add the search result to a view, or just open the browser.

7:41 * abp on a decomplecting spree.

8:27 abp: Raynes, https://www.destroyallsoftware.com/talks/wat ?

8:57 the-kenny: Wat?

8:59 rhickey: I'm still not loving the names of the new thread macros, considering:

8:59 let-> ==> as->

8:59 test-> ==> pred->

9:00 maybe - when-> ==> is->

9:00 the latter then being a nil test

9:00 maleghast: rhickey: Is this for 1.5..?

9:01 rhickey: yes

9:01 would like to get this sorted before release

9:01 foodoo: rhickey: is there a google groups discussion about these? (couldn't find one)

9:01 maleghast: and your preference is for the versions on the right..? (I'm guessing because they seem more semantically appropriate?)

9:01 foodoo: what are they supposed to do?

9:02 rhickey: the ones on the left are already in the beta

9:02 maleghast: rhickey: I thought so

9:02 rhickey: some people are confused about let->, I don't like test-> conflicting with ideas about testing

9:03 maleghast: rhickey: fwiw I like the options you set out ^^ better than the current ones

9:03 rhickey: when-> is ok, and matches when, but nil test more general than truthy

9:03 but 'is' is a new notion

9:03 Chousuke: I'm reading those names as "thread-as" and "thread-pred" and "thread-is". the last one doesn't quite make sense to me.

9:03 rhickey: I have other ideas for it, not for now

9:04 maleghast: Certainly as-> and pred-> are better (imho) than let-> and test->

9:04 clgv: rhickey: I like "as->" and "pred->" - improved naming. :) I dont know about "is->"

9:06 rhickey: nnil-> another option for when-> or is->

9:06 mpenet: pred-> does sound better than test->

9:06 maleghast: rhickey: would you be completely opposed to being totally explicit =: notnil->

9:07 rhickey: would have to be not-nil->

9:07 algernon: perhaps truish-> ?

9:07 rhickey: not truish, when-> is better for that

9:07 maleghast: rhickey: I would imagine so

9:07 rhickey: new name to get to not nil semantic

9:08 alexnixon: rhickey: I was thinking about let-> ( http://dev.clojure.org/jira/browse/CLJ-1110 ) in particular it feels like it should support destructuring

9:08 rhickey: though if it were renamed that would make less sense

9:08 Chousuke: nnil-> is probably not going to be a good idea. it will look like a typo

9:09 maleghast: Chousuke: Hence my suggestion to be more explicit and we got to not-nil->

9:11 jballanc_: maybe exists->

9:12 rhickey: alexnixon: let-> does destructure, but that's less useful than you might think as it gets repeated and often the threaded result won't destructure similarly

9:14 alexnixon: alexnixon: I don't think it does - the body of the expr in the 'let' after macro expansion is ~name (which doesn't work if name is {:keys [x y z]})

9:14 Chousuke: for the not-nil cases you might just use the ? convention and go for -?>

9:14 alexnixon: rhickey: I don't think it does - the body of the expr in the 'let' after macro expansion is ~name (which doesn't work if name is {:keys [x y z]})

9:15 rhickey: alexnixon: showing firther how that can't be made to work

9:15 further

9:16 Hodapp: Here's a silly question I couldn't figure out last night: Is there a way I can evaluate something as if in the context of some namespace, without using :use for the entirety of the file?

9:16 say, just one function.

9:16 rhickey: I'm not going to discuss destructuring more, it's too complex for threading, can't cascade

9:17 Chousuke: Hodapp: you can use require and import just that one function

9:18 Hodapp: you can also temporarily change namespaces by calling in-ns but that's kind of ugly.

9:18 Hodapp: Chousuke: I meant more that I want to define (for instance) just a single function, but in order to reduce some syntactic sugar I'd like to avoid either :use-ing that namespace or prepending it to everything inside it

9:19 hugod: rhickey: when-> is a little like a maybe monad, so maybe->?

9:20 Hodapp: oh well, in the meantime I can just alias quil.core to 'qc', that's not too ugly I suppose

9:21 rhickey: hugod: we don't have maybe

9:22 alexnixon: rhickey: fair enough, I'll leave it there. FYI though I've found it useful when making incremental updates to state-like maps (let-> {:foo 1 :bar 2} {:keys [foo bar] :as state} (assoc state :foo (inc bar)) (assoc state :bar (* foo 2))) ==> {:foo 3 :bar 6}

9:23 Hodapp: This might be one of the few languages I use where the language's creator frequents the IRC channel :)

9:23 rhickey: one problem people had with pred-> was thinking that the tests would be predicates called on the threaded val

9:24 hugod: without a culture built around a Maybe type, raises the question as to maybe based on what?

9:25 maleghast: rhickey: I can see how that would be (almost) as confusing as test-> now that you mention it… The naming of "things" is a difficult pursuit when you get down to it, no?

9:28 hugod: rhickey: when-> and test-> could also take an optional binding (when-> expr [a] ....), and if let-> used (let-> [a] ...), then the three forms would vary only in the logic applied to the clauses. If the binding in let-> were optional, then it becomes just an augmented variant of ->.

9:30 rhickey: hugod: how does binding cascade?

9:30 as-> gives the threaded argument that name in every expression

9:31 your now going to bind over and over, so it becomes a one-shot

9:31 now very threaded

9:31 not

9:31 you're

9:32 lpetit: rhickey: beware, or Raynes will not talk to you anymore :-p

9:32 squidz: will the stack traces in clojure ever improve? I just started programming with clojure and so far have made a simple blog, and a XML manipulation script, and in the beginning I thought there are two negatives about clojure. The first being the parenthesis, the second being the stack traces. Now the parenthesis don't bother me at all though. Will I also get used to the stack traces? Or are they kind of difficult for everybody?

9:32 rhickey: squidz: write a patch

9:33 squidz: hm never done anything crazy like that before

9:33 maleghast: squidz: To be honest I used to find them very intimidating and now I don't - time and exposure do seem to help

9:33 rhickey: lpetit: for correcting myself? :)

9:33 Chousuke: maleghast: also, pretty-printers

9:33 foodoo: maleghast: agree. It's a matter of practise

9:33 lpetit: rhickey: Don't know if you've been following on clojure-dev, but I'm working on adding more dynamicity to the 'ns macro

9:34 e.g. have (ns a) (ns b (:require a)) work on a repl

9:34 there were interesting questions along the way, involving how clojure.core is loaded differently when it's from raw source code, or from AOT code. Detailed email coming soon

9:34 squidz: also, Ive heard that there is a new Invokedynamic bytecode for the JVM. Could this benefit clojure?

9:36 lpetit: squidz: stack traces mostly keep being intimidating, we'll have to work on this, for sure

9:37 squidz: lpetit: have you heard about invokedynamic in the JVM?

9:37 HolyJak: squidz: http://blog.fogus.me/2011/10/14/why-clojure-doesnt-need-invokedynamic-but-it-might-be-nice/

9:37 squidz: thanks HolyJak

9:41 pyr: rhickey: hugod: any chance of since something resembling thread-expr's for-> and for->> ?

9:44 TimMc: rhickey: Destructuring in let-> is not meaningful at all, since the binding form is also the tail-position form.

9:44 (let [& 0] (let-> [1 2 3] [f & r] [r & f])) ;; => [(2 3) 0 (0 1)]

9:45 Maybe it should expand to let* instead of let.

9:45 lpetit: all, I've got a patch for the dynamic ns issue I raised on the ml: https://github.com/laurentpetit/clojure/commit/0fe0c5238c00ef871ff6523d4b50d07a1bd86aa8

9:46 If anybody can test against his own project / codebase, etc. ?

9:47 rhickey: no, he tweeted earlier in the week about not wanting to talk anymore to people using your you're incorrectly :-)

9:47 rhickey: don't know if you've time for it, but there's a patch ^^ for solving the dynamic ns problem

9:48 3-liner

9:50 maleghast: rhickey: Totally off topic and trivial, but please can you bring stickers to Clojure exchange next week..?

9:51 rhickey: lpetit: link?

9:51 lpetit: https://github.com/laurentpetit/clojure/commit/0fe0c5238c00ef871ff6523d4b50d07a1bd86aa8

9:51 rhickey: ^^

9:52 rhickey: lpetit: I'm quite concerned about touching ns for this release given the ridiculous complexity and fragility in the ns/require system

9:52 lpetit: rhickey: I understand. We've put 2 hours of pair-programming with Christophe to be sure that we've got the most ridiculous and innocuous addition to it

9:53 rhickey: :)

9:53 lpetit: rhickey: meaning, we've had the temptation to rewrite the whole thing several times, but got away from it :)

9:55 rhickey: in a nutshell (between a tl;dr and the full explanation): (require 'foo) adds foo to *loaded-libs*, but (ns foo) does not. Meaning that if you first write (ns foo) then (ns bar (:require foo)), then it's only the first (:require foo) that will prevent it from being reloaded again and again from the disk.

9:57 hugod: rhickey: https://gist.github.com/4169539 was what I had in mind

10:00 hcumberdale: Hi ;)

10:02 maleghast: hcumberdale: Hello

10:03 hcumberdale: I've uploaded files to a server into a directory 'x'

10:03 maleghast: ok

10:03 * maleghast wonders where this is going

10:03 hcumberdale: Now I build a reference to the files by extension fs/list x

10:03 maleghast: I see

10:03 hcumberdale: How to send an order of the elements from the frontend for further processing?

10:04 Simply send the file names in an ordered list again?

10:04 maleghast: er...

10:05 hcumberdale: Reordering of the processing is possible without changing them

10:05 rhickey: @hugod I find that baffling, and with the docstring unchanged, don't know how to use it

10:05 hugod: ^^

10:06 hcumberdale: wow rhickey here, awesome

10:06 rhickey: hugod: sticking to as-> what is the intent?

10:09 lpetit: is there no ticket w/patch? I can't move on that without it

10:10 hcumberdale: rhickey: what are the plans for clojure 1.5 ?

10:10 lpetit: rhickey: oh, I wanted to wait for some kind of approval first, 'cause I don't like when bug trackers are filled with things that may not go anywhere

10:10 rhickey: I'll create it right now, following the procedure

10:10 mdeboard: hcumberdale: It's almost like he's a real person

10:11 hcumberdale: mdeboard ;)

10:14 rhickey: hcumberdale: what do you mean?

10:15 * cgrand notices a naming party is going on!

10:15 rhickey: cgrand: yes. please help

10:16 as-> pred-> instead of let-> test->

10:17 when-> could stay as-is or get nil-based version name TBD

10:17 borkdude: wow, even loading packages is lazy in haskell?

10:19 cgrand: I like Chousuke suggestions of using the ? convention so -?> or ?->

10:19 rhickey: hugod: now as-> is gone from your gist - I'd like to focus on as-> to understand your destructuring proposal

10:20 cgrand: ? means truthiness elsewhere

10:20 hugod: rhickey: I see now I was confused about let->, since it doesn't actually thread anything.

10:21 cgrand: rhickey: true it's importing a conflicting convetion

10:21 maleghast: hcumberdale: sorry, I had to step away for a few minutes there… I _was_ trying to be helpful… Where did we get to?

10:21 rhickey: hugod: you mean in its implementation?

10:22 cgrand: test-> has a cond feeling but cond-> would lead people to think only one expr is threaded

10:22 hugod: rhickey: it's just a repeated let, nothing is threaded into the forms

10:22 rhickey: cgrand: right, cond-> is my favorite

10:23 hugod: depends on what you consider threading, it does not become the first arg

10:23 hugod: cgrand: cond for me implies the threaded value would take part in the test predicates

10:23 rhickey: hugod: I don't see that unless condp->, but most people expected short-circuit

10:26 lpetit: rhickey: http://dev.clojure.org/jira/browse/CLJ-1116

10:26 rhickey: there are many places where one needs only non-nil conditionals. Imagine nnil->, if-nnil, when-nnil

10:27 lpetit: ok, how about some tests with that please?

10:28 hugod: rhickey: I added examples to the gist too. I find the usage confusing in the end. Apologies for the noise.

10:32 rhickey: hugod: the problem with that is that the most important use of as-> is to thread into expressions where you don't want to be forced into first arg

10:32 and more generally, of binding as well

10:32 your stuff threads and binds

10:32 lpetit: rhickey: grmlml, ok :)

10:34 rhickey: do you want a separate patch, so that you can try it against current version of clojure (demonstrating the problem), and then against patched version of clojure ?

10:34 rhickey: lpetit: no, I tried it already with current Clojure

10:35 lpetit: rhickey: ok, so I'll add the tests to the patch and ping there when it's done

10:43 TimMc: rhickey: I strongly support as->, since (as-> 5 a ...) is way less confusing than (let-> 5 a ...).

10:44 "With 5 starting as 'a, ..." vs. "Let 'a be 5, no wait, let 5... 'a..."

10:44 I keep messing up the order of the first two forms in let->.

10:46 It's as bad as nth.

10:46 alexnixon: TimMc: the intended usage (also unclear, I'd argue) is within an existing threading macro

10:47 TimMc: (-> (+ 1 2) (as-> three (+ 1 three))) => 4

10:47 TimMc: Yeah, I understand the rationale -- but the name should match the order.

10:48 (And I understand that nth, as a seq fn, takes the seq as the final arg.)

10:48 hugod: would ->as be a better name, in that it is used within a thread, but doesn't start one?

10:49 TimMc: I don't see why it *can't* be used on its own.

10:50 hugod: TimMc: indeed - would a non-threaded version have a body (like let), or just return the bound value?

10:50 TimMc: Non-threaded version?

10:53 All I'm saying is that as-> would be nice where -> and ->> are not quite enough.

10:53 hugod: I thought you meant something like https://gist.github.com/4169930

10:57 TimMc: hugod: How does that differ from as-> (well, let->)?

10:59 hugod: TimMc: it doesn't have the first expression argument, so the argument order is more what you would expect when using outside of a threaded expression

11:02 TimMc: Oh I see -- I missed that you'd reversed the param.

11:02 *params

11:03 Raynes: Is there a Mongo-related reason why refheap doesn't accept pastes over 64kB?

11:05 (or other technical reasons besides disk space)

11:09 rhickey: hugod: I don't like ->blah for thread stuff, and still, that depends on your notion of threading. This is named threading

11:10 as-> seems uncontroversially better than let->. What avour pred-> and nnil-> ?

11:10 TimMc: ->foo also conflicts (visually and possibly code-wise) with record constructors

11:10 rhickey: TimMc: right

11:11 TimMc: No one *should* create a record called that, but it's still a problem.

11:14 jballanc: rhickey: could you use cond-> instead of pred-> ?

11:14 pred-> reminds me of lisp-ish cond's

11:15 rhickey: jballanc: people presume cond-> will short circuit on first match

11:15 jballanc: ah, true

11:15 naming *is* hard

11:15 rhickey: this threads into every expr for which corresponding test is true

11:17 mdeboard: dowhile :)

11:18 jballanc: solongas->

11:18 keepgoing->

11:18 yeah...I'm out of ideas

11:18 clgv: +1 for "pred->"

11:19 rhickey: it's not while, nor so long as

11:19 mdeboard: I see.

11:19 jballanc: it returns at the last pred that evaluated true, right?

11:19 rhickey: each clause is gated, but it proceeds

11:20 gate-> was an earlier proposal

11:20 jballanc: oh, ok...I see

11:20 hmm...makes me think test-> is almost best

11:20 rhickey: there's just so much test-this and test-that around testing

11:20 the word is dead

11:21 jballanc: assert-> ?

11:21 but that's probably as dead as test

11:22 TimMc: THe problem here is that we don't have a pattern in Clojure branching on nil alone.

11:22 *for branching

11:22 We've got nil-punning and that's it.

11:22 it's more like while-has-value->

11:23 rhickey: TimMc: this one (pred->) has nothing to do with nil, do you mean nnil-> ?

11:24 TimMc: Sorry, yes, I'm pondering when->

11:24 off in my own little world

11:26 value->

11:26 rhickey: is->

11:27 Foxboron: Mixing up some ClojureDocs search plugin for Sublime Text 2. Anyone got any whis on functionality :D?

11:27 wish*

11:27 rhickey: some-> (also currently truthy)

11:28 and predicate based

11:28 TimMc: is-> sounds like a test

11:28 As for test->... how about guard->?

11:28 rhickey: TimMc: only if your notion of is has been broken by that test framework

11:28 :)

11:28 TimMc: haha

11:29 *That's* where I got that.

11:30 mdeboard: Is test-> currently (test-> pred & args)?

11:30 Can't really find any docs for 1.5 that cover new stuff.

11:31 rhickey: mdeboard: no, (test-> expr test1 thread1 test2 thread2 ...)

11:31 mdeboard: Ah i see.

11:31 Just found changes-draft-v7.md

11:31 rhickey: where test1 is an expression, if true, threads through thread1, else skips

11:33 TimMc: guards in other langs short circuit like cond

11:34 TimMc: Is there semantic pollution on the name "guard"?

11:34 s/pollution/baggage/

11:34 guard-each-> would be more explicit

11:35 rhickey: not for Clojure, but as I said, guards are like cond

11:35 jballanc: when you put it like that, it seems more like select->

11:35 or even filter->

11:35 mdeboard: if-apply-> or when-apply->

11:36 jballanc: You're not really filtering or selecting though, you're performing operations selectively (I thought about those two as well)

11:36 rhickey: gate->

11:40 xumingmingv: ,(let [String 1] (println String))

11:40 clojurebot: 1

11:41 mdeboard: rhickey: I'm a newb but I think a noun as a threading macro name is a bad idea.

11:41 xumingmingv: Why the above the above output is 1? according to the http://clojure.org/evaluation

11:43 according to http://clojure.org/evaluation, it should output "String" right?

11:43 mdeboard: xumingmingv: Because it finds a binding to that var locally so it uses it without checking for other bindings

11:44 gfredericks: mdeboard: xumingmingv: not a var, just a local

11:45 xumingmingv: mdeboard: but according to http://clojure.org/evaluation, it should check whether String is a class first, then check whether it is a local binding or not

11:45 mdeboard: Yeah, sorry, I just meant variable.

11:45 llasram: mdeboard: I think what xumingmingv is saying is that the documentation says that class name lookup happens *before* local binding lookup

11:45 xumingmingv: llasram: YES

11:46 lpetit: rhickey: tests added: http://dev.clojure.org/jira/secure/attachment/11725/dynamic-ns-patch2.diff

11:48 mdeboard: xumingmingv: Yeah, no clue. It doesn't seem like it works like that

11:49 llasram: xumingmingv: The documented order seems odd to me though -- the observed behavior seems less surprising. You'd need to dig into the implementation to figure out if something has changed or if the documentation is just wrong

11:50 xumingmingv: mdeboard: llasram, yeah seems the documentation does not match the REAL implementation

11:52 rhickey: hi hickey, any hint? does the documentation indeed doesnt match the implementation?

11:55 * gfredericks thinks that's a surprising discrepancy

12:26 antoineB: hello, is there a clojurescript developper here?

12:27 dnolen_: antoineB: yes :)

12:28 bbloom: ping, what was your points about errors yesterday?

12:28 antoineB: (= js/NaN js/NaN) give false

12:29 in js: NaN == NaN also give false

12:29 should clojurescript "=" fix it?

12:30 as same as (number? js/NaN) => true

12:30 S11001001: ,(= Double/NaN Double/NaN)

12:30 clojurebot: false

12:30 S11001001: antoineB: guess not

12:30 ttimvisher: has there been any progress towards enabling debugger support along the lines of `require 'ruby-debug'; debugger; 1` in ruby or `(swank.core/break)` that actually allows you to access a repl in the frame?

12:31 cdt seems to work too much with state, and I can barely get it to work anyway. I want to be able to set a breakpoint in my code and then get a repl

12:31 llasram: ttimvisher: ritz? https://github.com/pallet/ritz

12:31 technomancy: ttimvisher: I worked on getting swank.core/break working in nrepl: https://github.com/technomancy/limit-break

12:32 antoineB: S11001001: why such behavior?

12:32 technomancy: I haven't tried it on recent versions but it might work

12:32 err--debug-repl specifically, not the swank version exactly

12:32 ttimvisher: technomancy: hah! love the name

12:33 S11001001: antoineB: because functions following behavior laws like transitivity and reflexivity is for ivory tower academic types, not those working down in the trenches on real world applications

12:34 antoineB: see also: http://dev.clojure.org/jira/browse/CLJ-893?focusedCommentId=27605&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-27605

12:34 seangrove: S11001001: That's a bit of an obtuse answer ;)

12:35 antoineB: S11001001: why Double/NaN and Double/NaN differ?

12:35 S11001001: seangrove: guess I'm more annoyed about the resolution of clj-893 than I thought I was.

12:35 ttimvisher: thanks for the pointer

12:35 S11001001: antoineB: the same justification as in clj-893 can be applied to your scenario: it's faster this way, just document that it doesn't work with nan

12:36 llasram: It's an an aspect of IEEE floating point. NaN != NaN in any compliant language

12:37 S11001001: llasram: that's irrelevant if your contract for = includes reflexivity

12:37 technomancy: you could argue that floats are a lost cause; if you're using them you need to understand you're prioritizing speed over correctness

12:38 Foxboron: So, i am making some plugin to search the clojuredocs.org. I notice that, when you search. The Search result displays wrong number of examples.

12:38 Anybody know if this is a known bug or?

12:39 llasram: S11001001: Fair enough, but adds some flavor to your to your argument :-)

12:40 dnolen_: antoineB: I don't see what there is to fix. If you want to check for NaN, use js/isNaN

12:41 technomancy: I guess that's not a helpful distinction if your runtime offers nothing but floats

12:41 something to keep in mind when picking a runtime I guess

12:41 antoineB: i use NaN from string to int conversin

12:41 *conversion

12:42 technomancy: antoineB: there are no ints in JS

12:43 antoineB: good points

12:44 so i convert string in an integer form to floats :)

12:45 dnolen_: just notice also that i can use map/filter/etc... with (.children dom-element) if i don't extend HTMLCollection

12:46 dnolen_: do you plan to do it?

12:46 dnolen_: antoineB: I'm not sure what you mean. plan to do what?

12:48 antoineB: dnolen_: am i the only who wants to do map/filter on dom tree?

12:49 dnolen_: antoineB: no need for us to add it. extend HTMLCollection to ISeq or ISeqable

12:50 antoineB: i do it, but i take me some type to figure it out

12:50 *he take

12:50 *it takes

12:55 dnolen_: antoineB: yes more examples on how to do this would be nice, DOM array-like collections are easily made into seqs via `prim-seq`

12:56 (extend-type HTMLCollection ISeqable (-seq [this] (prim-seq this))

12:58 antoineB: dnolen_: i use the same as (extend-type array ...)

12:58 so i use array-seq

12:58 dnolen_: antoineB: sure, but array-seq just calls prim-seq :)

12:58 antoineB: i just noticed it :)

12:59 what "prim" stands for?

13:02 dnolen_: antoineB: primitive

13:12 DaReaper5: Anyone here know korma

13:19 Anyone here know korma

13:20 mdeboard: DaReaper5: Always better to just ask your question

13:22 DaReaper5: how do i do a "with" when a relationship is not defined

13:22 i can do a join but it does not grab all the fields like a "with" would

13:22 ... and i am having trouble with subselect

13:40 Sonderblade: what's the way to sum a list of sum a list of ints in clojure?

13:40 antoineB: (sum (flatten nested-list)) ??

13:40 lazybot: antoineB: What are you, crazy? Of course not!

13:40 technomancy: Sonderblade: reduce + apply concat

13:41 insert parentheses as appropriate

13:41 nDuff: Sonderblade: was the "sum a list of" being repeated intended?

13:41 technomancy: comp partial reduce + partial apply concat

13:42 Sonderblade: yes but reduce + isn't very good for a huge list

13:42 * nDuff would read "sum a list of lists of ints" as clear intent (and good grammar), but "sum a list of sum a list of ints" sounds like it could be a brain/keyboard failure.

13:42 Sonderblade: or for summing floats due to rounding errors

13:42 technomancy: Sonderblade: ...?

13:43 there's no way to work with floats without rounding errors

13:43 you can use apply + instead of reduce, but it works out to the same thing

13:44 Sonderblade: well the naive way of using reduce + produces bigger rounding errors than a smarter algorithm does

13:46 dnolen_: Sonderblade: not sure why you think reduce is bad for large lists. And rounding errors don't apply to your original question - ints. reduce is the way to go unless you need something more specific.

13:47 Sonderblade: and you can probably get a pretty decent performance boost by using the same code shape but switching to reducers for the case of list of list of ints.

13:50 Sonderblade: dnolen_: what if i have a list of floats then?

13:50 dnolen_: Sonderblade: it sounds like you want to do something different in that case. So implement whatever you think is best.

13:54 tanzoniteblack: Sonderblade: if you're really worried about round errors for some reason, and don't care about performance or memory, you can use reduce +'

13:55 Sonderblade: tanzoniteblack: i care about performance too

13:56 technomancy: performance, speed, convenience: pick any two

13:56 gfredericks: I can't imagine that + vs +' has anything to do with rounding

13:56 technomancy: err--s/performance/correctness/

13:57 Hodapp: technomancy: I usually see it as "fast, cheap, good"

13:57 technomancy: yep =)

13:57 gfredericks: or as devops_borat recently said

13:57 Sonderblade: e.g. this (println (reduce + (range 99999999))) is much slower than i thought

13:57 gfredericks: "enterprise, cloud, strategy"

13:57 tanzoniteblack: gfredericks: +' supports arbitrary precision, so if the number of bytes needed to correctly encode the number exceeds the current number type (int, float, double, etc.) it ups the number to a larger type (eventually to BigNum)

13:57 Hodapp: or sometimes "fast, cheap, good, Windows - pick 2 (Windows counts as 2)"

13:57 technomancy: Hodapp: I'll have to remember that one

13:57 clgv: Sonderblade: it performs boxing and unboxing ;)

13:58 gfredericks: tanzoniteblack: I really doubt the difference applies to floats

13:58 Sonderblade: clgv: now you understand why i asked for a sum function

13:58 tanzoniteblack: gfredericks: why wouldn't it?

13:59 gfredericks: ,[(* 3e250 7e250) (*' 3e250 7e250)]

13:59 clojurebot: [Infinity Infinity]

13:59 gfredericks: tanzoniteblack: because there's no easy way to do what you want with floats

13:59 kevin4567: why doesn't "lein test" run the tests specified by with-test?

14:00 gfredericks: tanzoniteblack: what should (+' 1e300 1e-100) do?

14:00 tanzoniteblack: should it change to BigDecimal because of rounding issues?

14:01 technomancy: kevin4567: that style is just very uncommon; lein test simply searches for namespaces in your test directory

14:01 tanzoniteblack: gfredericks: would there be a rounding error there?

14:01 gfredericks: tanzoniteblack: yep

14:01 ,[(= 1e300 (+' 1e300 1e-100)) (= 1e300 (+ 1e300 1e-100))]

14:01 clojurebot: [true true]

14:02 technomancy: kevin4567: running all src namespaces through run-tests would be unreasonable for most projects

14:02 gfredericks: apparently I didn't need such drastic exponents to demonstrate that

14:03 kevin4567: technomancy: thanks for the info

14:03 technomancy: kevin4567: you can specify test namespaces on the command line. maybe being able to read them out of project.clj would be a good feature?

14:03 gfredericks: ,(= 1e20 (+ 1e20 1))

14:03 clojurebot: true

14:03 kevin4567: technomancy: how do you specify the namespaces on the command line?

14:04 tanzoniteblack: gfredericks: apparently that doesn't work as I thought then

14:04 gfredericks: tanzoniteblack: with integers the situation is much simpler; but the issue isn't rounding, it's overflow

14:04 technomancy: kevin4567: you just ... specify them on the command line?

14:04 not sure what you're asking

14:07 kevin4567: technomancy: I think adding the dir to my project's :test-paths seems like the best solution... thanks again

14:07 technomancy: oh yeah, if all your src/ namespaces are likely to have tests that's probably best

14:08 kevin4567: technomancy: that is the case for me, yeah

14:10 dnolen_: Sonderblade: you haven't been clear as to what kind of performance you are looking for. Do you want to work on large primitive Java arrays? for that you have areduce. your expression takes ~6000ms on my machine. using areduce takes <100ms

14:14 m0smith: hi all

14:15 solussd: is it possible to make protocol implementations namespace private?

14:15 m0smith: is there some trick to getting add-watch to work in clojurescript on an atom? It seems to work but is never called

14:17 gfredericks: m0smith: I've used it a good bit without issues

14:17 * nDuff likewise has never needed any "tricks" to get atoms in cljs to work

14:18 m0smith: just calling swap! correct?

14:18 gfredericks: yep

14:19 m0smith: ok, thanks

14:20 gfredericks: once you're desperate enough you can try the JS debugger

14:20 m0smith: gfredericks: I was trying but it locked up firefox on the a deref of the atom

14:29 seangrove: m0smith: I'm using shoreleave's pubsub which is built on atoms and add-watch I believe, working well

14:30 m0smith: seangrove: ok, thanks it must be something I am doing wrong

14:30 dnolen_: m0smith: sounds like you might be accidentally doing some kind of recursive deref?

14:32 m0smith: dnolen_: maybe but the code works in that the atom is updated as expected, just the watchers don't get called

14:32 in clojure is works as expected, just clojurescript is not working

15:02 deg: Hi all... So, I decided today to abandon my misguided ways and switch to Emacs, rather Eclipse. (Only using Eclipse because I couldn't get nrepl to work when I first started with clojure a few weeks ago). Anyway, all attempts now are still failing, but I'm now familiar enough with the clojure env that I figure I need just a bit of help to get things working...

15:02 egghead: deg: with emacs did you try using technomancy's emacs-starter-kit ?

15:03 deg: Anyway, first attempt was in Windows 7, and I ran into problems with both clojure-jack-in and nrepl-jack-in, that they could not start the server. (no error, just hang)

15:03 So, I figured I'd try in a Ubuntu VM. Things came much closer this time.... Nrepl works, but I seem to be having a problem with the classpath.

15:03 egghead: ooo, windows... don't think I'll be much help there, though it might be a environment variables issue :/

15:04 deg: lein run works fine from the command line. But, I try a c-c c-k from an emacs buffer, and it fails to find the *__init.class of the first namespace in my ns

15:05 (for now, let's ignore the windows problems. If I get this working in Ubuntu, I'm happy for today).

15:05 technomancy: deg: did you do jack-in from a buffer inside the project?

15:05 deg: No.

15:05 Let me try that.

15:05 technomancy: ok, so in that case it will start a stand-alone repl that only has access to leiningen itself

15:06 deg: Sound like that's my problem. Let me just test. gonna be a moment or two. Thanks!

15:07 spiral68: if you have installed nrepl in emacs, you could connect to a running "lein repl" and type M-x nrepl...

15:07 bbloom: dnolen: i updated that ticket last night about the errors

15:07 dnolen: bbloom: yeah I checked it out earlier & left a comment as well.

15:08 bbloom: dnolen: did you take a peek at the second patch?

15:09 deg: Much closer now, but I don't seem to be in the right namespace.

15:10 dnolen: bbloom: I did, but I agree that it doesn't make sense. It's not communicating the correct environment.

15:11 deg: egghead: yeah, it works if I type the namespace explicitly, but I can't yet see how to put the repl into my namespace.

15:11 bbloom: dnolen: yeah, that's what i realized. but what i think we could do is to make a new exception class like CompilerError or something and then add a catch block for it and allow that one to pass through… that would be the right environment then, right?

15:12 technomancy: deg: C-c C-n should do it

15:12 C-c M-n rather

15:12 dnolen: bbloom: like I said in my comment - I don't see how that would be any different from the first patch, everywhere an error might occur you must pass along the environment in the exception. so it ends up looking like your first patch.

15:12 deg: Aha. https://github.com/kingtim/nrepl.el says C-c M-n but that seems to have no effect.

15:13 bbloom: dnolen: well every form goes through a call to parse, which does have the correct environment

15:14 deg: Hmm, and C-c C-n seems to do something -- shows a nil result. But, I'm still not in the right namespace.

15:14 I'm going to restart emacs. Maybe traces of the old repl are still running and getting in the way.

15:15 dnolen: bbloom: ok, so I guess we'd still have to change from assert to something that throws this new exception. Did you actually try to see if this works?

15:15 bbloom: dnolen: no, you don't need that change, you just only wrap it once. i started to do the change but realized it needed a custom exception type and i don't know anyhing about gen-class :-P

15:18 dnolen: the issue with that approach is gen-class needs AOT compilation and stuff, right?

15:18 dnolen: bbloom: hmm do we need to do that - we have ex-info

15:18 bbloom: in Clojure 1.4 I think for this exact purpose.

15:18 bbloom: dnolen: I don't know about ex-info

15:19 dnolen: bbloom: look for ex-info (and ex-data) http://github.com/clojure/clojure/blob/master/changes.md

15:19 bbloom: dnolen: ah ok, that'll probably do the trick

15:19 i'll give it a try

15:19 dnolen: bbloom: cool

15:20 deg: technomancy: Whoops, missed your comment above... but found the same answer. The M-x command works for me and is, indeed, bound to C-c M-n. But, looks like that keystroke is not going through Windows+VMWare+Ubuntu to Emacs. So, not a problem with clojure; something else in my env eating chars, I guess.

15:21 technomancy: deg: you can use ESC n if something is interfering with alt as meta

15:22 brainproxy: deg: if you're just getting started w/ emacs, I can recommend bbatsov's emacs "prelude":

15:22 https://github.com/bbatsov/prelude

15:22 gives you a nice base setup

15:22 deg: technomancy: Right. Forgot about that... too many years of emacs working right sinc ethe last time I had to use ESC.

15:22 Actually, I'm and old time Emacs user, going way back to Teco in 1978 or so.

15:23 technomancy: whoa nice

15:23 brainproxy: deg: ah, i see

15:23 deg: But, for the past many years, my "emacs" was the DOS/Windows Epsilon clone.

15:23 technomancy: I'd recommend reading through things like the prelude or starter kit for stuff to steal but not using them outright

15:23 Raynes: technomancy: Is someone else working on fixing partial selectors so they don't go into unnecessary namespaces? I can't follow that thread very well.

15:23 technomancy: Raynes: selectors in general, not partial selectors as such

15:23 deg: So, I'm not real up-to-speed on where Gnu emacs is different from Epsilon, ZMacs, or (gasp) Twenex Emacs.

15:24 Raynes: technomancy: Partial selectors, selectors, whatevs.

15:24 deg: Anyway, thanks for the help. I think I'm good now, until the next question.

15:24 technomancy: Raynes: 1.x does this, but I suspect only because it was added after 2.x branched

15:28 brainproxy: technomancy: there's enough wiring in the prelude that cherry-picking isn't really possible if you're a noob (in this case, deg isn't exactly a noob), however...

15:28 what's nice is you can stick whatever .el stuff you want in personal/

15:29 and it just works

15:29 technomancy: that's a shame

15:29 I specifically rewrote the starter kit to move most of the functionality out into independent packages for composability reasons

15:29 brainproxy: well for the most part anyway, so what a lot of people are doing is forking prelude, and then pushing their clones w/ their stuff in personal/

15:30 technomancy: but most of the people working on alternate starter-kits are moving in the opposite direction

15:30 maybe 3 years in they will turn around and start to consider composability =)

15:30 brainproxy: technomancy: I understand your reasoning, and it's probably the better approach all considered

15:30 _zach: Is there a reasonable way to extend a protocol to a java array type? (e.g. Byte[])

15:30 brainproxy: however, for getting started, it's hard to beat the prelude

15:31 technomancy: you could say the same thing of rails

15:31 p_l: I love starter-kit-24, but for god's sake, I think I need to bleach out the clojure parts

15:31 technomancy: easy to get started until you want to do something the authors didn't have in mind

15:31 bbloom: dnolen: yeah this works

15:31 dnolen: new patch incoming

15:31 dnolen: _zach: (extend-type (class (make-array Byte/TYPE 0)) ...)

15:32 brainproxy: technomancy: i get you; however, after spending almost a year w/ it, I've been able to do whatever I needed by just sticking some custom .el scripts in personal/

15:32 p_l: technomancy: does prelude also include the "brain dead opinionated decisions that cause horrible crap but are hidden from first time user" part of Rails?

15:32 _zach: dnolen: Awesome, thanks

15:32 dnolen: bbloom: sweet

15:32 brainproxy: p_l: probably the easiest thing is to just take a look :D

15:32 bbloom: dnolen: ticket updated

15:33 p_l: brainproxy: nah, Emacs is too important part of the OS to risk ;P

15:33 technomancy: p_l: I mostly just know of it from people with questions in #emacs

15:33 p_l: not when I needit everyday

15:33 though I was quite pissed today when launching slime while having nrepl open bollocked both

15:33 (and no, I didn't do anything by myself to setup association between slime and clojure)

15:34 brainproxy: p_l: trying it out isn't too risky; just copy your ~/.emacs.d to somewhere else, then start fresh with an empty .emacs.d and clone bbatsov/prelude into it

15:34 bbloom: dnolen: similar approach could be taken in compiler.clj with emit -> emit-form

15:34 dnolen: but most errors come from analysis at this point

15:34 p_l: brainproxy: that's when laziness comes in ;)

15:35 brainproxy: :D

15:39 dnolen: bbloom: what's the motivation for parse -> parse-form? seems like unnecessarily breaking code for anyone that might be using the analyzer right?

15:39 bbloom: seems better to add something like parse* which doesn't the exception wrapping and leave parse unchanged.

15:40 which does

15:40 bbloom: dnolen: it's only a breaking change if people are using defmethod on parse

15:40 dnolen: there still is a parse function

15:40 dnolen: bbloom: yes but why do we need a breaking change at all. just make a new entry point - none of those parse lines need to change right?

15:41 bbloom: dnolen: you need the breaking change because calling analyze pass through the try/catch

15:41 dnolen: er calling parse

15:41 parse is recursive

15:41 the alternative breaking change would be worse: every call to parse would need to be rewritten to parse*

15:41 tgoossens: In a game. I represent a robot as a map. Also there is a board. i'm trying to convince myself that i don't need identity for having a robot on the board. But i'm not sure. Because how i'm going to "move robot X forward on that board" "is robot x on this board?"

15:42 dnolen: bbloom: there is only one call to parse tho right? line 902

15:42 in analyzer.clj

15:42 tgoossens: Any advice in what direction i can look to help myself out here

15:43 S11001001: tgoossens: how many robots can be on the board

15:43 bbloom: dnolen: hmmm, i might have been thinking of analyze

15:43 tgoossens: since they cannot share position with another robot. As much as there are cells on the board

15:43 dnolen: bbloom: yes different

15:43 bbloom: dnolen: there are many calls to analyze :-P

15:43 dnolen: bbloom: yep

15:43 tgoossens: (so finite)

15:43 bbloom: dnolen: k, let me look

15:45 dnolen: hmm seems like i probably want the try/catch wrapper around analyze too

15:46 tgoossens: s11001001: i've been thinking about that it doesn't matter. "moving robot x forward" means "move the robot at position x,y that has certain properties, forward" but i think its getting tricky then

15:48 S11001001: tgoossens: you don't have to think about the rest

15:48 tgoossens: of the properties

15:48 (assoc robot :x new-x :y new-y)

15:49 tgoossens: why don't i have to think about the rest?

15:49 iosica: anyone writing unittest for macro?

15:49 S11001001: look at that assoc call, tgoossens

15:49 tgoossens: yes

15:49 S11001001: does it mention anything about the other properties of robot?

15:49 iosica: how do you compare with expected results when macros are using gensym ?

15:49 tgoossens: no. but what if suddenly i allow two robots to be at the same place

15:49 dnolen: bbloom: I don't see why we need it there. Why do you think we need it?

15:49 tgoossens: then the system is broken

15:50 S11001001: tgoossens: the call I just wrote allows two robots to be in the same place

15:50 bbloom: dnolen: if an exception occurs outside of a special form, the line reported will be the enclosing special form

15:50 cvkem_: I get some weird errors in clojure when processing larger volumes of data: "java.lang.ClassFormatError: Unknown constant tag 34". I seems like my data is transformed to a classfile ???

15:50 lazybot: cvkem_: How could that be wrong?

15:51 tgoossens: maybe i'm just not getting what you are trying to do :p

15:51 i know what assoc means

15:51 and i know what it does

15:51 but i don't see how it solves my problem

15:51 S11001001: (assoc robot :x 8 :y 43) puts a robot at 8,43

15:52 (assoc robot2 :x 8 :y 43) puts another robot there

15:52 tgoossens: so instead of keeping on the board on what position what pieces are

15:53 you give a piece a coordinate

15:53 S11001001: sure

15:53 tgoossens: ok

15:53 i was trying to make a "piece" independent of the "board"

15:53 but then again

15:53 maybe i'm forgetting that is doesn't matter here

15:54 because i can freely add en remove news key-vals to the map

15:54 without anyone caring

15:54 S11001001: indeed

15:54 tgoossens: hmmm yes

15:54 and

15:54 if there are two boards

15:54 and they both expect a piece which has an x coordinate

15:54 but x means y in the other boards axis

15:55 where in the program would you convert that

15:55 dnolen: bbloom: ah right, there are some asserts that are not w/in parse - but are at the analyze level.

15:55 tgoossens: meaning:

15:55 bbloom: dnolen: yup, v4 of path uploaded. much nicer :-)

15:55 S11001001: tgoossens: all your pieces are {..., :x ?, :y ?}. Means a function.

15:55 bbloom: dnolen: w00t code reviews.

15:55 tgoossens: ok cool

15:56 i think i get it

15:56 bbloom: dnolen: although if we want to do the same thing for compiler.clj, we'll probably need to rename emit to emit-form or something like that

15:56 dnolen: for the reasons prior discussed about better to break defmulti than to break emit callers

15:56 er defmethod

15:56 15 -> 6 -> 6 -> 2kb

15:56 tgoossens: i just came from java. So maybe that's where my thinking came from. Because of the interface of a piece that cannot be adapted

15:56 but in clojure you just at some key :p

15:56 bbloom: that's the way patch version sizes should look :-)

15:57 S11001001: tgoossens: there are more complicated ways you can separate coordinates, piece types, per-board data, and coordinate systems, in a functional setting, but they're easier to get right in Haskell. No need to overcomplicate things for yourself when something simple works.

15:57 tgoossens: cool

15:58 thanks a lot :)

15:59 still wondering whether at some point in the little game i'm making i'll need some references

15:59 *(ref *)

15:59 bbloom: dnolen: oops, small issue

15:59 S11001001: tgoossens: if your ad-hoc structures start to need separation, you can namespace your :keys

15:59 bbloom: dnolen: want that one wrapping-errors to also include the parse-invoke

16:00 dnolen: v5 coming i guess, heh

16:00 dnolen: bbloom: did you have chance to confirm that the patch actually catches the kinds of errors that were tripping you up on your own code base?

16:00 tgoossens: correct

16:00 bbloom: dnolen: yes

16:00 dnolen: bbloom: cool, I'll take it for a spin myself as well

16:00 S11001001: tgoossens: per se, you never *need* refs, and I think our large, ~1000-file clojure application at my previous job used, like, 7 of them, but that was just for hackishness

16:01 tgoossens: mm

16:01 interesting

16:02 for example robots must be able to exchange energy (tag :energy in the map)

16:02 my first way of thought was

16:02 refs and transactions

16:02 but i could just as well just return a vector (or map) of the two new robots

16:02 right?

16:02 clojurebot: to be fair I dunno that I've ever had code out right rejected, it just sits in jira or assembla or where ever, or if I ask if there is any interest (before writing any code) I get told to go write alioth benchmarks

16:02 bbloom: dnolen: v5 there too

16:02 S11001001: tgoossens: indeed, and that's the first (and likely last) thing I'd do too.

16:02 tgoossens: ok cool

16:03 jondavidjohn: So I've got this guy -> (take card_count (reduce into (mapcat (fn [c] (-> (inc (rand-int _rand_ceiling)) (take cards) (cons _new_cards))) cards)))

16:03 tgoossens: its hard to start thinking like that if two months ago all i knew was OO in java :p

16:03 jondavidjohn: and it almost does what I want it to do

16:04 S11001001: tgoossens: welcome to magic land

16:04 tgoossens: yeah the past two months have been the most interesting of all time for me (a humble student computer science in the third grade )

16:05 bbloom: dnolen: devn was asking me for help with an error he was encountering. i sent him patch v1 and it made it so he could track down the issue instantly :-)

16:05 jondavidjohn: but it keeps repeatedly taking the first N elements off the front of `cards` with take, I really want it to progress through `cards` as it removes elements from the front

16:05 tgoossens: a lot of the magic i found in destructuring. its fantastic

16:06 nevertheless thanks for the support ;-)

16:06 S11001001: np

16:07 TimMc: cvkem_: That's pretty bizarre. Is it repeatable?

16:07 dnolen: bbloom: no this is a great patch - errors at analysis time are so painful.

16:08 bbloom: I think this should catch ns errors too w/ file & line numbers etc :)

16:08 cvkem_: TimMc: it is very repeatible.

16:08 Raynes: dnolen: I got my first patch vetted by The Rich. :D

16:08 bbloom: dnolen: yeah, that's the benefit of the exception handling approach rather than throwing a special new type of error in select cases

16:08 dnolen: Raynes: sweet :)

16:08 bbloom: brb

16:08 Raynes: Not that you should care. Just wanted to tell somebody with cool hair and you're the closest.

16:08 dnolen: haha

16:09 ucb: I'm using aleph's tcp-client to implement a protocol, however the handshake of the protocol has different frames depending on the stage of the handshake. Is it possible to re-set the encoder/decoder of an already open tcp-client in aleph?

16:09 additionally, is there an aleph-specific channel?

16:09 TimMc: cvkem_: I'd love to see a reduced test case.

16:10 cvkem_: That is slightly more complex, as it runs as an integrated part of a web-framework.

16:10 Any suggestions when data is stored as class-files?

16:12 TimMc: Can you determine what your code is doing to provoke this?

16:12 cvkem_: The class-file is: 34 in class file vinzi/cdp/ns/pcCvrm$eval359 (where the $eval359 suggests that it is generated on the fly)

16:13 tgoossens: s11001001: just realized how fucked up the OO design was. a Piece was an object that could be either on a board or not on a board and had to have "class invariants" and that bullcrap

16:13 here it is as simple as

16:13 removing the :x :y keys

16:13 S11001001: tgoossens: you got it

16:13 tgoossens: also

16:13 a robot has an inventory of items

16:14 eg [battery1 battery1 battery2]

16:14 it doesn't matter "which one"

16:14 as long as they have the same values

16:14 it has "that" item

16:14 still wondering though because not all keys might match

16:14 probably a bad idea

16:15 gfredericks: does anybody using paredit-vim know the keybinding for splicing?

16:16 or where the docs for that are?

16:16 S11001001: tgoossens: Smalltalk has a structure called a "Bag". It is an unordered list, in that if you add the string 'hi' to it twice, you have a bag with two 'hi's in it. It's typically implemented as a map of unique items to an int indicating the count, because all 'hi's are created equal, so it only bothers to remember one of the actual values.

16:17 gfredericks: nm we got it

16:17 bbloom: gfredericks: https://github.com/vim-scripts/paredit.vim/blob/master/plugin/paredit.vim#L162

16:17 tgoossens: interesting

16:17 thats probably more useful

16:19 S11001001: since all batteries are created equal, if you have a list [battery battery battery], you can remove the first, you can remove the last, you can replace it with a list of two new batteries, and it's all the same

16:19 cvkem_: TimMc; the names-space vinzi/cdp/ns/pcCvrm is a namespace that is generated by code and that is filled dynamically with code via (clojure.core/load-string)

16:20 tgoossens: and if a certain battery has different properties then it is just "Another" type of piece in the inventory

16:20 S11001001: right

16:22 cvkem_: TimMc: the execution of the function is trigged by an (eval myFunc) or (eval myFunc params). Now I think of it, this eval is killing me as the parameter params is probably translated to an anonymous class

16:23 gfredericks: any guesses why my type Foo cannot be cast to Foo?

16:23 (given I've run `lein clean` since code changes)

16:23 brehaut: gfredericks: different class loaders?

16:23 tgoossens: cool i'm really getting the hang of this. And to avoid that robots can be in the inventory of another robot i could use taxonomies (isa? ::item) or a key that e

16:23 gfredericks: brehaut: wat? this is a really vanilla project

16:23 tgoossens: clojure is just so mindboggenly flexible i just can't believe it

16:23 brehaut: gfredericks: an AOT'd lib?

16:24 S11001001: tgoossens: yeah

16:24 cvkem_: TimMc: at least I think the eval is the issue. Earlier I also ran into problems as eval uses the undocumented print-dup function to pass parameters around.

16:25 gfredericks: brehaut: well I am doing gen-class on the ns

16:28 * gfredericks tries uberjaring it

16:30 brehaut: gfredericks: the clojure runtime does use its own class loader for the compiler i think

16:31 gfredericks: sure

16:31 I just don't understand why this would happen if I'm not doing anything weird

16:32 mpenet: Is this expected with extend-type on cljs? https://gist.github.com/4172023

16:32 looks like a bug

16:34 dnolen: still around?

16:34 dnolen: mpenet: extend-type on js/Object doesn't make sense

16:35 mpenet: you probably want extend-type default

16:35 mpenet: as far as the syntax- that quirk matches Clojure as far as I know.

16:35 mpenet: well its just an example, I had a similar issue with js/jQuery

16:35 and IFn

16:36 dnolen: mpenet: yes ^

16:36 mpenet: k

16:37 tgoossens: s11001001: ow cool I just realized what 'complecting' is about (in my robot example)

16:37 dnolen: mpenet: I could be wrong about that - if Clojure allows a more relaxed style for multiple arities of a protocol then it should be fixed.

16:37 mpenet: if you're allowed to do that in Clojure feel free to open a ticket in JIRA

16:38 mpenet: ok I ll check

16:38 tgoossens: i was thinking "when i create my robot how can be sure that it is on a correct position"

16:38 the thing is

16:38 you don't

16:38 at least not at that level

16:38 of the program

16:38 S11001001: yeah, "don't do that" is an important part of clojure philosophy

16:38 dnolen: mpenet: what I really meant was that - that limitation in CLJS predates my involvement

16:38 tgoossens: that would be complecting multiple stuff

16:38 and would be a pain

16:38 if you want to change the rules

16:39 S11001001: same applies to ensuring robots don't fit in inventories, incidentally :)

16:40 tgoossens: hmmm

16:40 yes :D

16:43 s11001001: ok i'm almost there! Last thing: Do you have something to say on this issue of mine: http://tinyurl.com/dyx7q95

16:44 its about collision detection and to check whether a certain piece can be on another

16:47 S11001001: tgoossens: marick's approach is good, and you can deal with the reverse problem by calling your collision function both ways

16:47 tgoossens: yes

16:50 oskarth: how can I find out that @foo is a dereffed atom rather than just the value that is stored in the atom? something like (type @foo) or (meta @foo)

16:51 jondavidjohn: can anyone help a clojure n00b with this? -> http://stackoverflow.com/q/13634761/555384

16:51 llasram: oskarth: mu. That depends on `foo`, not the value returned by `(deref foo)` (which is what `@foo` means)

16:53 oskarth: llasram: what do you mean? I'm traversing a form and want to define a predicate to find all @forms

16:53 tgoossens: cool.

16:53 a robot cannot share position with another robot

16:53 but can share position with itself

16:53 so thats a problem there :D

16:54 llasram: jondavidjohn: Just on your formatting q, the ->> macro can help a lot to avoid nesting and improve readability. (->> cards (mapcat ...) (reduce into ...) (take ...))

16:54 jondavidjohn: thanks

16:55 llasram: oskarth: Oh, ok. `@foo` is a reader macro which expands at read-time to `(deref foo)`. So if I understand correctly, you could look for all calls to `deref` and sort out the type of their argument

16:56 oskarth: I can do this: (= "clojure.core/deref" (str (first (macroexpand (quote @foo))))) but that's kind of...ugly

16:56 jondavidjohn: llasram: it's you again. :) yeah, I can my mind starting to work a little differently, not thinking as much in terms of mutability and looping, pretty interesting.

16:57 *...can feel my mind...*

16:57 oskarth: llasram: what do you mean by 'look at all calls to `deref`'? how would we do that?

16:57 mpenet: dnolen: jvm clojure seems to allow both: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L802 unless I am missing something obvious

16:58 llasram: jondavidjohn: It is me! Heh. But yeah, it was quite a mind-trip at first. I've been programming in Clojure every day for about a year now, so instead my code in other languages ends up looking weird and inverted to other people :-)

16:58 oskarth: There are several ways, depending on your larger goal. Taking a step back, may I ask what that goal is?

16:58 jondavidjohn: llasram: right right... I love languages that stretch me to think about problems differently

16:59 llasram: it is hard to compartmentalize though

16:59 dnolen: mpenet: there's not enough information there to confirm that. make a multi-arity protocol and actually try it.

17:00 mpenet: sorry I mean multi arity protocol fn.

17:01 oskarth: llasram: trying to traverse a hiccup-like form which represents the DOM, and inside it there are dereffed atoms. Writing a macro that maps these forms to 'events'

17:02 llasram: jondavidjohn: So just program in Clojure full time. Seems like the easiest solution.

17:02 muhoo: all you need is to find someone to pay you to do that.

17:03 * muhoo grumbles bitterly and goes back to writing java for money

17:03 mpenet: dnolen: you are right, it doesn't work, maybe the docstring could be updated on deftype though

17:04 dnolen: I guess the intention was to show how it could be done for single arity, then show multiple, but it can be interpreted differently imho

17:04 jondavidjohn: llasram: If only it could pay the bills...

17:04 llasram: oskarth: Check out http://clojuredocs.org/clojure_core/clojure.walk/postwalk That's probably your best bet

17:05 mpenet: dnolen: on extend-type I mean

17:05 oskarth: llasram: thanks! will do

17:06 dnolen: mpenet: I've been burned by in the past as well - I see 2 paths - rally to making extend-type more flexible (a lot of work) - or use the static information that we have about the protocol to give a descriptive error of the syntax violation (a patch)

17:07 mpenet: dnolen: the later seems good enough, yes

17:07 dnolen: mpenet: I honestly the last option is better than improving an already verbose doc string.

17:07 honestly think.

17:07 mpenet: better to have 1 way to do it also

17:08 dnolen: mpenet: the CLJS compiler has all the information it needs for good error warning here - feel free to open a ticket.

17:08 mpenet: dnolen: I think I ll open tickets for this on both clj and cljs, they both allow it

17:08 dnolen: mpenet: sure

17:09 mpenet: dnolen: cljs is a bit odd, it depends on what you extend, sometimes it works, sometimes not

17:09 dnolen: mpenet: what do you mean?

17:10 mpenet: dnolen: https://github.com/ibdknox/jayq/blob/master/src/jayq/core.cljs#L25

17:10 dnolen: there is a mix of the 2 styles on this file, see nth and lookup

17:11 dnolen: again, I might be missing something

17:11 dnolen: mpenet: yeah it's not clear to me how that every worked in jayq

17:11 ever

17:12 mpenet: dnolen: I am trying to clean this up, I stumbled on this while trying to kill the jQuery.prototype.call extension

17:16 actually only cljs allows this, I am getting confused :p

17:25 deg: technomancy, brainproxy: Thanks for those final bits (two hours ago). I had to run off for a bit, so missed them then.

17:26 wei_: what's a good way to send a clojurescript data structure along with the initial page load? I can ping the server after the page loads (I'm using noir and fetch), but I'd like to save an xhr.

17:34 dnolen: wei_: you could probably emit a script tag and populate with a call to CLJS compiler infrastructure directly - (cljs.compiler/emit (cljs.analyzer/analyze {:ns {:name 'cljs.user}} '{:foo 1}))

17:34 that will give you a string, "cljs.core.ObjMap.fromObject(["\uFDD0'foo"],{"\uFDD0'foo":1});"

17:40 bbloom: for the first time in 6+ months of writing clojure, i'm really wishing for some static type checks….

17:40 trying to write a dense little algorithm. keeping track of the various maps and sets and their values is hurting my brain

17:40 wei_: good idea. I would have to include the cljs compiler into my project then right? how would I do that since I'm getting "could not find cljs/compiler.clj on classpath"

17:41 dnolen: bbloom: so playing around with the patch - I note that you dump the env or is that because we use ex-info?

17:41 bbloom: dnolen: what do you mean "dump the env" ?

17:41 mpenet: wei_: dnolen: couldn't you just use cljs.reader/read-string instead? (on something like a script tag with type=text/edn)

17:42 dnolen: mpenet: nice idea

17:43 bbloom: at the repl if I type (let [x 1] (let [y])) I get a giant dump of the analysis environment this doesn't seem desirable

17:43 mpenet: dnolen: sounds like something I could add to jayq as well

17:43 wei_: bbloom: would clj-schema help for validating the maps?

17:43 bbloom: dnolen: oh, didn't try it in the repl. was working with lein cljsbuild auto

17:44 wei_: had no idea there was a clj-schema, was just thinking about the need for that the other day

17:45 dnolen: could use a different ex-info map entry rather than :env

17:45 wei_: there's also typed clojure but I haven't looked at it yet

17:45 dnolen: bbloom: are you saying because we use :env is why it gets dumped?

17:46 bbloom: dnolen: apparently: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ExceptionInfo.java#L40

17:47 dnolen: seems like lein cljsbuild is calling .getMessage, but nrepl is calling .toString

17:47 dnolen: how about I just put :line, :col, and :file into ex-data ?

17:47 dnolen: or something like that

17:48 dnolen: bbloom: :line, :column, :file and perhaps :tag - and we should use :tag as the filter when catching the exception?

17:49 bbloom: dnolen: what would :tag be? :cljs/CompilerError ?

17:49 dnolen: bbloom: AnalysisError no?

17:49 :cljs/analysis-error ?

17:49 bbloom: dnolen: well we could do this same thing for emit at some point

17:50 analysis plus code generation == compiler. compiler.clj is a misnomer right now :-)

17:50 dnolen: bbloom: really? someone might use the analyzer w/o the compiler

17:51 bbloom: dnolen: so if we add wrapping-errors to compiler.clj, should that have a different :tag ?

17:51 dnolen: yes

17:53 bbloom: dnolen: i'm not convinced about that, but we can always deal with that when the issue arises

17:53 dnolen: I'll tweak the patch to include those keys

17:53 wei_: mpenet: works great, thanks. what does text/edn mean?

17:54 mpenet: wei_: possible mimetype for edn, just like text/js with js on script tags

17:54 wei_: and I guess to prevent some (old) browsers to interpret it as js

17:54 dnolen: bbloom: I see no reason to not deal w/ it now. projects like cljs-lua have already shown the analyzer can be used by itself.

17:55 bbloom: dnolen: i meant deal with the differing name when we get to better error reporting in compiler.clj

17:55 wei_: oh, this edn (https://github.com/edn-format/edn). gotcha

17:57 dnolen: bbloom: it's not an error generated by the compiler - so I see no reason to claim that it's a compiler error. :cljs-lua/compiler-error :cljs/compiler-error :cljs-scheme/compiler-error etc seems about right to me.

17:57 bbloom: dnolen: ok

17:57 dnolen: bbloom: we actually have a nice parse-ns fn now in analyzer - the kind of thing you'd want to use w/ datomic - :compiler-error makes no sense.

17:58 er codeq

17:58 bbloom: dnolen: i was mainly concerned with a common source code error, so there is an easy way to test for an error without having to know all the potential sources

17:59 dnolen: you're right, the name compiler-error doesn't make sense, but call it :foo-error and it would be easier to tell "has this error already been wrapped up with environment info?"

18:06 dnolen: bbloom: I don't know what you mean. how is that different from :cljs/analysis-error ?

18:07 bbloom: dnolen: this patch currently only improves error reporting in the analyzer. if we also improve error reporting in the code generator, then we'd still only want to wrap ex-info onto the error once, not multiple times. if they use different tags, then the should-i-wrap-this? predicate needs to test for both tags

18:09 mpenet: wei_: I just added this functionality to jayq (also fyi fetch has a nasty bug with persistent datastructures, I would be careful)

18:10 ibdknox: If you are around, any chance of merging the PR that fixes that (fetch #14)?

18:10 bbloom: dnolen: anyway, v6 is up http://dev.clojure.org/jira/browse/CLJS-432

18:10 dnolen: bbloom: so you're afraid a second level of wrapping - perhaps I don't really understand ex-info, but I don't see how that would happen. analysis throws an analysis error, compiler catches doesn't know what to do w/ it and just throws it right?

18:11 bbloom: dnolen: what if an exception is thrown in the compiler?

18:11 dnolen: outside of analysis

18:12 dnolen: bbloom: it throws it's own ex-info error, right? what's the problem?

18:12 wei_: cool, I am using jayq. re: fetch, are you talking about this issue that you fixed recently? https://github.com/ibdknox/fetch/pull/14

18:12 mpenet: wei_: yes

18:13 bbloom: dnolen: well yeah, but then you wind up with duplication in error handling mechanisms. as the number of AST passes increase, we want to have 1 error handling mechanism, not N == number of passes :-)

18:13 dnolen: i'm just happy to have analysis errors reported clearly. we can deal with expanding the error handling strategy later

18:15 wei_: mpenet: nice. what's the easiest way to apply the fix? are you on clojars?

18:15 mpenet: nope I am not but I can push a version with the fix

18:16 under my ns

18:19 wei_: https://clojars.org/cc.qbits/fetch

18:19 wei_: mpenet: tyvm

18:21 bbloom: dnolen: does that new patch look good?

18:29 i'm wondering how other people handle this reoccurring functional programming issue that I encounter….

18:29 let's say you have a nested data structure that you plan to manipulate across several iterations of an algorithm

18:30 and you're "mutating" the various odds and ends in that data structure

18:30 it seems useful to separate identity and value, so sometimes i'll "flatten" the structure and replace the value with a gensym that represents the identity

18:31 like, if you had a graph with nodes and edges represented by {:a #{:b :c} :b #{} :c #{}}

18:32 and you wanted to "name" the edges, you could replace the :b and :c with 'edge__123 and 'edge__124

18:32 does this make sense at all?

18:36 jondavidjohn: I'm using partition-by to split up a collection into chunks, and I want to randomly size the chunks up to a given max so I can say that each chunk can't exceed that max number of items.

18:40 bbloom: jondavidjohn: can you give an example to clarify?

18:49 jondavidjohn: ,(partition-by (fn [i] (= 0 (rand-int 5))) [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20])

18:49 clojurebot: ((1 2 3 4 5) (6 7 8 9 10 ...) (15 16 17 18) (19 20))

18:50 jondavidjohn: ,(partition-by (fn [i] (= 0 (rand-int 2))) [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20])

18:50 clojurebot: ((1) (2 3 4 5) (6 7 8) (9 10) (11 12 13) ...)

18:51 jondavidjohn: so see how it's producing chunks bigger than 2? I understand why, but I'd like the chunks to have max # of items, but randomly chunked up to (and including) that max.

18:51 bbloom: ^

18:51 AimHere: Why not repeatedly invoke (partition (rand-int n) ...) on your sequence?

18:52 metellus: ,(doc partition-by)

18:52 clojurebot: "([f coll]); Applies f to each value in coll, splitting it each time f returns a new value. Returns a lazy seq of partitions."

18:52 AimHere: Or perhaps the increment of (rand-int n)

18:52 bbloom: jondavidjohn: ah, i see

18:52 metellus: jondavidjohn: that means that the length of a partition is really the amount of times in a row (rand-int 2) gives the same number

18:53 jondavidjohn: metellus: right, but I'd like to do it without having to track that

18:53 bbloom: &(take 5 (repeatedly #(rand-int 5)))

18:53 lazybot: ⇒ (2 1 2 0 2)

18:53 bbloom: &(take 5 (repeatedly #(rand-int 5)))

18:53 lazybot: ⇒ (2 1 3 2 4)

18:54 bbloom: seems like a more reliable strategy, then use that with take/drop pairs

18:54 jondavidjohn: my non-functional mind thinks I need to track how many times it gives the same number and force it the next time around.

18:55 bbloom: jondavidjohn: you're better off with a split-at in a lazy-seq loop

18:55 AimHere: I'd concoct a function that 'take's a random number less than your maximum, and lazily spits out the subsequences

18:55 arohner: Raynes: with conch, is there a way to use (cd)?

18:55 AimHere: ,(doc split-at)

18:55 clojurebot: "([n coll]); Returns a vector of [(take n coll) (drop n coll)]"

18:55 AimHere: Or that

18:55 hughfdjackson: why does (repeat 3) crash my repl?

18:56 :D it seems an odd thing to do so; i expected it'd just be an infinite seq of `3`s

18:56 bbloom: hughfdjackson: you're repl is likely trying to print an infinite sequence

18:56 hughfdjackson: d'oh

18:56 that would explain it

18:56 bbloom: hughfdjackson: try binding *print-length*

18:57 Raynes: arohner: To change the current directory? No, but you can pass a :dir option as per the readme.

18:58 arohner: Raynes: ah, thanks

18:58 I did "read" the readme, but I was looking at :env vars instead :-)

18:58 hughfdjackson: bbloom: apparently the lein repl doesn't declare itself rebindable

18:58 bah!

18:58 thanks for the answer none the less :)

18:59 Raynes: arohner: Actually, the readme doesn't seem to show any :dir examples, but it should work. If not, open an issue and I'll fix it tonight.

18:59 arohner: :dir works

18:59 Raynes: Great

18:59 arohner: The readme only contains (print (sh/stream-to-string (sh/proc "ls" "-l" :dir "lib/") :out)), which is a little subtle

19:00 Raynes: Yeah, I need to add an example for conch.sh too

19:00 arohner: great lib

19:00 Raynes: <3

19:01 arohner: I might extend it to support SSH

19:03 bbloom: jondavidjohn: did you come up with a solution?

19:04 jondavidjohn: here's what i got: https://www.refheap.com/paste/7164 somebody can probably do a shorter/better version too :-)

19:10 AimHere: bbloom, mine looks very similar

19:11 THe only real difference is the check-for-emptiness at the start

19:11 Also, I think you have a bug

19:12 rand-int can sometimes return 0, which is maybe not a good thing to have here

19:57 nsxt: has anyone worked through let over lambda?

20:21 lynaghk: I'm using Compojure to fetch data a 3rd party API, munge it, and then serve it up over http. The data isn't personalized in any way. Would it make sense to write a caching layer in Clojure (to limit duplicate API calls) or should I put a cache directly in front of the Compojure instance?

20:25 brehaut: lynaghk: if its truly doing nothing at all, use a caching front end server

20:25 no need to reimplement it in clojure

20:25 bbloom: lynaghk: yeah, no sense reinventing the wheel. just a few lines of varnish config should do the trick

20:25 brehaut: or even just nginx proxy pass caching

20:26 bbloom: either way

20:26 brehaut: nginx isnt as impressive as varnish, but it'll still do the job just fine for a lot of basic caching needs

20:26 bbloom: agreed

20:26 lynaghk: brehaut: yeah, that's what I was thinking. The only tricky part is that sometimes the requests are coalesed. E.g., a single http request fetches data for IDs 1, 178, 387, and 43.

20:27 brehaut: I could split apart the requests in the client, but having 5--10 simultanious HTTP requests from a mobile app sounds like trouble.

20:27 brehaut: im not sure i understand; if you have frontend server → clojure app → api

20:27 bbloom: lynaghk: how are the batch requests formulated? as query params? json data? what?

20:27 lynaghk: bbloom: it's flexable. Right now it's query params

20:28 brehaut: lynaghk: also, if you are implenting a cache in clojure, its worth looking at core.cache first

20:28 lynaghk: brehaut: yep.

20:28 brehaut: oh, yeah, that's what I was looking at. Just thought I'd poll #clojure about the relative merits of thaht vs. something out of process.

20:28 brehaut: i'd go out of process myself

20:29 HTTP cache is a solved problem

20:29 even if you set up varnish between your app and the API

20:29 bbloom: lynaghk: are the individual looks ups expensive? or is it the network round trip? or what's the slow part?

20:29 lynaghk: how likely is the same batch request going to happen multiple times?

20:30 lynaghk: ie. is it worth it to cache batches? or do you really need to cache individual items

20:30 lynaghk: bbloom: the batching is just so the moblie app can ask for new data all at once; no batching going on between the backend server and 3rd party API

20:31 bbloom: lynaghk: ok, is the 3rd party api the slow part?

20:31 lynaghk: bbloom: yeah, slowest right now. I haven't done a ton of benchmarking to see when Compojure falls over

20:32 bbloom: lynaghk: could you put the nginx or varnish cache in front of the 3rd party api?

20:32 lynaghk: bbloom: so it sounds like I could do a varnish cache between Compojure and the 3rd party API

20:32 bbloom: lynaghk: bingo :-)

20:33 lynaghk: bbloom: of course, if I unbatch the requests I can save Compojure from having to do a ton of repeat work. I'll look into HTTP request overhead and see if it makes sense

20:33 bbloom, brehaut: thanks for the tips. I wouldn't have thought to put Varnish between my server and the 3rd party API, which sounds rad.

20:33 bbloom: lynaghk: yeah, request overhead is bad unless you've got Keep-Alive enabled

20:34 lynaghk: but in general, HTTP is a terribly broken protocol when it comes to concurrency

20:34 lynaghk: keep alive will only save you the connection overhead… but there still isn't any pipelining really

20:34 Luyt: What to think of http://programming-motherfucker.com/

20:34 bbloom: i mean the HTTP spec has pipelining, but so many servers are broken, that most browsers don't do pipelining

20:35 lynaghk: bbloom: hmm. I think I'll tackle it one bit at a time. Once jetty becomes the bottleneck that'll mean our app is very successful =D

20:35 bbloom: lynaghk: luckily, most browsers will have a keep-alive connection pool of 4 or 6 or so connections per domain. so you'll get some concurrency there and just keep-alive should be good enough

20:36 lynaghk: all i'm saying is that you should make sure your HTTP response headers include "Connection: Keep-Alive" when measuring request overhead :-)

20:37 lynaghk: bbloom: thanks for the pro tip; I'll check that in right now.

20:38 muhoo: how would you even do pipelining in ring/jetty anyway?

20:38 Guest14063: Hello, On behalf of 3 bachelor thesis project.

20:38 bbloom: lynaghk: often keep-alive is off by default because it introduces some subtle state into an otherwise stateless protocol. can cause odd confusing bugs if you're proxying to various backends

20:39 lynaghk: bbloom: you mean if the HTTP connection from the client goes through a few proxies before it hits my server?

20:39 dyba: does anyone know of a Clojure library that automatically runs your tests in the background?

20:39 If you're familiar with Ruby, I'm looking for the Guard equivalent for Clojure

20:40 bbloom: lynaghk: we ran into an issue where we had some app mounted at /foo and another mounted at /bar … when we set keep alive, and you navigated in your browser from /foo/xyz to /bar/abc, then you got an error from the server that was serving /foo … b/c the browser pools connections by domain, not by path

20:41 lynaghk: bbloom: ah. Subdomains would aleviate that potential issue, no?

20:42 bbloom: lynaghk: yes, but they introduce a new issue: Cross Domain Origin Policy :-/

20:42 er Single Origin Policy? whatever it's called

20:42 brehaut: derp-hard :/

20:42 lynaghk: bbloom: any apps would be totally independent

20:43 bbloom: lynaghk: then that would be fine :-) our case was like /app and /api

20:43 lynaghk: bbloom: the client is iOS, so cross-domain stuff isn't an issue

20:43 bbloom: ahh. yeah. trouble.

20:43 bbloom: lynaghk: even better :-)

20:43 lynaghk: bbloom: c2po client is getting polished up with some docs, and it has the livereload server built in as you suggested

20:44 bbloom: you want to schedule a time to skype and kick the tires on it?

20:44 bbloom: lynaghk: could do that. what's the skype about? you want to observe me try to use it? or you want feedback after i try it?

20:44 lynaghk: bbloom: yeah, behind the preverbial mirror

20:46 bbloom: bbloom: um ok, not sure what i'd graph with it tho :-) i'd need a goal

20:46 er lynaghk: not bbloom:

20:47 lynaghk: bbloom: yeah, I'm writing up some basic docs. I'll ping you early next week with the details and maybe a use-case or two if you don't have any data of your own you want to dig into

20:47 bbloom: lynaghk: yeah, email me when you're ready

20:51 dyba: haven't found a Clojure tool that automates test runs after saving files. Does anyone know of such a tool?

20:51 muhoo: dyba: midje

20:52 dyba: muhoo: oh yeah? I'll take a look right now

20:52 brehaut: lein-autotest/lazytest?

20:55 dyba: brehaut: that's it! lazytest is what i've been looking for. Thanks!

21:13 arohner: did clojure.contrib.except/throwf get migrated anywhere?

21:14 bbloom: arohner: not familiar with it, but is it just a non-special form of throw? would #(throw %) suffice?

21:15 arohner: (throwf "an exception message") => (throw (Exception. "an exception message"))

21:15 * gfredericks could have used that at least a hundred times

21:15 arohner: it also does (throwf "a %s message" "exceptional"), but I can live without that part

21:16 bbloom: #(throw (Exception. %))

21:16 :-P

21:16 wei_: when writing leiningen plugins, how does one test locally?

21:16 arohner: thank you :-)

21:16 bbloom: but yeah, i wish that the special form was throw* and that throw was a function

21:20 gfredericks: #(throw (ex-info % {:wat :happened}))

21:22 seangrove: wei_: What kind of plugin are you writing?

21:23 wei_: deploying clojurescript assets to s3

21:24 seangrove: Ah, nice

21:24 No idea on testing, sadly, as I'm sure you've seen on the ml

21:29 Sgeo__: Wait, throw is a macro?

21:29 Why?

21:29 clojurebot: Why is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone

21:29 wei_: seangrove: it's pretty easy to deploy to clojars, so that'll work

21:29 seangrove: Is there a macro like thrush that takes the a form and then pass it as-is to each subsequent sexp?

21:30 ,(let [x 10] (- x 4) (- x 6))

21:30 clojurebot: 4

21:30 seangrove: I suppose let is essentially that, with a bit of extra typing

21:31 Sgeo__: doto?

21:31 ,(macroexpand '(doto (a b c) (d e) (f g)))

21:31 clojurebot: (let* [G__56 (a b c)] (d G__56 e) (f G__56 g) G__56)

21:31 Sgeo__: Oh, guess not

21:32 gfredericks: well nearly

21:32 if all he wanted was side effects that's basically equivalent

21:32 Sgeo__: Well, if the things are macros...

21:33 Then you don't want to use let like that

21:33 possibly

21:34 seangrove: No problem, I just see this pattern a lot using the closure library

21:34 It's not horrible, but it could really use a nice cljs library to wrap it and make sense of it

21:42 devn: Anyone see https://github.com/micha/hlisp-starter/blob/master/PROJECT.md?

22:54 Sgeo__: If I'm tempted to do metaprogramming with run-time shenanigans rather than macroexpand-time shenanigans, does that mean Ruby is likely to be a better fit for me than Clojure?

22:56 arohner: Sgeo__: not really. Clojure can do more than enough run-time shenanigans

22:56 though they're still very different

23:34 zeiris: HI! I've never used clojure, but am familiar with Java/Haskell/a Lisp. I want to hack together a data visualization app: I want a really responsive and clean-looking UI (most likely custom) with (probably) detailed raster graphics involved.

23:35 Could anyone point me towards good UI library starting points? I remember some of the worrydream.com based UI experiments used clojure - possibly through a web service, but still a starting point.

23:35 devn: zeiris: seesaw is worth a look

23:35 zeiris: (The reason I want to use clojure, is I strongly suspect I'll want to spend a bunch of time tweaking a data transformation DSL. None of the other languages in my toolbag really suit that.)

23:37 devn: zeiris: i might be misunderstanding your needs, but seesaw is basically java's swing, but not as big of a bummer to use

23:37 and it supports theming

23:38 is that what you mean by UI?

23:38 zeiris: quil would probably be another good place to look (processing in clojure)

23:40 Sgeo__: re: you're previous question about ruby. it depends on how much you enjoy the ability to shoot yourself in the foot.

23:40 Sgeo__: It's fine as long as all doing so is deliberate.

23:40 devn: right, until it isn't ;)

23:41 or until another developer needs to add a feature

23:41 Sgeo__: And as long as it is not idiomatic to make shooting oneself in the foot more likely.

23:42 zeiris: devn: awesome, thanks - that should be a decent starting point for clojure-y abstractions, if not the final library choice :)

23:44 devn: zeiris: godspped!

23:45 Sgeo__: i don't know specifically what you're trying to do, but my experience is that some of the iffy metaprogramming that i used to do in ruby feels much more elegant in clojure

23:46 just as in ruby you're allowed to make mistakes, but i think it's a bit more obvious when you're walking down that path in clojure

23:48 Sgeo__: anyway, it seems like you're asking a question that can be answered without trying it. do some of this metaprogramming stuff in clojure and then weigh it against your ruby impl.

23:48 s/can/can't

23:48 Sgeo__: I haven't touched Ruby in a while

23:49 It's just a language that comes to mind when I think of run-time metaprogramming

23:49 A

23:49 Although now that I think of it, surprised Smalltalk didn't come to mind first

23:49 devn: so why the question about ruby vs clojure? try it in clojure. that will ultimately be your answer

23:50 or smalltalk vs clojure, or whatever. try it in both and then you have some kind of base expectation to go off of

23:51 take something to the extreme to understand the dosage

Logging service provided by n01se.net