#clojure log - Sep 05 2014

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

0:00 ddellacosta: Licenser: sorry to hear that. :-(

0:00 Licenser: I'm demanding ;)

0:02 justin_smith: Licenser: yeah, it's kind of a brittle set of tools altogether

0:02 which emacs mode are you using?

0:03 dgaffney: Hey, sorry to bother y'all again - one more stumbling bock around doseq/map/seq/iterations over maps in general - can one of y'all translate this gist? https://gist.github.com/DGaffney/f13aa6c176240ecf2ffd

0:03 maybe a better way to say that would be to wrap it functionally...

0:04 updated.

0:04 Licenser: justin_smith wsomething I ended up with, and paredit :D

0:04 dgaffney: (that's what I'm trying to do in clojure as a ruby version (i'm so sorry.)

0:04 justin_smith: dgaffney: I don't know ruby, what would that output?

0:04 dgaffney: "one,1\ntwo,2\n"

0:05 thats what str would equal after the iteration.

0:05 I've been googlin' about but I'm not seeing the exact thing I'm looking for (which is the case for all my questions, obviously)

0:06 justin_smith: ,,(apply str (mapcat #(apply format "%s,%s\n" %) {:one 1 :two 2}))

0:06 clojurebot: ":one,1\n:two,2\n"

0:07 dgaffney: (Y) (Y) (Y)

0:07 hmm..

0:08 is all i'm missing really just mapcat instead of map/doseq/seq?

0:08 justin_smith: if you used strings as keys rather than keywords the output would match excctly

0:08 dgaffney: I have code that would work if it returned things.

0:08 justin_smith: or you could wrap the kw arg in a call to name

0:08 dgaffney: mapcat is for when each element returned is a sequence, and they should all be joined into one sequence

0:08 dgaffney: mm, sounds useful. and the # operator is for?

0:09 justin_smith: shortcut for fn

0:09 dgaffney: mm

0:09 justin_smith: ,(apply str (map #(apply format "%s,%s\n" %) {:one 1 :two 2}))

0:09 clojurebot: ":one,1\n:two,2\n"

0:09 justin_smith: actually I did not need mapcat there

0:10 the secret sauce was apply - turns the list from map into varargs to str

0:10 well, to format also :)

0:10 dgaffney: mostly following :)

0:11 justin_smith: apply takes any number of args, and unwraps the last arg (which must be a list) to make all the remaining args to the function that is the first arg

0:12 ,(apply + 1 2 [3 4 5])

0:12 clojurebot: 15

0:14 dgaffney: and what is % called in clojure world for increased googleability?

0:14 justin_smith: it is a token that means "the first arg" inside an fn made with #()

0:15 ,(macroexpand-1 '#(+ 1 %))

0:15 clojurebot: (fn* [p1__103#] (+ 1 p1__103#))

0:15 justin_smith: hopefully that helps

0:15 ,(macroexpand-1 '#(apply + 1 %&))

0:15 clojurebot: (fn* [& rest__128#] (apply + 1 rest__128#))

0:15 justin_smith: the varargs version

0:15 ,(macroexpand-1 '#(+ 1 % %2))

0:15 clojurebot: (fn* [p1__153# p2__154#] (+ 1 p1__153# p2__154#))

0:15 justin_smith: the two arg version

0:16 that's most all you need to know about #() and % (I assume you can guess what %3 or even %1 would mean)

0:24 munderwo: ddellacosta: so I’ve got austin working in the browser so thats good. What about the noderepl side of things. i found bodil/noderepl is that the best one to try?

0:24 ddellacosta: munderwo: sorry, I can't offer any good advice on that front, haven't touched node at all. :-(

0:25 munderwo: ahh bugger.. I do always try to use the most esoteric parts of a stack however, so I’ve only got myself to blame. Im stabbing around with node-webkit which adds complexity to the matter :)

0:26 on another note which is the real root of my problem I have a javascript lib that I need to do “var something = foo.bar.baz(arg1, arg2, func1)

0:27 I know how to call a method on a javascript function. But I dont know how to get further down in the next.

0:28 gratimax: (.baz (.bar foo) arg1 arg2 func1)

0:28 TheMonarc: ca

0:29 baz

0:29 munderwo: yeah thats what I thought. But I think that actually comes out as foo.bar().baz(arg1 arg2 func1)

0:30 justin_smith: munderwo: (-> foo .bar (.baz arg1 arg2 func1))

0:30 TheMonarc: car o cdr

0:31 justin_smith: munderwo: to unambiguously get properties rather than methods, use .-bar

0:31 munderwo: ahh!!! I think that might work!

0:31 justin_smith: (-> foo .-bar (.baz arg1 arg2 func1))

0:31 the -> syntax makes the mental conversion with js much easier

0:32 gratimax: yeah, I forgot about that -. A bit rusty in clojurescript

0:32 munderwo: yeah. Its a really wierd js lib.

0:32 .bar is actually a function. but with another function under it…just wierd

0:33 justin_smith: ok, don't use .-bar for a function, use .bar

0:35 munderwo: huh.. actually I did need it to be -bar .. thanks!

0:35 gratimax: .- is for values, . is for calling functions

0:36 munderwo: wierd js lib….

0:38 gratimax: not sure what you mean, that's not strange, that's just how clojure works

0:38 clojure has no such thing as objects with properties. the closest thing is maps

0:38 so any s-expression is asssumed to be a function call, which unfortunately does not work with JS

0:39 justin_smith: gratimax: records are like objects with properties too

0:39 gratimax: and deftype, if you have a strict set of properties to set

0:40 dgaffney: blergh - justin_smith that wasn't exactly what I was looking for :(

0:40 justin_smith: dgaffney: so what are you trying to do?

0:40 dgaffney: care to answer one more q before I off for the night? I know new people are annoying some times, I'm trying to minimize that.

0:40 I promise what I'm working on is cool though...

0:41 justin_smith: ~ask

0:41 clojurebot: The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question.

0:41 tac_: ~ask May I ask why that is?

0:41 clojurebot: Pardon?

0:41 gratimax: justin_smith: but the thing is we never use the record properties outside the scope of the record declaration or method declaration

0:41 justin_smith: gratimax: wat

0:42 dgaffney: https://gist.github.com/DGaffney/9de267eeb1a337a7a531 < this thing.

0:42 clojurebot has a much better ask response than ruby channel does.

0:42 justin_smith: dgaffney: do you want a proper *ml templating lib, or is this an exercise?

0:43 dgaffney: I'm trying to setup a namespace that will convert what will be a series of nested maps into a specific *ml, GEXF

0:44 justin_smith: https://github.com/cgrand/enlive I like enlive for html manipulation

0:44 dgaffney: The reason for homerolling is that the rules for this document are specific enough and annoying enough that writing it as a homerolled thing is much less a pain than doing it any other way in my experience

0:44 justin_smith: Raynes also has a templating lib, https://github.com/Raynes/laser

0:44 OK

0:46 dgaffney: I think that if I see a demo of some code given that input/output I'll have enough to finish up this file, which should be sufficient to get to the place I want to be.

0:46 which means I'll stop bothering you all!

0:46 gratimax: justin_smith: the point I was getting at is that it is just semantics. clojurescript needed the extra .- out of necessity

0:46 dgaffney: ... until I start learning how to use futures ...

0:47 justin_smith: gratimax: ahh, right, because we have other ways to make sure the method on the thing and the property of the thing are unambiguous (though we now can use .- in jvm clojure too)

0:48 dgaffney: do you want something fully general that walks the input, or is the input totally predictable in structure?

0:48 dgaffney: the keynames and values will differ but the general structure will be the same, justin_smith

0:48 gratimax: justin_smith: exactly

0:59 dgaffney: what says you, justin_smith?

1:01 justin_smith: dgaffney: something like this https://www.refheap.com/89828

1:01 it's a bit ugly, I think the output is right

1:01 err mostly

1:01 you will have to turn k into (name k) I think in the prop fn

1:02 dgaffney: mm

1:03 hah, tried (str k) immediately

1:03 justin_smith: and probably turn the (apply str (map ...)) in contents into another string/join

1:03 dgaffney: lemme try that.

1:03 that's exactly it.

1:03 awesome.

1:03 now, to wrap that into a file write

1:03 then its all amazing

1:03 justin_smith: it's ugly and not very general, but at least it is somewhat clear

1:04 dgaffney: yes - I'll learn and play with it.

1:04 Alright, I'm signing off for the night. Thanks for all the help through the day, justin_smith!

1:04 great first day in the clojure world. You guys are pretty nice.

1:05 justin_smith: also, if it ends up being a performance bottleneck, the jvm has StringBuilder that does the equivalent of s += s2

1:05 dgaffney: mm

1:05 I doubt it will be a bottleneck, coming from ruby ;)

1:05 but yeah, I'll check out StringBuilder.

1:06 justin_smith: well, immutible things are easier in general

1:06 dgaffney: I'm learning that.

1:06 alright, night!

1:06 justin_smith: good night

1:06 dgaffney: thank you, seriously. You shaved off hours of this exercise in learning a new language in what was way too many years in rubyland.

1:06 night!

1:47 bcm: is there something like paredit, but for html?

1:50 ddellacosta: bcm: ask in #emacs? although probably someone around here knows too

1:50 gratimax: bcm: closest thing I can think of in the ballpark is emmet, but I don't think that's for emacs

1:51 well, wait. no such tool exists, because there are some tags without closing tags

1:51 like img, input, and probably more

2:01 bcm: damnit that's why

2:02 wow dave, nice oauth+friend work

2:22 ddellacosta: bcm: sorry was away. thanks. :-) A bit behind on updates to the lib though, unfortunately.

2:54 mpenet: seanaway: jetty9 (server and client) support websocket and there are adapters for it, ex https://github.com/mpenet/jet

3:15 babygau: could anyone please explain core.reducers in layman's term. I'm not Eng native speaker so I find it difficult to understand from @rich hickey's article

3:22 bcm: ddellacosta: aren't we all 1/2 away. I'll probably use your lib for my current project: www.elgethub.com

3:26 ddellacosta: bcm: neat.

3:30 bcm: anyways, if you need a hand with it, ping me

3:30 bcm: at least, the oauth2 stuff.

3:51 babygau: could anyone please explain core.reducers in layman's term?

5:35 sm0ke: what the easiest way to dump some bytes to a file and read them back

5:35 into array of same length

5:36 clgv: sm0ke: ObjectOutputStream or DataOutputStream wrapped around FileOutputStream

5:36 sm0ke: ugh thats easy? i was hoping something like spit and slurp

5:37 clgv: sm0ke: or one of the serialization libraries

5:37 sm0ke: dont worry about serialization , given data is just ##(.getBytes "abc")

5:37 lazybot: ⇒ #<byte[] [B@39147d0f>

5:37 clgv: sm0ke: nippy or carbonite?

5:38 sm0ke: serialization to files, I meant ;)

5:38 sm0ke: ,(spit "/tmp/ok" (.getBytes "foo"))

5:38 clojurebot: #<SecurityException java.lang.SecurityException: denied>

5:39 clgv: sm0ke: I have one myself that is battle-tested in our projects. there you'd just do (quick-freeze "foo.data" "abc") or (quick-freeze "foo.data" (.getBytes "abc"))

5:40 sm0ke: it's that one https://github.com/guv/frost

5:41 sm0ke: nice but it looking for something raw

5:41 i am*

5:41 i am trying to track down a problem with nippy

5:41 i think is a*

6:21 clgv: sm0ke: ah ok. well use the streams I mentioned - cant get rawer than that ;)

6:29 cfleming: Testing testing 1 2 3

6:34 sm0ke: ,(apply prn (concat (repeat 2 "Testing") (range 1 4)))

6:35 clojurebot: "Testing" "Testing" 1 2 3\n

6:35 sm0ke: ,(apply print (concat (repeat 2 "Testing") (range 1 4)))

6:35 clojurebot: Testing Testing 1 2 3

6:35 cubix: hi, does anybody know some FSM library that works in ClojureScript?

6:36 I tried https://github.com/cdorrat/reduce-fsm but failed

6:57 clgv: cubix: how about https://github.com/ztellman/automat ?

6:58 sm0ke: yeah "prn" is inteded to get an output that clojure can read back in

7:03 sm0ke: hmm ##(pr "foo")

7:03 lazybot: ⇒ "foo"nil

7:03 sm0ke: ,(doc pr)

7:03 clojurebot: "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print in a way that objects can be read by the reader"

7:03 sm0ke: i wonder whats the difference

7:03 ,(doc prn)

7:04 clgv: sm0ke: you can read i back e.g. with `read-string`

7:04 clojurebot: "([& more]); Same as pr followed by (newline). Observes *flush-on-newline*"

7:04 sm0ke: oh i mean between pr and prn, doc makes it clear now

7:04 clgv: ,[(type (read-string (pr "abc"))) (type (read-string (with-out-str (print "abc"))))]

7:04 clojurebot: "abc"#<NullPointerException java.lang.NullPointerException>

7:05 sm0ke: ,(pr (java.util.Date.))

7:05 clojurebot: #inst "2014-09-05T11:04:40.975-00:00"

7:05 sm0ke: (print (java.util.Date.))

7:05 clgv: `pr` and `prn` differ by the line break printed by the latter

7:06 the bot wont show you that though

7:06 sm0ke: it will i guess

7:06 clgv: ,(prn "clojurebot")

7:06 clojurebot: "clojurebot"\n

7:06 clgv: ah he does ^^

7:06 ,(pr "clojurebot")

7:06 clojurebot: "clojurebot"

7:13 cubix: clgv: thanks, I'll check this out

7:19 clgv: hm, I tried automat, but when added to the project.clj & source file, I only get "WARNING: No such namespace: automat.core"

7:20 clgv: could it mean that automat doesn't work in ClojureScript?

7:21 luxbock: I think it most definitely doesn't

7:22 cubix: luxbock: are you referring to my question?

7:22 luxbock: yes

7:23 cubix: luxbox: ok, thanks

7:24 aa, OK, now I see: it uses Java code internally, I should have checked before asking :)

7:28 christian_stamm: hi. i'm looking for a way to distribute a (css-)file with a clojure lib and then copy it to a target path during leiningen build of the project using the lib.

7:29 pretty sure im missing something quite obvious

7:31 beamso: lein jar should take anything from the 'resources' directory and put it into the jar

7:31 christian_stamm: beamso. yes. that part works.

7:32 now i want to take it from the jar in another projects build

7:32 beamso: is the other project also built by leiningen?

7:32 christian_stamm: yes

7:33 beamso: you can have nested leiningen projects

7:34 https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies

7:34 it's also dependent on how you want to access or use the file

7:34 clgv: cubix: oh, you asked for cljs...

7:36 christian_stamm: beamso, that would be fine for development I guess.

7:37 the goal would be to distribute the file with library A. The project B uses the library and puts the file to the right place at build time.

7:38 clgv: christian_stamm: when you build a standalone jar (uberjar) for deployment of the project all the files from the depencies are part of that uberjar

7:38 christian_stamm: project B is clojurescript by the way. An is used by opening a html-file. The css needs to be placed relative to the html

7:39 so i have to move it from classpath to a filesystem path

7:39 clgv, yes. still i would have to copy the file somehow

7:42 clgv: christian_stamm: ah ok, I dont know about clojurescript best practices for that case but in a clojure project you would not have to copy it

7:44 christian_stamm: I guess i will be coding my first leiningen plugin this weekend then.

7:48 beamso: can you use version control or something instead of a leiningen plugin?

7:48 you can refer to other repos in both svn and git

7:52 clgv: christian_stamm: copying will create a new error source

7:53 christian_stamm: clgv. yes but it is vital for my usecase

7:54 i guess

8:00 clgv: you should double check that ;)

8:03 christian_stamm: i will :)

8:12 babygau: http://stackoverflow.com/questions/25681197/explain-core-reducers-library-in-laymans-term

8:19 clgv: babygau: no lazyseqs therefore parallelizable

8:20 babygau: @clgv, tks, I got it, but I'm not clear about `reducible` function

8:21 clgv: babygau: I think that categorizes how many arguments the resulting function has...

8:21 babygau: what I understand after reading Rich article is `core.reducers` return a `reducer` which is `reducible` collection

8:22 but I haven't figured out how it work :(

8:22 clgv: babygau: a function passed to `reduce` always gets two parameters: the previous result (or initial value) and the next value

8:23 babygau: whil the sequence functions build a lazyseq object, the function from the reducers namespace build function compositions

8:23 babygau: so it is lazy-sequence composition vs function composition

8:24 babygau: @clgv: how could they turn `sequable`collection into `reducible` collection

8:27 clgv: babygau: what exactly do you want to know about that? implementation details?

8:28 babygau: @clgv: ok, that explains why `core.reducers` can be `curried` functions as well

8:28 @clgv, that's exactly what I want

8:29 clgv: babygau: well than have a look at `reducer`, `folder` and `defcurried`

8:30 babygau: @clgv, I know it could be so over my head, bcoz I'm so new to #clojure but I want to understand it to some extend

8:31 clgv: babygau: well then, if I were you, being new to clojure I'd try to understand how to use reducers conceptually and leave out the implementation details

8:31 babygau: @clgv, just found this one over Google, is it one https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj

8:31 clgv: babygau: yeah that's clojure's main repository ;)

8:33 babygau: @clgv tks, I'm looking at it now :-P

8:34 @clgv, where could I find some idiomatic for naming function and its args in #clojure

8:35 @clgv: does `ret` stands for `return`???

8:35 lazybot: babygau: How could that be wrong?

8:36 babygau: @lazybot: it's just bcoz I'm new to #clojure and want to learn some good style guide of how to write properly #clojure code

8:36 clgv: babygau: there is no such ruleset

8:36 babygau: lazybot is actually a bot and no real person ;)

8:36 right lazybot???

8:37 lazybot: do you ignore me??

8:37 :(

8:37 ???

8:37 damn it does not trigger

8:37 &(inc 1)

8:38 babygau: @lazybot: if you use (doc some-thing) in REPL, you will see the authors have his own naming style guide >.<

8:38 lazybot: clgv: Yes, 100% for sure.

8:38 clgv: Uh, no. Why would you even ask?

8:38 clgv: Oh, absolutely.

8:38 ⇒ 2

8:38 clgv: uuhh damn he lags behind

8:38 babygau: @clgv it's so funny haha

8:45 @clgv: if I see it general form (xf reducing-fn) -> reducing-fn, xf means transformation function, right?

8:46 dagda1_: how do I return a lazy sequence from a function?

8:49 AimHere: dagda1_, depends *how* you want your function turned into a lazy sequence

8:50 DO you mean a function that returns a lazy sequence, or a lazy sequence of the function's iterated return values, or what?

8:50 dagda1_: AimHere: I guess if the last call of the function is reduce thent that will return a lazy seq

8:51 AimHere: You guess wrong

8:51 Reduce isn't lazy

8:51 dagda1_: AimHere: take is though?

8:51 AimHere; take returns a lazy seq

8:52 AimHere: Take returns a lazy sequence if you feed it a sequence

8:53 Reduce doesn't return a sequence. reductions returns a lazy sequence of the interim values of reduce, though

8:53 ,(take 10 (reductions + (range)))

8:53 &(take 10 (reductions + (range)))

8:53 clojurebot: (0 1 3 6 10 ...)

8:53 lazybot: ⇒ (0 1 3 6 10 15 21 28 36 45)

8:53 clgv: today: the big bot lag!

8:54 AimHere: clojurebot used a nonlazy range, and calculated the entire sequence

8:55 justin_smith: AimHere: what is a nonlazy range?

8:55 AimHere: One where (range) is a nonlazy sequence and has to be evaluated in full before you do anything with it

8:56 justin_smith: so why did he return at all? or do you mean somewhere other than the immediate scrollback

8:57 clgv: AimHere: huh? no, you forced printing since the lazy-seq was the result - it is still a lazyseq both bots returned

8:57 AimHere: It was a joke. I was hinting that the reason clojurebot took a few seconds to calculate the first 10 triangle sequence was that it was evaluating an infinite loop

8:57 justin_smith: that's a weird joke

8:57 clgv: strangely worded then :P

8:57 AimHere: It made sense to me at the time


9:04 thesaskwatch: Hi, anyone had a problem with "error in process filter: Variable binding depth exceeds max-specpdl-size" in cider?

9:06 clgv: thesaskwatch: did you search the issues on github?

9:07 justin_smith: thesaskwatch: this is emacs language for "stack overflow" - it happens in a lot of different code, and it means someone was using recursion where they should be using a loop - emacs has no TCO

9:08 thesaskwatch: justin_smith: thanks

9:08 justin_smith: thesaskwatch: recently there have been reports of larger amounts of output making this happen

9:08 thesaskwatch: I didn't use recursion, but I guess I have tons of recursion beneath few lib calls

9:08 justin_smith: but I have seen that even in the built in eshell if my lines get long enough

9:08 thesaskwatch: well, its on the elisp side

9:09 they are likely using some recursive code where they need a loop

9:09 thesaskwatch: justin_smith: my case is processing tens of thousands of db rows

9:09 justin_smith: if you know how to reproduce it, you could turn on debug-on-error

9:09 thesaskwatch: justin_smith: ok, I'll try to

9:09 justin_smith: thesaskwatch: if you are doing a lot of printing, try logging directly to a file rather than sending it all to *out*

9:09 thesaskwatch: justin_smith: ok, thanks

9:10 justin_smith: because the overflow with massive output amounts is a known issue

9:21 bja: any pointers of building clojure apps that want their own version of ring/compojure and depend on storm-core?

9:22 clgv: bja: what does "want their own version of ..." mean?

9:22 bja: I've recompiled storm-core at this point, patching it to the latest versions of its clojure dependencies (and fixing the resulting bugs due to migrating to newer library versions0, but this doesn't seem like a very good long term solution since it now just pins me on slightly newer library versions

9:23 clgv: bja: ah you have conflicting dependencies in your preoject?

9:23 justin_smith: bja: if you make your own version of a lib, you can either uberjar locally, or push your own artifact to a repo like clojars

9:23 bja: for conflicting deps, you need to use :exclusions in project.clj

9:24 bja: well, exclusions won't work in my case (due to storm's default build being an uberjar)

9:24 that is the source of my problems actually

9:24 justin_smith: yeah, package and deploy your own version of storm-core then

9:24 bja: the normal binary distribution of storm includes ancient copies of various ring middleware, hiccup, and composure

9:24 *compjure

9:25 err, well, I give up spelling that

9:25 ok, that was what I feared

9:26 thanks!

9:26 clgv: no chance that they update their deps?

9:26 bja: clgv, there's a thread that goes back to pre-migration to apache about it

9:26 they want to solve the problem in general

9:27 justin_smith: if it isn't aot, it may be possible to insert your own version of the deps in the classpath to take precedance, but in the presence of aot you are pretty much screwed I think

9:27 bja: storm is AOT'd

9:28 clgv: justin_smith: woah! you are worshipping the devil! :O :P

9:28 justin_smith: if only we had some VERY_OFFICIAL_DOCUMENT informing the world that in the clojure ecosystem, shipping AOT is a bug

9:28 clgv: ?

9:28 bja: it lead to a very weird situation of being able to (-> "ring/util/codecs.clj" clojure.java.io/resource slurp println) to see the source I expected but (require 'ring.util.codecs) found the AOT'd .class that storm provided

9:28 clgv: justin_smith: the classpath override suggestion ;)

9:29 justin_smith: well I mean to do it via a sane manner, like specifying your deps earlier in project.clj

9:29 clgv: ah right. though the newer version could have breaking changes, in that case bja is screwed

9:29 justin_smith: bja: yeah, that's the kind of shit aot causes

9:30 clgv: justin_smith: sounded like you want to manipulate the classpath manuall ;)

9:30 bja: I think I'm just going to fork all of their dependencies, rename their class path and just pin those there

9:30 at least then the aot'd versions won't bite me

9:30 justin_smith: I'd say the presence of AOT is all the excuse you need to make your own packaging with updated deps

9:30 yeah

9:30 bja: the updated dependencies don't even really matter. I mean, I don't really care where the include-js macro from hiccup lives

9:31 just wish that I could :exclusions [hiccup ring compojure] on storm-core like I can with everything else

9:37 Bronsa: 1.7.0-alpha2 is out

9:37 justin_smith: cool

9:38 clgv: Bronsa: what's new?

9:39 Bronsa: clgv: https://github.com/clojure/clojure/blob/master/changes.md :)

9:39 clgv: oh there's actually something there

9:41 oh `update`, but does that mean (update-in m [] f) does not get fixed?

9:42 justin_smith: oh, the warn on boxed math feature is a massive game changer

9:42 puredanger: thx :)

9:42 I expect it will undergo further changes in how you turn it on/off before 1.7.0 final but I have found it very useful

9:43 clgv: yeah, definitely a good idea

9:43 justin_smith: glad to see it in there for sure

9:44 puredanger: I wrote that while I was doing Alioth perf improvements. got tired of reading bytecode to tell whether boxing was happening.

9:44 Bronsa: hah

9:45 justin_smith: puredanger: is there an overhead to the check, such that you would want to turn it on during dev, and off in prod, or is it basically free?

9:45 puredanger: it's compile-time, so not a big deal

9:45 Bronsa: http://xkcd.com/1205/ made me think of this

9:46 clgv: so transducer will remain as -1 arg versions of the lazy functions? can we get an exception if we set *i-do-not-want-to-use-transducers* to true? just because I remember that missing params in threading statements happen pretty frequently

9:46 puredanger: clgv: yes. and no. to your questions :)

9:46 Bronsa: clgv: yeah that's the only thing that kinda sucks about having transients & lazy-seq fns in the same var

9:46 justin_smith: clgv: I bet robert.hooke could fix that for you

9:47 Bronsa: error messages will get weird

9:47 clgv: yeah. thats what I feared. another exception that doesnt tell anyone what really went wrong

9:47 Bronsa: cannot create ISeq from clojure.core$foo is the new ArityException

9:48 clgv: :O :(

9:48 mikerod: Bronsa: on this change page for 1.7 I noticed the same changes list for JDK 1.7 update and ASM update

9:48 clgv: it probably happens off-site as well

9:48 mikerod: I guess that was just copied over from 1.6?

9:48 Bronsa: mikerod: dunno ask puredanger :)

9:48 puredanger: mikerod: I don't understand what you're asking

9:49 mikerod: :P

9:49 puredanger: link?

9:49 mikerod: https://github.com/clojure/clojure/blob/master/changes.md list a JDK update

9:49 Same as https://github.com/clojure/clojure/blob/clojure-1.6.0/changes.md

9:49 As well as ASM.

9:49 puredanger: the change list is additive

9:49 mikerod: oh woops!

9:49 sorry

9:49 I need to read headers better

9:51 Transducers seemed to throw in a curve ball for me when I was reading the recent stuff the other day. I noticed this new 1-arity version of the reducing function.

9:51 My understanding of this is that that fn will be called once the reduction is complete? That seems to add a whole new level of power to reduce

9:51 clgv: ,(clojure-version)

9:52 is clojurebot tracking daily builds or something like that? since he usually reports "-master"

9:52 mikerod: Without the 1-arity, a reducing fn couldn't perform anything once the reduction was "done". I was just surprised to see this is now there, when I didn't read about it anywhere before seeing it added to the commits.

9:53 puredanger: mikerod: it was being filled in with identity automatically via the completing function

9:53 we encountered cases where you wanted to have that ability though (for example, closing a transient collection), so it's been promoted into public use

9:53 mikerod: puredanger: yes, but it is giving a new "hook" for a reducing fn to know when the reduction is complete right?

9:54 puredanger: yes, the transient example is a good one.

9:54 puredanger: sure

9:54 mikerod: What I'm curious about, is will clojure.core.reducers/fold also use this?

9:54 puredanger: no

9:54 or at least, no plans right now

9:54 we do expect to add some kind of parallel-reduce capability to core

9:54 but unsure yet what shape that will take

9:55 mikerod: Hmm. I thought that may be valuable if you wanted to do something at each paralell leaf that was about the whole coll at that leaf being reduced

9:55 parallel*

9:55 Bronsa: puredanger: is that something that is planned for 1.7 or "sometimes in the future"?

9:55 puredanger: I would expect it to be in 1.7

9:55 mikerod: I guess with fold the combine-fn can sort of do things that involve the reducing being "done"

9:55 puredanger: transducers really is a work in progress. there are several more things to be done.

9:56 Bronsa: cool

9:56 puredanger: in both functionality and performance

9:56 Bronsa: transducers are probably the most exciting enhancements in clojure in some time, for me

9:56 mikerod: 1.7 looks promising

9:58 puredanger: http://dev.clojure.org/jira/browse/CLJ-1499 and http://dev.clojure.org/jira/browse/CLJ-1515 for example

9:59 Bronsa: apropos Range, I know you didn't write the patch but maybe you know -- why isn't it implemented with a deftype?

9:59 is it too early in the bootstrapping phase?

9:59 oh wait it's written in the ticket's description. nvm

9:59 puredanger: :)

10:00 there's actually some not-yet visible more work on that too. I expect Tim and I will be working on it some next week.

10:01 mpenet: 1.7 is full of exciting stuff indeed

10:02 puredanger: and feature expressions continues to make progress - http://dev.clojure.org/display/design/Feature+Expressions has been updated quite a bit lately

10:02 Bronsa: puredanger: can you push the magic button and update the dashboard? :P

10:02 puredanger: yeah

10:03 perplexa: hey, is there something that's cleaner than using (+ 0) to get a 0? :P

10:03 ((constantly 0)) seems also dirty

10:03 * perplexa is a newb :)

10:03 christian_stamm: ,(*)

10:03 clojurebot: 1

10:03 christian_stamm: ,(+)

10:03 clojurebot: 0

10:03 perplexa: christian_stamm: mmh ;/

10:03 is there not something like (gimme 0)? :)

10:03 christian_stamm: ,0

10:03 clojurebot: 0

10:03 perplexa: i think i'll have to wrap it in a function ;p

10:04 clojurebot: "1.7.0-master-SNAPSHOT"

10:04 Bronsa: oh confluence supports daily updates via mail

10:04 mpenet: CLJ-1517 is very intriguing as well. I wonder what kind of impact this will have on various benchmarks and "real world" apps

10:04 Bronsa: that'll do

10:05 puredanger: Bronsa: I don't think any of that works. The thing that is broken is the "cron" aspect of Confluence so it never does the jobs its supposed to do. I suspect that includes sending email.

10:06 mpenet: yeah, I'm looking forward to looking at that more. just haven't had time lately.

10:06 Bronsa: damn.

10:06 puredanger: you can try it :) I just have low hopes.

10:07 Bronsa: the "Email Daily Reports" has Next Execution = 02-Mar-2014. Sounds useful.

10:07 Bronsa: hah

10:08 puredanger: if I get some time to mess with it I will. probably something that needs to be restarted somewhere.

10:09 I notice that the system uptime points back to exactly that same day.

10:10 I notice also that "System Favourite Character" is set to Chewbacca.

10:10 so we've got that going for us

10:11 Bronsa: I'll take Chewbacca over a working system every day

10:11 clgv: btw: should Numbers.equiv for two longs not be replace by an intrinsic operation "=="? I dont see that in the decompiled class file

10:11 Bronsa: clgv: only if you use it as a test in a if expression

10:13 clgv: Bronsa: oh ok. intrinsincs are still mysterious to me...

10:14 Bronsa: is there a reason that is limited to if conditions?

10:17 Bronsa: clgv: the *cmp jvm bytecodes don't return a boolean, they return integer values that the various jumping bytecodes understand

10:18 clgv: Bronsa: ah interesting

10:18 hugod: Is there any side effect on a namespace when you do an unqualified require - one that is queryable using ns-* functions?

10:19 Bronsa: clgv: so the predicate intrinsics are defined as cmp+jmp and require 2 branches

10:19 justin_smith: "jumping bytecodes" makes me think of Mexican jumping beans.

10:20 Bronsa: clgv: also probably the JVM will inline those Numbers.equiv calls

10:21 stuartsierra: hugod: no

10:21 hugod: stuartsierra: it might be interesting to add one

10:22 as soon as :as or :refer is used, it becomes visible

10:22 stuartsierra: yes, it might

10:22 hugod: I could imagine adding a generated alias, for instance

10:23 stuartsierra: but nothing prevents you from using fully-qualified symbols for namespaces which happen to have been loaded elsewhere

10:23 I.e., without deep analysis, you can't determine all dependencies of a namespace.e

10:23 hugod: right, and that becomes increasingly problematic when macros introduce them

10:24 stuartsierra: yep

10:24 Price of having macros.

10:25 hugod: well, you could make you macros require namespaces they inject into *ns*

10:27 fwiw, this came up because I got an error about cache protocols being unsatisfied when reloading some core.async code

10:28 clgv: Bronsa: thx

10:33 gfredericks: puredanger: s/alpha1/alpha2/ in the first line of your clojure-dev email

10:33 puredanger: you get the prize! I always leave in one typo.

10:35 mdrogalis: Ha.

10:37 gfredericks: yaaaay

10:41 puredanger: gfredericks: here's your prize: () () () () () () ()

10:41 I had some leftover

10:42 Bronsa: I updated every schedule on the Confluence job page. no clue if that will help. Most likely it will just cause the whole thing to die when it tries to do more work. :)

10:43 gfredericks: ,((comp count list) () () () () () () ())

10:43 clojurebot: 7

10:43 mdrogalis: gfredericks: Wow, you got 7 of something. Fancy!

10:44 puredanger: (inc gfredericks)

10:44 lazybot: ⇒ 89

10:44 puredanger: hey, lazybot is back! :)

10:47 clgv: yeah those two bots seem to have issues today

10:48 gfredericks: mdrogalis: http://xkcd.com/1417/

10:48 puredanger: nice

10:49 mdrogalis: Ha

10:54 csd_: Why does this function experience integer overflow under certain circumstances and how can I fix it? My understanding is that this is a result of the function not being truly lazy but I'm not clear on what in particular is causing this. http://pastebin.com/a4JuNbbv

10:54 The recursions are wrapped in concat which itself returns lazy-seq

10:55 justin_smith: saving up concat calls can blow the stack

10:55 but that would not be an integer overflow, it would be a stack overflow

10:55 puredanger: stuartsierra refers to that as a concat bomb

10:56 justin_smith: csd_: use (conj (first coll) ...) instead of (concat (list (first coll)) ...)

10:56 gfredericks: clojurebot: a concat bomb is (first (reduce concat (repeat 10000 [42])))

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

10:56 gfredericks: clojurebot: concat bomb is (first (reduce concat (repeat 10000 [42])))

10:56 justin_smith: csd_: oops, you need to swap the args for conj

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

10:56 gfredericks: ~concat bomb

10:56 clojurebot: concat bomb is (first (reduce concat (repeat 10000 [42])))

10:57 TimMc: perplexa: identity

10:57 justin_smith: ,(conj '(0) 1 2) ; csd_ can also work with your other instance of concat

10:57 clojurebot: (2 1 0)

10:58 puredanger: I think the new cat transducer may be another way to avoid it

10:58 justin_smith: puredanger: yeah, I think that could end up making concat somewhat obsolete, if I understand what it does properly

10:59 stuartsierra: `into` with vectors is another alternative

10:59 non-lazy, of course

10:59 csd_: justin_smith: I was under the impression for some reason that `cons` was better for recusion than conj

11:00 perplexa: TimMc: thx

11:00 csd_: still getting integer overflow using conj

11:00 TimMc: $findfn 0 0

11:01 lazybot: [clojure.set/union clojure.set/intersection clojure.set/difference clojure.core/time clojure.core/dosync clojure.core/long clojure.core/short clojure.core/-' clojure.core/+ clojure.core/unchecked-negate clojure.core/* clojure.core/- clojure.core/doto clojure.core/unc... https://www.refheap.com/89853

11:01 justin_smith: csd_: are you sure it is integer overflow?

11:01 sg2002: Hello. Can somebody tell me whether it's possible to create method with java generics in it using proxy?

11:01 csd_: justin_smith: it's the last test of http://www.4clojure.com/problem/132

11:01 justin_smith: because in that case, it would not be in the code you shared - it's somewhere else

11:05 clgv: sg2002: no, that generic stuff is only java compiler magic

11:05 sg2002: Genclass solution works for me, but I don't really want a class... What I want is to be able to create a class like new ClassA<ClassB>() { public boolean match(ClassB obj) {}} with ClassA being an abstract class.

11:08 Here: https://groups.google.com/forum/#!msg/clojure/Xv1pKATfP0c/qmPdGT1LNKsJ it was suggested that something like (:gen-class :extends ^{:parameters [SomeItemType]} java.util.AbstractCollect)) works for genclass. Maybe there is a similar syntax for proxy?

11:09 Also, is there a way to view java signature of objects created by proxy other than decompiling?

11:10 justin_smith: csd_: OK, the integer overflow is happening because the function is not lazy

11:10 csd_: I was confused because there is nothing in the code you first showed us that would cause an integer overflow, but in the 4clojure problem's context, by not being lazy, the first error you hit is an integer overflow

11:14 csd_: What's not lazy about it though? Concat is lazy and it doesn't seem like a concat bomb is happening. It's wrapped in lazy seq. I also replaced `rest` with `drop 1` to no effect

11:16 justin_smith: csd_: I just made a version that is actually lazy, care to see it?

11:16 (as in, passes the test and does not make the fib generator overflow)

11:17 csd_: id prefer to do it myself i just don't know what's causing the problem in the existing function

11:22 justin_smith: csd_: I actaully am not a lazy seq expert - I tend to fumble until things work when making things lazy. But there are some reliable ways to figure out if the thing you made is properly lazy (like calling (take 10 (f ... (range))))

11:24 csd_: ok thanks

11:24 tgkokk: How would I create a zipper with 1 as root and then (i.e. after the zip-vector call) add 2 and 3 as children? I've been trying for an hour but I've arrived to sub-par solutions (e.g. I can add 2 and 3 but then I can't add other children to 2 nor 3).

11:26 justin_smith: tgkokk: how are you adding to the zipper?

11:26 tgkokk: with z/insert-child and z/append-child

11:26 I intend to use it as a tree, but I'm not sure how that will work out.

11:27 PigDude: do you ever do this? defmulti with dispatch function that does not operate on args

11:27 justin_smith: PigDude: so each implementation of the multimethod can only do one thing?

11:27 CookedGryphon: How do I make emacs install a stable version of cider?! I've tried everything, including deleting all my packages and only enabling the stable melpa, but it's still finding the broken snapshot from somewhere

11:27 PigDude: and instead returns some atom value, for instance. so that the code user can configure something globally and not need to pass this value to each mm call. convenience at the expense of flexibility

11:28 CookedGryphon: you use vim

11:28 TimMc: CookedGryphon: There's a stable version of cider?

11:28 justin_smith: PigDude: don't add a global atom to your library

11:29 CookedGryphon: TimMc: well 0.7.0 as opposed to 0.8.0-SNAPSHOT

11:29 justin_smith: TimMc: 0.7.0 was intended to be stable

11:29 TimMc: I don't know how stable it actually is, but that was the intention

11:29 PigDude: justin_smith: this is not my library, it is some database functions that need to use a configured data source. things are greatly simplified if code does not need to pass in the type of data source

11:29 TimMc: One of these days I should try it again.

11:29 PigDude: justin_smith: if this is not the right way to do it, i'm curious how others would go about it

11:29 TimMc: justin_smith: Oh, stable as in Debian. :-P

11:30 CookedGryphon: Cider is actually working pretty nicely nowadays, it's emacs package management that's letting me down

11:30 PigDude: justin_smith: so, (db/do-something) should use the correct store, which would already have been set up in -main. so, there is no store-specific config involved, just need to know which backend is used

11:30 justin_smith: PigDude: if it's for an app and not a library, then sure, make a wrapper that elides the db argument and supplies your globally configured db config

11:31 PigDude: the problem is libraries that create a global config

11:31 csd_: justin_smith: figured it out. it was the reference to `count` breaking things.

11:32 justin_smith: csd_: I was able to eliminate count and still get the error

11:32 PigDude: justin_smith: ok, and would that wrapper be the sort of multimethod i'm using right now, or something else?

11:32 justin_smith: csd_: but maybe I had broken something else in the process :P

11:33 PigDude: this seems a weird way to use multimethods - I would make a few wrapper functions that access your config, c.j.jdbc is not a huge lib

11:33 technomancy: CookedGryphon: I'm using el-get

11:33 PigDude: nothing to do with jdbc, but "wrapper functions" is unclear to me. what does "make a few wrapper functions" mean?

11:33 technomancy: bonus: you can install packages over HTTPS instead of insane unencrypted executable transmission

11:34 Bronsa: puredanger: I'm reading the updated wiki page on feature expressions, regarding "Reading Unreadable Things" that shouldn't be a problem as we already have *default-data-reader-fn* -- the feature expression reader just needs to bind that to (constantly nil) before reading the next form

11:34 PigDude: justin_smith: let's say you've got :breadbox and :refrigerator and you want to store things in one or the other automatically, so (food/save "eggs") would use the right store. what might that look like if you're not using MMs?

11:34 justin_smith: PigDude: OK, the reference to db threw me off :) a wrapper function is one that takes one fewer args than the target function, and supplies a default arg (plus the others) to the target

11:35 PigDude: OK, so based on the type of the arg you want to dispatch - this is a reasonable place to use a multimethod, sure

11:35 PigDude: justin_smith: right now I have (defmulti save (fn [& _] (get-store-...))), (defmethod save :refrigerator [name] ...)

11:35 (equivalent)

11:36 justin_smith: but there you aren't doing any dispatch by value?

11:36 PigDude: in that case :refrigerator might be some atom value

11:36 (global)

11:37 the dispatch is on that value

11:38 this might be clearer https://www.refheap.com/86f595d58b359a6056c198d4a

11:39 justin_smith: but this is an abuse of defmulti, because you aren't dispatching on args at all, you are just picking up a global config

11:39 PigDude: how many antipatterns in that paste? :)

11:39 yep, wondering what's preferrable so that method definers and callers don't have to be aware of it

11:39 justin_smith: csd_: I figured out my issue: using conj instead of cons made it non-lazy TIL

11:41 PigDude: make a function that has all the same args as the one you want to call, except for the db-config arg. Then supply the atom for that arg, passing all others unchanged

11:41 PigDude: so double the number of functions

11:42 justin_smith: hrm - wait

11:42 sorry

11:42 PigDude: it seemed if i took the wrapper fn approach, injecting the global, then i double the number of my functions, is why i went w/ MM at first

11:42 justin_smith: so these multis are dispatching on their args - they get the value with that key from the config

11:43 didn't you say previously that the multis were ignoring the arg?

11:43 PigDude: these multis don't really dispatch on their arguments at all, they just pull that atom value

11:43 so neither method definer nor caller are aware of the backend config source

11:43 justin_smith: never mind, I need coffee

11:44 PigDude: that explains that, i wrote this on my first cup of coffee ;)

11:44 justin_smith: and I still think one small wrapper per function using the global config is actually simpler than the other contortions you would end up with

11:44 PigDude: hm, ok

11:44 clearly the thing to do is to encapsulate that in a macro and do (defdbmethod) ;)

11:45 then i'm a clojure ninja

11:45 justin_smith: it would make it easier :) for each function supplied to defdbmethod, you make a new one that takes one fewer args and supplies your config

11:52 technomancy: oh wait

11:52 el-get pulls in a broken cider

11:52 so while I still advise it in general, I can't recommend it in this particular case

11:53 justin_smith: technomancy: in general, my heuristic neural net wetware is drawing very strong connections between the "cider" and "broken" nodes

11:54 technomancy: justin_smith: in the past I avoided this by installing from marmalade. then I found out marmalade doesn't have SSL.

11:54 so I guess I'm gonna check it out from git and do a manual install

11:54 of version 0.6.0

11:54 CookedGryphon: :(

11:57 technomancy: oh, you can use el-get to install old versions

11:57 \m/

11:58 danneu: justin_smith: i am not a person. i am a t-800 cybernetic organism. a learning computer.

11:58 technomancy: just add :branch "0.6.0" in the cider recipe

11:59 justin_smith: technomancy: nice to know about that

12:00 technomancy: yeah, I can't recommend package.el in good conscience at this point

12:44 danneu: i'd like to use https://github.com/yogthos/markdown-clj for user input but disallow arbitrary html. for example, i want it to parse <http://google.com> but escape <h1>Hello</h1>.

12:44 is there a simple solution?

12:50 justin_smith: danneu: clj or cljs?

12:51 danneu: justin_smith: clj

12:51 im rendering the template on the server and doing (md/md-to-html-string (:text post))

12:51 justin_smith: you could potentially use enlive on the output of md-to-html-string, altering non anchor markup?

12:52 danneu: justin_smith: haha, yeah - that's my last resort. hopefully java/clj has a markdown implementation that works as i describe (which is how the `markdown` npm module works)

12:54 this is the kind of thing that makes the http://standardmarkdown.com/ project exciting for me

12:54 hiredman: enlive's emit* seems to stack overflow pretty easily, and you can't pass enlive's datastructure to clojure.xml/emit because enlive parses comments as {:type :comment ...} (totally different from any other nodes)

12:58 justin_smith: hiredman: oh, I've never seen that, good to know

12:58 the stack overflow part that is, never even tried using the c.x/emit with enlive

13:01 danneu: i finally moved from hiccup to selmer. i realize it was kinda masochistic to use twitter bootstrap with hiccup (i.e. massive class pollution)

13:01 justin_smith: 𝓣𝓱𝓮 𝓶𝓸𝓻𝓮 𝔂𝓸𝓾 𝓴𝓷𝓸𝔀

13:01 danneu: sometimes you just want to copy and paste html and be done with it...

13:02 and rest assured that html is escaped ^_^

13:03 it's kinda like that time someone registered on my node.js site with the name "__proto__" and i had some logic that used usernames as object keys

13:03 justin_smith: wow

13:04 danneu: hard knocks man

13:14 * clgv is reminded of http://xkcd.com/327/

13:18 xicubed: danneu: I am a CLJ 9000 computer. I became functional - well I’ve always been functional… My instructor was Mr. Hickey. He taught me to sing a song in Harmonikit…

13:18 tuft: hello clojuresphere

13:31 danneu: what's the best way to wrap a thread-unsafe function `.doSomething` to force synchronous execution across threads? my naive solution is (defn do-something [x] (swap! result (fn [_] (.doSomething x))))

13:31 justin_smith: danneu: swap! does not lock, it retries

13:31 hiredman: that is terrible

13:31 danneu: haha

13:31 naive, guys!

13:31 naive!!

13:32 justin_smith: danneu: an agent is synchronous though

13:32 danneu: justin_smith: ah thanks. so i just immediately deref

13:32 hiredman: agents are asynchronous

13:33 danneu: if you must ensure serial execution use a lock

13:33 justin_smith: hiredman: I mean they block until the previous alteration has run, rather than retrying

13:33 technomancy: Clojure Fact: "agent" is short for "asynchronous gentleman"

13:34 hiredman: justin_smith: they don't block, they queue actions

13:34 justin_smith: hiredman: sorry, yeah, block was the wrong term to use there, my bad

13:34 hiredman: send can block, but the blocking behaviour depends on the number of cpu cores

13:34 send-off doesn't

13:37 danneu: would this do the job? (def thing (Thing.)) (def do-something [x] (locking thing (.doSomething thing x)))

13:39 hiredman: Thing can just be Object, sure

13:40 I like (locking #'do-something (.doSomething thing x)) which would lock on the var object holding the function

13:51 danneu: when a java constructor looks like Thing(int options) and provides a list of available option ints, how do you generally enable multiple options? xor the ints together?

13:52 llasram: danneu: bit-wise or (not xor)

13:52 danneu: wow

13:53 no wonder clojurists yak shave so much

13:55 dbasch: danneu: I don’t follow. What does that have to do with clojure?

13:57 AimHere: Yak shaving is a jargon term, originating from Ren and Stimpy cartoons, referring to a complex series of tasks where your current task bears apparently no relation to the end goal

13:59 dbasch: AimHere: I think probably everyone here knows what yak shaving is, what I don’t follow is why danneu said what he said given the context of a Java constructor

13:59 danneu: dbasch: i guess people with lower level experience are used to that

14:00 (A | B | C)

14:00 Thing(A | B | C)

14:00 if (options & A) ...

14:00 dbasch: danneu: that’s the old C way of doing things, which some people carrier over to Java but has little to do with Clojure

14:01 danneu: that makes sense

14:01 dbasch: in C (or assembly) you typically defined flags and or’ed them together as needed

14:01 and and’ed to check if set in a register / variable

14:01 technomancy: I've only seen that style in java code written by someone who has never written java before.

14:02 danneu: my noobness is leaking :(

14:02 technomancy: never mind that I've never written java before either

14:02 dbasch: in Java you have more idiomatic things such as Enums

14:04 or Properties

14:05 TimMc: danneu: When you interact with that sort of interface from Java, you still have to do bit operations on numbers...

14:06 tuft: bit masking was magical to me when i first started reading code, heh

14:08 dgaffney: Hey everyone - quick question: I'm sending in a data package via RestClient in ruby and seeing something different print out on the route in clojure - any idea why this data blob is getting all malformed immediately upon arrival? https://gist.github.com/DGaffney/79f60f8beb3e5e9a1bbc

14:08 tuft: i guess in clojure it's just keywords instead of enums?

14:10 dgaffney: can you see what's going on the wire?

14:11 dgaffney: I am *very* familiar with restclient and can assure its being sent as it is supposed to on that end.

14:11 tuft ^

14:12 tuft: dgaffney: what does just plain (println params) show?

14:13 dgaffney: sorry, tuft

14:14 my computer has this awful kernel panic bug that kills the machine every once in a while. Did you reply to that q?

14:14 tuft: ack!

14:14 dgaffney: what does just plain (println params) show?

14:15 dgaffney: hold

14:16 {:attributes {:value wee, :for something_else}, :label Peat Bakke, :id peat}

14:16 :|:|:|

14:17 tuft: ah hm

14:17 sorry, i'm stabbing in the dark a bit. hopefully i'm not giving you the impression i know anything =)

14:17 ghadishayban: hiredman: rather like your reduce idea for java.jdbc

14:18 llasram: tuft, dgaffney: You never want to `println` data-structures. `prn` is you want the `read`-able representation of some Clojure data

14:18 hiredman: in abstract I think everyone does, but there is no code for it yet which is where we can really get down to bikeshedding

14:18 dgaffney: rgr, llasram - you know what the deal is there anyway?

14:19 danneu: dgaffney: are you using ring-json middleware to parse the json?

14:19 dgaffney: {:attributes {:value "wee", :for "something_else"}, :label "Peat Bakke", :id "peat"} < prn output

14:19 tuft: llasram: ah indeed. all my logging is prn lately -- what was the point of "human readable" logs again?

14:19 llasram: dgaffney: It looks like the Ruby side is encoding the `attributes` array via repeated use of the query parameter

14:19 dgaffney: [ring.adapter.jetty :as jetty] may be the offender?

14:19 llasram: dgaffney: While the Clojure side is taking the last value

14:19 dgaffney: danneu ^

14:21 llasram: dgaffney: Are you using the `ring.middleware.params/wrap-params` middleware?

14:21 Oh, it's a POST

14:21 hmmmmm

14:22 Same deal though, just with form parameters instead of query parameters

14:22 dgaffney: no, llasram

14:22 I am not using that

14:23 trying via curl now

14:23 llasram: dgaffney: Then maybe try it :-) I'm pretty sure that's what's happening, that whatever middleware *is* parsing the form parameters is keeping only the last

14:24 Oh, wait. JSON? nm. I don't actually know what's going on

14:25 justin_smith: with any luck there is a switch to get a sequence from a repeated key, or at least get the raw input and do your own parsing - failing either of those you could replace or rewrite the body parsing middleware I guess

14:25 "A valid JSON data representation won't duplicate keys in the same nesting level."

14:26 dgaffney: A bit confused with that sentence, justin_smith

14:26 justin_smith: the one I quoted, or before that?

14:27 dgaffney: both :(

14:27 nah, i get it now

14:27 justin_smith: so, do I understand correctly that you are getting json in the request body, and it has repeated keys?

14:27 dgaffney: I just don't understand why I would not get a literal translation of the data package I sent in

14:28 Two maps in a list, both with identical keys.

14:28 (still learning vernacular, may be using wrong names)

14:28 llasram: dgaffney: Can you `tcpdump` the request, see exactly what RestClient is sending?

14:28 justin_smith: dgaffney: so something like [{:a 0} {:a 0}] and you only get one of those maps?

14:29 dgaffney: yes

14:29 I get {:a 0} back

14:30 The representation of the thing in clojure would be very similar to {:attributes [{:a 0}, {:a 10}]}

14:30 I can't tcpdump well enough to get it to punch out what you're looking for

14:31 samflores: are you using ring.middleware.json/wrap-json-params to parse the json?

14:32 dgaffney: negative, samflores

14:34 samflores: what are you using to parse the json?

14:35 _yocapybara_: hey guys, total noob here - I'm trying to require jdbc.types but get told jdbc/types.clj isn't on my classpath despite org.clojure/java.jdbc in my leiningen dependencies - where's the best first place to look?

14:35 dgaffney: I am not familiar enough with libraries to know yet, but here's the list: https://gist.github.com/DGaffney/134ddc2626d737c727fc

14:35 samflores: cheshire

14:35 :D

14:35 dgaffney: cheshire mayhaps? I think that's the relevant library

14:35 yeah

14:36 danneu: RestClient.get("http://localhost:3000/lol", {:body => {:id => "peat", :label => "Peat Bakke", :attributes => [{:for => "attribute_name", :value => 1}, {:for => "something_else", :value => "wee"}]}})

14:36 wrong window

14:36 dgaffney: I don't even see *where* encoding is happening - its happening before the routes?

14:36 hiredman: _yocapybara_: what version of java.jdbc?

14:37 samflores: try feedind (cheshire.core/parse-string "") with the string directly in a REPL

14:37 ouch

14:37 llasram: dgaffney: I don't think at this point we have enough information to know what's going on. You have some middleware which is doing the decoding. But we don't know exactly what the middleware is even getting

14:37 Well, until danneu finishes figuring out exactly what RestClient is sending :-)

14:37 hiredman: _yocapybara_: http://clojure.github.io/java.jdbc/ doesn't show a types namespace

14:37 dgaffney: samflores: nil

14:37 _yocapybara_: hiredman: I've put 0.3.5 in lein

14:37 hiredman: aaah

14:38 that will teach me to follow old blog posts blindly :) thanks!

14:38 totally explains it

14:38 samflores: yeah, the sample I gave you will return nil. you need to put your json string there

14:38 hiredman: ~blogs

14:38 clojurebot: blogs are never to be trusted

14:39 dgaffney: https://gist.github.com/anonymous/cfb946576feaf91f50d9

14:39 _yocapybara_: hiredman haha

14:39 samflores: it seems cheshire know how to properly parse json :D

14:40 danneu: i cant figure out how to set the body in restclient

14:40 dgaffney: Here, here's my whole core.clj https://gist.github.com/DGaffney/919600dc05a00fc6e883 - I don't know where the middleware is being applied...

14:40 danneu: sends everything as params or headers

14:41 dgaffney: it may just not be applied at all?

14:41 samflores: handler/site

14:42 danneu: you want to send your {stuff}.to_json as the body of the request with content_type: :json.

14:42 dgaffney: how do you modify it? I assume setting cheshire explicitly would resolve this?

14:44 samflores: actually (handler/site) wraps your requests with several middlewares. so you handler will receive it already parsed (wrongly)

14:44 danneu: dgaffney: try RestClient.post("http://localhost:3000/lol", {:id => "peat", :label => "Peat Bakke", :attributes => [{:for => "attribute_name", :value => 1}, {:for => "something_else", :value => "wee"}]}.to_json, :content_type => :json)

14:44 dgaffney: I have

14:45 comes through as {}

14:45 samflores: replace handler/site with handler/api

14:45 http://weavejester.github.io/compojure/compojure.handler.html#var-site

14:46 danneu: neither of those include wrap-json-params https://github.com/ring-clojure/ring-json

14:46 api is just a subset of site

14:47 samflores: yeah, I know

14:47 dgaffney: no dice replacing handler/site with handler/api

14:48 it returns identical output

14:48 danneu: dgaffney: check out that link i dropped. then add (-> app handler/site ring.middleware.json/wrap-json-params)

14:49 add [ring/ring-json "0.3.1"] to project.clj

14:50 samflores: danneu, I've used wrap-json-params some time ago... but I believe without it the handler should receive the raw (unparsed) string, don't?

14:50 can't remember

14:50 llasram: danneu: Yeah, but dgaffney is printing out only the middleware-parsed :params

14:51 so they'll only see anything it if something parses the JSON

14:51 danneu: wrap-json-params will parse a request's json body string into a map and expose it in (:params req)

14:51 if the request has a json content-type

14:51 llasram: danneu: Er, yeah, sorry -- my comment was meant for samflores

14:52 danneu: I think you're on the right track :-)

14:52 dgaffney: updated core - https://gist.github.com/DGaffney/76a95097b7ef402f5c6f

14:52 no dice.

14:53 danneu: dgaffney: are you still using your original snippet

14:53 dgaffney: was a bit confused on the mixed syntax for use

14:53 This is a new snippet

14:53 would you like me to stick to a single?

14:54 danneu: i mean, what's your restclient commandn look like

14:54 samflores: got it, llasram & danneu

14:55 dgaffney: RestClient.post("", {:id => "peat", :label => "Peat Bakke", :attributes => [{:for => "attribute_name", :value => 1}, {:for => "something_else", :value => "wee"}]})

14:55 dbasch: dgaffney: you need to remove the handler/site

14:55 danneu: dgaffney: change it to this

14:55 https://gist.github.com/danneu/056234ad4b167a4f376e

14:56 you need to add content_type: :json

14:56 that way the middleware knows that the body of the requst (string) needs to be parsed into json

14:57 i also had to add .to_json to the end of the params hash arg

14:57 dgaffney: That doesn't work for me still :(

14:57 I need to leave the house now

14:57 its too late.

14:58 oh well.

14:58 blerghhhh - I'll talk to you guys later

15:00 danneu: dgaffney: oh, they seem to be available in (:json-params req)

15:00 dgaffney: what does?

15:01 danneu: the parsed json on the clojure side

15:01 easier to debug this kind of thing with (clojure.pprint/pprint request) in your route

15:02 (POST "/test" request (clojure.pprint/pprint request))

15:03 dgaffney: https://gist.github.com/anonymous/da4cf0dfa047f692effc

15:04 https://gist.github.com/anonymous/05deea2c3bb8253aba8f < full req

15:04 danneu: :content_type => :json needs to be in your restclient

15:05 if you look at the headers in your request gist, it has x-www-form-urlencoded

15:05 which is what restclient's POST defaults to

15:06 this all works for me using this RestClient command https://gist.github.com/danneu/056234ad4b167a4f376e

15:06 dgaffney: {:ssl-client-cert nil,

15:06 :remote-addr "",

15:06 :scheme :http,

15:06 :query-params {},

15:06 :session {},

15:06 :form-params {},

15:06 :multipart-params {},

15:06 :request-method :post,

15:06 :json-params

15:06 {"id" "peat",

15:06 "label" "Peat Bakke",

15:06 danneu: 8^D

15:06 dgaffney: "attributes"

15:06 [{"for" "attribute_name", "value" 1}

15:06 {"for" "something_else", "value" "wee"}]},

15:06 :query-string nil,

15:06 danneu: there ya go

15:06 dgaffney: :route-params {},

15:06 :content-type "application/json",

15:06 :cookies {},

15:06 :uri "/test",

15:06 :server-name "",

15:06 :params

15:06 {:id "peat",

15:06 :label "Peat Bakke",

15:06 :attributes {:for "something_else", :value "wee"}},

15:06 :headers

15:06 {"accept-encoding" "gzip, deflate",

15:06 "user-agent" "Ruby",

15:06 "content-type" "application/json",

15:06 danneu: at least it's not a clojure stacktrace

15:07 dgaffney: "content-length" "123",

15:07 "accept" "*/*; q=0.5, application/xml",

15:07 llasram: :-)

15:07 dgaffney: "host" ""},

15:07 :content-length 123,

15:07 :server-port 8080,

15:07 danneu: we'd be here a while

15:07 dgaffney: :character-encoding nil,

15:07 :body #<HttpInput org.eclipse.jetty.server.HttpInput@773ba8d6>,

15:07 :flash nil}

15:07 JESUS

15:07 sorry

15:07 sorry.

15:07 hahahaha

15:07 well, when you set content type its fine

15:07 butttt - this stack still kicks it to the handler all weird

15:07 so is :json-params something I can access?

15:07 danneu: yeah

15:08 dgaffney: can you throw a sample over? - these env level things are always a bit hard to wrap around the first time through the gate

15:08 danneu: i dont use compojure's bindings. i just always bind the entire request: (GET "/" request (println (:json-params request))

15:09 ghadishayban: puredanger: the varargs comp tweak committed today is interesting. specific rationale?

15:09 puredanger: moar faster?

15:09 puredanger: dunno, no conversation about it

15:11 Bronsa: ghadishayban: looks like it should be

15:11 ghadishayban: the previous version did the looping each time the function returned by `comp` run, this version does it at the `comp` call site

15:11 if I'm reading it correctly

15:12 justin_smith: dgaffney: yeah, you should be able to access (:json-params request) within your handler

15:12 danneu: the bindings in compojure are just generic clojure destructuring

15:13 danneu: a decent intro http://blog.jayfields.com/2010/07/clojure-destructuring.html

15:14 amalloy: Bronsa: doesn't the new comp have a stackoverflow issue if you pass it a bunch of functions?

15:15 ie, ((apply comp (repeat 10000 inc)) 1) should blow up

15:15 danneu: justin_smith: they do more than just that

15:15 justin_smith: ,((apply comp (repeat 10000 inc)) 1)

15:15 clojurebot: 10001

15:15 justin_smith: ,*clojure-version*

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

15:15 danneu: dgaffney: https://gist.github.com/danneu/dce2ec9e46362875c014

15:15 justin_smith: danneu: like what?

15:16 danneu: justin_smith: (GET "/:user-id" [user-id] ...)

15:16 llasram: https://github.com/weavejester/compojure/wiki/Destructuring-Syntax

15:16 justin_smith: danneu: OK, that is kind of magic, was not aware of that bit of magic

15:17 danneu: i mean, it's not the end of the world. i just like the consistency of always having a req object.

15:17 it's also more obvious to compojure noobs

15:17 justin_smith: {a :with-a x :x :as request}

15:18 danneu: yeah [user-id :as req]

15:18 dgaffney: btw i switched out wrap-json-params for wrap-json-body which is prob what you want.

15:18 my gist should work for you

15:20 Bronsa`: amalloy: yeah it looks like it does but does anybody really comp 1e5 fns?

15:26 hiredman: well, deep comps became much more likely given transducers, but I dunno about 1e5

15:27 dgaffney: All good!

15:27 Ok, only 1.5 hours behind schedule.

15:27 whatevs, thanks so much guys.

15:29 _2_Chopin4453: fucking gel

15:30 stuartsierra: At a guess, the `comp` change may allow better JVM inlining.

15:31 _2_Chopin4453: shit and have sex

15:31 stuartsierra: The prior version of `comp` was looping over a list of functions, rather than compiling a completely new function.

15:32 _2_Chopin4453: dam it

15:32 turbofail: troll detected

15:38 scheafer: hi- i've got a question about the definition of ClojureScript equality and Javascript objects. In particular, I'm (= (goog.date.Date. 2000 1 1) (goog.date.Date. 2000 1 1)) returns false but (.equals (goog.date.Date. 2000 1 1) (goog.date.Date. 2000 1 1)) returns true. that's pretty unexpected. is there a reason for this?

15:38 _2_Chopin4453: sex have it

15:39 falafel: Is there an official documentation from transducers yet?

15:39 danneu: markov chain gathering entropy)

15:40 hiredman: scheafer: = may default to object identity

15:40 scheafer: for things it knows are immutable objects it may compare values

15:41 scheafer: I dunno, but it seems like a good guess

15:42 ananna: Hi I'd like a recommendation for an introductory tutorial that goes into how I can create a simple web app using Clojure. I've done most of SICP, so I have some theoretical understanding and I hope to refine it by studying Fogg's book, but I want to hit the ground running. Any recommendations on what I can use? I've found: http://www.linuxjournal.com/content/intro-clojure-web

15:42 scheafer: hiredman: it seems like it would be useful to have an equality function which switches between core/= and .equals based on the argument types. i'm surprised that this sort of thing hasn't come up before and isn't incorporated into core

15:43 joobus: ananna: http://www.youtube.com/watch?v=VVd4ow-ZcX0

15:43 justin_smith: scheafer: doesn't = already use .equals, depending on the argument type?

15:44 scheafer: justin_smith: not from what i've seen from the source

15:44 ananna: joobus: Something written? I don't do visual things well.

15:44 hiredman: scheafer: it likely has, and was thought about, and this was arrived upon

15:45 justin_smith: scheafer: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Util.java#L33 this is called by =

15:45 scheafer: hiredman: yep. so it makes me think that either it's there and i dont know about it or i'm way off base with what i'm trying to do :)

15:45 joobus: ananna: I'm a noob. I've been working through this: http://clojurekoans.com/

15:45 ananna: but it isn't a web app

15:45 ananna: just exercises in clojure

15:45 justin_smith: scheafer: I assume you did not look very far, it's called directly by =

15:46 scheafer: justin_smith: i think that's the clojure code, not clojurescript

15:46 turbofail: i think scheafer is talking about cljs

15:46 hiredman: scheafer: goog.date.Date is mutable (it has setters to set values) so comparing it as a value is a bad idea

15:46 justin_smith: scheafer: oh, I had the wrong context, sorry

15:46 ananna: joobus: I've seen it and it really is generally helpful, but I guess I'm just looking for something I can do to make a small toy project and experiment with it as I build stuff

15:46 turbofail: but that said in cljs there's a protocol IEquiv

15:46 hiredman: scheafer: you could say two dates are equal, some could mutate one, then suddenly they aren't equal

15:47 turbofail: in which you can define how equality works for that type

15:47 dbasch: ananna: how about https://devcenter.heroku.com/articles/clojure-web-application

15:47 ananna: dbasch: That's what I'm looking for, thank you.

15:47 scheafer: hiredman: agreed. but clojure & java have the same problem and = delegates to .equals for java objects. i know clojurescript isn't intended to be identical to clojure but i assumed the equality semantics would be consistent

15:48 turbofail: ah ha. i thought there would be a protocol approach to this problem but i coudln't find it easily. are the protocols doc'd somewhere? i must have missed them

15:48 hiredman: scheafer: is it a little more complicated, just delegates to .equals

15:49 turbofail: https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L301

15:49 dunno about any docs

15:50 scheafer: i see where my investigation failed. i looked at the clojurescript source for = and found that it used -equiv internally. i just assumed that -equiv was an implementation detail and not related to a protocol

15:50 hiredman: regardless, there is an easy answer, stop trying to use a universal equality operator

15:50 (defn date= [a b] ...)

15:50 scheafer: hiredman: yes, writing code would be much easier if i just stopped trying to write code ;)

15:51 turbofail: thanks for the pointer. i'll extend IEquiv over goog Date and get the desired behavior

15:55 Bronsa: puredanger: the changelog says that vswap! is a function..

15:56 puredanger: It seemed far more awkward to be precise in that sentence.

15:57 Bronsa: puredanger: you're still in time to make it a function so that the changelog will be true :P

15:58 * Bronsa will never get over vswap! being a macro

15:59 puredanger: pick your battles man :)

15:59 stuartsierra: http://dev.clojure.org/jira/browse/CLJ-1209 is my new campaign

16:00 Bronsa: stuartsierra: that seems like a good idea.. until somebody puts a large or infinite sequence in the ex-info

16:01 stuartsierra: yeah...

16:01 We need a "safe-print"

16:02 jeffterrell: stuartsierra: I like it. Both the CLJ-1209 and the *safe-print*.

16:02 stuartsierra: Which is probably Godel.

16:02 Bronsa: stuartsierra: maybe binding *print-length* and *print-level* to a safe value (say 10) in print-throwable?

16:03 stuartsierra: That's a start, at least.

16:13 hiredman: stuartsierra: there are issues with head holding there

16:13 slingshot would capture the env and throw it in its exceptions

16:14 it is problematic

16:14 oh, I guess not for the printing, I assumed 1209 was the "capture lexical scope in asserts" or whatever

16:15 stuartsierra: yeah, if you threw it, you're already holding it. I just want to print it, the way ExceptionInfo.toString does.

16:16 stompyj: I’ll raise your lexical scope and see you a lexical closure

16:26 numberten: can you :as bind a destructured vector?

16:27 TimMc: Try it and see.

16:27 numberten: i did :(

16:28 bounb: ,(let [[x y z :as vec] [1 2 3]] vec)

16:28 clojurebot: [1 2 3]

16:28 numberten: ah

16:28 silly me, I didn't put the :as in the []. thanks :)

16:28 bounb: np. from one newbie to another

16:29 numberten: :)

16:30 amalloy: hey, it looks like rich removed flatmap in favor of a lower-arity mapcat after all

16:39 mikerod: amalloy: apparently the 1-arity mapcat didn't work anyways

16:39 ,(mapcat identity)

16:39 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$map$fn__4338>

16:41 mikerod: This is due to mapcat

16:41 using apply on the colls without checking

16:41 `(apply map colls)`

16:42 Seems like an obviously broken thing. a) I'm surprised this was the case currently. b) given it being broken, looks like making the 1-arity of mapcat meaningful was an obvious thing to do

16:53 amalloy: mikerod: well of course it didn't. that's why it was suggested to use the one-arity mapcat instead of introducing flatmap

16:54 rich originally introduced flatmap because mapcat already had a one-arity definition, i guess not noticing that the behavior of that definition is just "throw an exception in all cases"

16:56 mikerod: amalloy: yeah, that's the interesting part :P

16:58 puredanger: amalloy: I have learned that "rich didn't notice" is never a betting position

17:01 amalloy: puredanger: i recall hearing that the reason (mapcat f) wasn't the original definition was because mapcat didn't have an arity available for shortening. it turns out i actually heard this from you, and from context i believed you were telling me that this was rich's actual reason, rather than the reason you'd inferred

17:02 mikerod: Everyone overlooks things sometimes

17:02 :P

17:02 puredanger: I'd say that was part of the reason from a conversation I don't fully remember

17:03 amalloy: to see the specific conversation, search for "flatmap" in http://logs.lazybot.org/irc.freenode.net/%23clojure/2014-08-06.txt

17:03 puredanger: I remember my conversation with you. I don't remember the full conversation from Rich.

17:04 I am (always) an imperfect translator

17:05 amalloy: well, now the conversation is there for the reference of anyone who doesn't remember it or wasn't there

17:05 puredanger: I believe the other aspect is the semantics of cat vs concat

17:05 hiredman: puredanger: if only you had some stone tablets up on that mount

17:06 llasram: (inc hiredman)

17:06 lazybot: ⇒ 54

17:06 puredanger: I think the introduction of the cat transducer (whose semantics changed a bit before commit) was key

17:07 allowing mapcat to just be a transducer of (comp (map f) cat)

17:07 technomancy: hehe

17:08 "What's this? Everyone using pull requests while I was gone? *smashes tablets*"

17:08 hiredman: technomancy: lol

17:43 SagiCZ1: is there any channel like "friendly physics" ? just got yelled at by some physicist over at #physics xD

17:43 wkelly: lol

17:44 amalloy: now i'm curious what the atmosphere in #physics is like

17:44 SagiCZ1: pretty shitty.. if you are stupid like me

17:44 amalloy: answer: about 1 bar, amirite?

17:44 arrdem: I'd expect it's a frictionless vacuum...

17:46 hiredman: knowing physicists about 1 bar too few

17:47 SagiCZ1: amalloy: oh i just got the joke...... see im this slow

17:48 holo: I just asked at #haskell how to disable those commas in lists cause they are causing my a headache, and all i got was silence :(

17:50 arrdem: holo: page 11 of the Haskell 98 spec. lists have commas.

17:50 holo: my goodness

17:51 amalloy: you kinda need commas in any language that doesn't have sexprs

17:52 SagiCZ1: sexprs.. kinky

17:52 it means "sex-tit" in my language..

17:53 holo: amalloy if they have some other use for [], maybe use other kind of bracket. hey for 10 items it gets 9 commas!! insane

17:54 amalloy: holo: so uh...here's a list for you, how many elements does it have? [id id id id id]

17:54 SagiCZ1: 19?

17:55 arrdem: SagiCZ1: 1

17:55 holo: amalloy, 5. i know it's a trick though hehe

17:55 amalloy: arrdem: well, 1 in the current implementation. my point was if they took his change the answer would be "somewhere between 1 and 5"

17:55 arrdem: amalloy: yep

17:55 SagiCZ1: ,#{:id :id :id :id :id}

17:55 finishingmove: Quick questions guys: what web framework to use if I were to start working on an app right now, as a Clojure beginner? I know about Compojure but I don't know if something new came to existence since I fiddled with Clojure last

17:55 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Duplicate key: :id>

17:57 finishingmove: I'm looking for something like a micro-framework, with good documentation

17:57 scottj: finishingmove: compojure is still the most popular starting point.

17:57 holo: finishingmove there's alot of hype around Om for single page apps, but you'll need to use ring/compojure anyway also

17:57 mischov: finishingmove: Just start with compojure.

17:58 finishingmove: It's got the documentation.

17:58 holo: amalloy how come it's 1..5 items?

17:58 amalloy: holo: because it could be [id, id, id, id, id], or [(id id), (id (id id))], or...

17:59 spaces are for function application

17:59 finishingmove: compojure it is then, thanks for the tip guys :)

18:01 holo: amalloy oh yes on the spot. just forgot i was using this ML syntax thing :o thanks . now i understand their silence

18:02 mischov: holo: Oh Clojure how I love you so....

18:02 holo: mischov, i'm beginning to love haskell too. i may become polygamist

18:04 mischov: holo: I keep trying to love Haskell, but I always end up running away crying from the frustration of never getting anything done. Clojure is always there to rock me gently and tell me it's okay.

18:05 technomancy: "It's got documentation" <- high praise =)

18:05 bja: can I tell leningen to add :exclusions [org.clojure/clojure] to everything except the clojure I have specified as a dependency?

18:05 technomancy: bja: you can have :exclusions in the top level of defproject that do that

18:05 but I can't think of a good reason to

18:06 holo: mischov, wow.. i hope i'm not disappointed

18:06 bja: will that also exclude an explicit named dependency? ala (defprojec ... :exclusions [org.clojure/clojure] :dependencies [org.clojure/clojure "1.5.1"])

18:07 technomancy: yes, but excluding a dependency in itself won't do anything iirc

18:07 mischov: technomancy: Well I actually prefer other things to Compojure but all the tutorials and such are for it so I can't in good faith recommend people to start elsewhere.

18:07 holo: clojure has technomancy ← high praise

18:07 technomancy: bja: why are you looking for this?

18:07 mischov: holo: As long as you're not me you'll be fine.

18:07 bja: I made the mistake of asking lein deps :tree given that I'm AOT'ing stuff for storm

18:08 amalloy: technomancy: it's the only real way to run on a fork of clojure, if that's what you want to do

18:08 technomancy: amalloy: oh, true

18:08 bja: apart from that it should be only necessary if your deps specify version ranges, but that case is hopefully very rare

18:23 danneu: mischov: how's gate coming?

18:25 mischov: danneu: Not bad, actually. Switched up arg coercion.. it's much nicer. Also fixed some other things to take away surprises.

18:26 danneu: It works REALLY well with Component. I add routes to components and then make the router depend on those components and it automatically gets and joins their routes.

18:27 danneu: I need to get an example of that up.

18:28 danneu: param coercion is nice. i saw https://github.com/Prismatic/fnhouse doing that too

18:28 saves a lot of boilerplate

18:30 mischov: I had it previously but I borrowed prismatic/core.typed's style for it. Looks much nicer. Works nicer too.

18:30 https://github.com/mischov/gate#handler-and-defhandler

18:38 danneu: mischov: what's driving the development/direction of gate? do you use it on anything for yourself?

18:40 mischov: danneu: Yea, I use it for all my web projects. I've been using it recently on the backend for Om/Reagent which is what drove my recent change to improve how *splats work.

18:44 SagiCZ1: can i somehow combine assoc and assoc-in? lets say i want to alter some first level keys and some nested keys as well in one call

18:46 arrdem: &(= (assoc {} :foo 3) (assoc-in {} [:foo] 3))

18:46 lazybot: ⇒ true

18:46 Jaood: SagiCZ1: assoc-in can do both

18:47 scottj: perhaps he means how assoc can take multiple k/v's but assoc-in doesn't.

18:47 SagiCZ1: i guess?

18:47 can i do (assoc-in m [:a :b] :value [:c] :another-value)

18:48 mischov: (comp #(assoc-in % ...) #(assoc % ...))

18:48 :P

18:48 arrdem: http://grimoire.arrdem.com/1.6.0/clojure.core/assoc-in/

18:48 no

18:49 mischov: Probably wouldn't be too hard to write a function to do it, though.

18:49 clojurebot: It's greek to me.

18:50 SagiCZ1: alright nevermind.. its ok

18:50 ben_vulpes: would it be bad form to move https://github.com/xeqi/peridot/blob/master/project.clj#L13 into the :dev dependencies so that I can run tests from emacs?

18:54 gfredericks: ben_vulpes: I think that's what technomancy recommends; I do it.

18:55 ben_vulpes: gfredericks: should i duplicate the entries or just move them into :dev?

18:56 technomancy's stuff seems to not have much in :test...

18:56 * ben_vulpes wants a github.com/user/*/project.clj

18:57 technomancy: :test is for stuff which you want during `lein test` only

18:57 which is ... basically nothing

18:57 ben_vulpes: i want all my test stuff available in my emacs repl, but i'm a novice at all the things and so am almost bound to make bad decisions unbounded

18:59 technomancy: I kind of want a big ol project spider too

18:59 anyone looking for a learning project?

19:00 ben_vulpes: what are you thinking about?

19:04 TimMc: What's this about spiders?

19:04 Fare: anyone interested in pair programming?

19:05 justin_smith: ben_vulpes: "dunno, clojure stuffs"

19:06 TimMc: Fare: On what? (Over what medium?)

19:06 ben_vulpes: justin_smith: lol

19:06 Fare: is there a place to find a pair programmer for clojure?

19:07 TimMc: I probably shouldn't due to RSI, but I'm curious...

19:07 Fare: my pure python dialect compiler for clojure + whatever the pair programmer wants.

19:07 Google Hangout and screen

19:07 technomancy: ben_vulpes: I was implying spidering github for project.clj files would be a good learning project

19:08 arrdem: technomancy: I think aysylu already has a project that does that..

19:09 mischov: SagiCZ1: https://www.refheap.com/89871

19:09 technomancy: oh yeah?

19:09 arrdem: technomancy: she mentioned it near the end of her clojure/west talk on Loom IIRC

19:10 technomancy: Fare: have you seen talky.io? might be nicer than G+ for simple ad-hoc things.

19:10 justin_smith: mischov: excellent example code

19:10 SagiCZ1: is "2d" some sort of literal in java?

19:10 technomancy: arrdem: hm; and I guess clojuresphere probably has this too

19:10 arrdem: (inc mischov)

19:10 lazybot: ⇒ 1

19:11 SagiCZ1: mischov: thank you!

19:11 mischov: SagiCZ1: My pleasure.

19:11 SagiCZ1: ,2d

19:11 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 2d>

19:11 arrdem: mischov: mind if I slap that in detritus?

19:11 Fare: technomancy, I admit I haven't — it looks good, but is it worth switching from Hangout?

19:12 mischov: arrdem: Not at all.

19:12 Fare: TimMc: I can do the typing, if you have RSI

19:12 SagiCZ1: mischov: btw whats up with the name? does "ate" have some special meaning/

19:12 technomancy: Fare: IMO it's better if you have two or three participants only

19:12 SagiCZ1: ?

19:12 Fare: is there a way to get local variable bindings in a java / clojure stack trace?

19:12 technomancy: Fare: just because there's no login and the URL is memorable

19:12 Fare: technomancy, that's OK: only two needed for pair programming

19:13 mischov: SagiCZ1: assassinate ... associnate

19:13 technomancy: also: less reliance on google

19:13 TimMc: ++

19:13 mischov: SagiCZ1: Just a lousy joke.

19:13 * arrdem summons the all seeing G to hover over technomancy

19:14 * technomancy flees underground

19:14 TimMc: Fare: A compiler for a subset of Python?

19:14 SagiCZ1: mischov: ok thats what i thought :]

19:14 dbasch: technomancy Fare: Screenhero is pretty good, but after two weeks you have to pay

19:14 Fare: I'm thinking "variant" rather than "subset".

19:14 So far, the syntax is the same, but the semantics is different, due to purity.

19:15 i.e. x = y binds a new x that shadows the previous

19:15 YET, it's visible in the rest of the current function's body.

19:15 which can be... interesting.

19:17 Jaood: is there an emacs refheap theme?

19:17 Fare: not implemented yet: grouping successive def ... statements into a letfn

19:19 I'm not sure how to best do it in presence of decorators:

19:19 arrdem: typed clojure: no really that can return nil

19:20 Fare: should I group things into a letfn, then do the decoration, or have any decorator break letfn continuity, and lose any mutual-recursion?

19:24 TimMc: Hmm, it doesn't really inspire me. I'm leery at this point of creating new languages. :-P

19:24 scottj: Jaood: apparently refheap's theme is based on tomorrow night bright, which is available in emacs.

19:28 SagiCZ1: can i somehow kill a thread from repl to which i lost a reference? :D

19:30 hiredman: yes

19:31 http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html

19:31 SagiCZ1: hiredman: thank you

19:42 Fare: TimMc: it's more interesting for the compilation passes than for the language itself

19:42 the syntax part is solved

19:43 right now, I'm struggling with wrapping each statement in the "least suitable monad that can express all its effects"

20:13 bounb: so i added a dep (data.json) in my project.clj, ran lein deps but i get this "CompilerException java.lang.ClassNotFoundException: clojure.data.json" when i try and require data.json

20:13 can anyone give me a hint?

20:14 beamso: what does the project.clj and the :require look like on that namespace (feel free to use refheap.com to paste something into)

20:15 bounb: sure hold on

20:16 https://www.refheap.com/89878

20:17 uh

20:18 just noticed one uses :require and the other require

20:18 beamso: yeah, i saw that but i was going to try both

20:18 bounb: blame the lein docs for calling require directly

20:19 ,(doc require)

20:19 clojurebot: "([& args]); Loads libs, skipping any that are already loaded. Each argument is either a libspec that identifies a lib, a prefix list that identifies multiple libs whose names share a common prefix, or a flag that modifies how all the identified libs are loaded. Use :require in the ns macro in preference to calling this directly. Libs A 'lib' is a named set of resources in classpath whose contents...

20:19 bounb: beamso: i tried anyway, makes no difference as expected

20:19 beamso: the first require is something that you'd use at a repl, the second require is the same format that you'd see at the top of a namespace

20:20 the "(require '[clojure.data.json :as json])" way worked for me

20:20 bounb: ohhh

20:20 yeah i just got that ha

20:21 yeah it's cos i copied it outta an ns form

20:21 cheers

20:30 now i have a new problem https://www.refheap.com/89879

20:31 beamso: try removing the ":" from before "require"

20:32 bounb: huh ok that works. why

20:32 beamso: the ":" is for the top of a namespace, not for the repl

20:32 or the namespace declaration, i should say

20:33 SegFaultAX: bounb: What he means is the form (:require ...) is calling the :require keyword as a function.

20:34 bounb: ah yes i see because the ns macro has this (:require ) reference

20:34 yeah, and that keyword doesn't exist outside of the ns macro

20:34 SegFaultAX: And keywords will try and look themselves up in whatever you pass to them as their first argument when called as a function

20:34 bounb: yeah i got that

20:34 SegFaultAX: Which is how eg (:foo {:foo "abc"}) works

20:34 bounb: ya

20:35 SegFaultAX: Just filling out the explanation.

20:36 bounb: and if :foo isn't in your assoc, it's just nil, not an error

20:38 but (reduce ...) returns nil as well ;)

21:14 jeffterrell: Man, I'm loving the test-refresh lein plugin. Finally, a solution to getting ripped out of my flow for 60s JVM startup times!

21:14 https://github.com/jakemcc/lein-test-refresh

21:17 xulfer: Can't you just use cider since it's already running a jvm?

21:18 It does look nice

21:21 technomancy: or grenchman

21:28 jeffterrell: I had difficulties with clojure-test-mode in emacs, if that's what you mean by cider. I'm natively a vim guy. :-)

21:28 I haven't tried grenchman.

21:28 * jeffterrell looks it up

21:30 jeffterrell: Looks like grenchman could work, but I'd have to figure out how to use in a test-runner kind of way. Is that about right?

21:30 Does look nice in general, though, and something to keep in mind.

21:30 xulfer: jeffterrell: Ahh I see. I have no idea why I assumed emacs.

21:31 I too am a vim guy really. I just tend to use emacs on anything with a rep;. Old habits and what not.

21:31 jeffterrell: Yeah, I do like the emacs ability to integrate with a REPL.

21:33 technomancy: Seeing that there's a way to run lein tasks in grench, that narrows the gap. But the other thing test-refresh does is a dependency-graph-based refresh as necessary whenever files change. So it's pretty convenient.

21:40 technomancy: jeffterrell: I see; yeah that's handy

21:41 still, I wish the dependency-graph tracking were separate from the test runner

21:41 jeffterrell: It is, actually. clojure.tools.namespace.repl/refresh

21:41 technomancy: oh right; cool

21:42 jeffterrell: Grenchman's good to know about too. I'd consider us even, except that, well, you kinda wrote stuff that I use every day. :-)

21:55 I love Clojure's concision. Witness:

21:55 (get #{:aborted :finished :failed} job-status :finished)

21:57 technomancy: yeah, I'm always skeptical of lein plugins that exist just to run in-project code I guess

21:58 like ... why have a plugin? why not just have a :main entry point?

21:58 but whatever, it's cool

22:02 jeffterrell: Yeah, I could see that. Although one could argue that `lein test` just runs in-project code. :-) But yeah, I know what you mean.

22:03 xulfer: Hm I'm curious. What causes lein to search for a main function?

22:04 I created a lib the other day using the default lein template. Changed nothing in the project.clj. No gen-class. Still warns about no main when it installs.

22:04 Not a big deal, I just hate warnings on installs.

22:07 jeffterrell: xulfer: I think you have to have a :main value in your project map that points to a namespace-qualified function.

22:07 Maybe the default lein template doesn't have that?

22:07 xulfer: Hmm

22:07 jeffterrell: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L196

22:08 xulfer: but why would I need that if it is just a library?

22:08 gfredericks: xulfer: you shouldn't for a library; what do you mean "when it installs"?

22:08 xulfer: so I should just define some stub function? i'll do that to make it go away

22:08 gfredericks: On another project when I do 'lein install' and pull my lib in as a dependency.

22:08 xeqi: ben_vulpes: moving those are fine. That was from when I was concerned about dev/test seperation. I've since relented and usually just put things in :dev now

22:09 gfredericks: xulfer: so you have libA and appB and you don't see this warning (about libA) until you're messing with appB?

22:10 xulfer: i don't want to see the warning at all

22:10 i don't understand why there should be a warning about a lack of a main function in libA

22:10 i don't get that warning from any other dep

22:10 gfredericks: there shouldn't, I'm just trying to make sure I understand what you're talking about

22:10 what makes you think it's referring to libA instead of appB?

22:10 xulfer: Yeah I understand. Yes that's what I mean.

22:11 Because appB has a main, and it is explicit in warning about libA.

22:12 gfredericks: I've never seen a warning about main that referred to a library

22:12 xulfer: Yeah. I mean my guess is that somehow I'm doing something incorrect.

22:12 gfredericks: what's the exact wording?

22:12 xulfer: I'm just not sure what it is since my lein stuff is so minimal.

22:12 jeffterrell: xulfer: You get this warning when you run `lein install` in the libA directory? Or at some other point?

22:12 xulfer: no in another app that is pulling in libA

22:12 one second let me force it to pull it in again.

22:15 Warning: The Main-Class specified does not exist within the jar. It may not be executable as expected. A gen-class directive may be missing in the namespace which contains the main method.

22:16 gfredericks: aah ha

22:17 that is a different problem than the one we guessed you were having

22:17 xulfer: Oh sorry.

22:17 gfredericks: but closely related

22:17 xulfer: I would have been more verbose, but I had to wipe out my repo to produce that. :)

22:17 gfredericks: I haven't seen this but I imagine it means leiningen thinks your lib has a main class when it's compiling it

22:17 xeqi: that warning is about having a :main without having :gen-class within that namespace

22:18 gfredericks: but since you don't gen-class (and shouldn't) the class reference fails

22:18 xulfer: I think you don't want a :main entry at all in libA, right?

22:19 xulfer: i don't have a :main

22:19 and no main function

22:19 gfredericks: you don't want either, but it's hard to see how this situation would happen if you don't have a :main

22:20 you're sure you never had one?

22:20 xulfer: I can show you actually. Don't be too critical. I'm learning and it's just a small convenience project.

22:20 https://github.com/mbsmith/clj-systemtray

22:20 but you can check out the project.clj, and core.clj there

22:20 gfredericks: that's the lib or the app?

22:20 xulfer: lib

22:20 xeqi: xulfer: is there a :main in appB/project.clj?

22:21 xulfer: Yes. Technically a -main

22:21 gfredericks: xulfer: did you use lein uberjar?

22:21 for the lib?

22:21 xulfer: but it's using the app template from lein

22:21 gfredericks: No I don't believe so. It's getting the library via clojars.

22:21 So whatever lein deploy clojars uses

22:22 xeqi: xulfer: the -main would be in the refered to namespace. Does that namespace have :gen-class in its namespace declaration?

22:24 xulfer: xeqi: Yes.

22:24 But I don't think it's related to the app in question.

22:24 Because the warning did not appear until yesterday when I added this library as a dependency.

22:25 xeqi: ah, you're running `lein install` in appB. that will create a normal jar, without the compiled/aot'd class because of ^:skip-aot in the project.clj

22:25 I think you want to run `lein uberjar` in appB

22:25 to create a runnable jar

22:26 gfredericks: I just pulled clj-systemtry from clojars and it seems to have an okay manifest

22:26 so I'm going with xeqi's theory

22:28 xeqi: `lein install` will create a normal jar + pom and add it to your local maven cache, which lets lein find it for other libraries. `lein uberjar` will create a jar with all of the required code inside it, which can be ran using `java -jar $jar-name`

22:28 since its an app, I believe you want the latter

22:29 gfredericks: I've never heard of `install` for an app or `uberjar` for a library

22:31 xulfer: hm okay

22:31 i'll try that

22:33 xeqi: xulfer: https://www.refheap.com/89886 as an example

22:35 technomancy: gfredericks: https://github.com/Seajure/odo

22:35 ^ works with `installed` apps

22:35 well

22:35 technically `deploy`ed

22:36 gfredericks: HUH.

22:36 okay now I've heard of it

22:36 it's still not normal though :P

22:36 technomancy: (also this may or may not be a ridiculous idea)

22:36 gfredericks: oh it is

22:36 technomancy: seajure hack night; what more need I say

22:37 gfredericks: I read the thing joe armstrong wrote and didn't really get it; the server only shape shifts once

22:37 can't think of why that's useful

22:37 is it not supposed to be?

22:37 technomancy: useful? that's already a lib.

22:37 gfredericks: oh dear.

22:38 technomancy: stramg lop?

22:39 technomancy: gfredericks: nein =(

22:40 xulfer: Thanks for the help guys

22:40 I was under the impression uberjar was only for end deployment

22:40 gfredericks: technomancy: we'll I'll pretend you're there in your honor

22:40 technomancy: gfredericks: I'll be there "in spirit"

22:40 xeqi: xulfer: are you making an app that isn't for end deployment?

22:40 technomancy: which is code for "not"

22:41 xeqi: I consider that the diff between lib vs app

22:41 gfredericks: xeqi: it's for end deployment in spirit

22:41 xeqi: gfredericks: oh, the final end deployment

22:42 gfredericks: yes

22:42 xeqi: really gotta hope theres no bugs in that one

22:42 ... deadlock

22:58 xulfer: xeqi: It is, but when I'm just simply trying to make sure all of my reps are pulled in, and that my repo will work properly I've used 'lein install' in the past.

22:58 I guess that isn't correct.

22:59 xeqi: ah, I use `lein test` for that. Though it won't check the final uberjar creation. Really `lein uberjar` is the only thing that does that I know of

23:02 Fare: anyone interested in pair programming a clojure-written compiler from a pure python dialect to clojure?

23:13 korqio_: `

23:30 danneu: i want mmcgrana in charge of my SEO campaign because i don't think i've ever ended up on github.com/ring-clojure on my first try

23:32 he must use fiverr campaigns to spam backlinks to github.com/mmcgrana/ring

23:32 Jaood: what happened to that guy? he started lots of clojure web stuff and then dissapeared

23:32 dissapeared from clojure at least

23:33 danneu: maybe he's having some hammock time

23:33 technomancy: it was pretty weird. he got really into the product development side of things, and then into google go.

23:33 which was surprising to me until I realized he never actually learned how the clojure repl worked.

23:34 did all his coding in textmate and always restarted for every change, so of course it was super tedious to get anything done.

23:34 I guess if that's your idea of programming then google go could actually look appealing.

23:34 Jaood: ;)

23:35 well yeah, looks like clojure wasn't his cup of tea

23:36 danneu: dude just moved on

23:38 Jaood: technomancy: looks like he love textmate to much to leave it, he created clojure syntax highlighting for textmate

23:39 technomancy: does heroku uses Go heavily?

23:39 technomancy: Jaood: yes =(

23:40 Jaood: Ok, that could be one of the reasons :)

23:41 technomancy: I think the causality actually went the other way

23:41 Jaood: he brought Go to Heroku?

23:42 technomancy: he was one of the early adopters anyway

23:48 catern: wow what a dumbguy

23:57 danneu: not quite...

Logging service provided by n01se.net