# #clojure log - Jan 15 2016

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

2:37 ulischinz: hey there

2:37 i

2:40 i'm trying to transform a vector of maps to a map of vectors, maybe someone can help me

2:40 given [{:a 1, :b 2, :c 3, :d 4, :e 5} {:a 9, :b 8, :c 7, :d 6, :e 5}]

2:40 i'd like to get {5 [{:a 1, :b 2, :c 3, :d 4, :e 5} {:a 9, :b 8, :c 7, :d 6, :e 5}]

2:42 i tried a lot but i cant manage... best result so far was a list of vectors :)

2:42 (for [p [{:a 1 :b 2 :c 3 :d 4, :e 5} {:a 9 :b 8 :c 7 :d 6 :e 5}]] [(:e p) p])

2:44 but thats not really what i want..

2:52 qsys: where's the 'p' comming from?

2:58 Kneiva: ulischinz: each map has an :e that you want to use as the key?

2:59 luma: (group-by :e maps)

3:06 ulischinz: sry tel...

3:08 now... @qsys i'd say that p is each element in that array...

3:08 Kneiva: exactly

3:09 luma: maps is ment to be the array of maps?

3:09 luma: yes

3:09 Kneiva: ulischinz: then what luma said above.

3:10 ulischinz: gonna check it out

3:10 Kneiva: ,(group-by :e [{:a 1, :b 2, :c 3, :d 4, :e 5} {:a 9, :b 8, :c 7, :d 6, :e 5}])

3:10 clojurebot: {5 [{:a 1, :b 2, :c 3, :d 4, :e 5} {:a 9, :b 8, :c 7, :d 6, :e 5}]}

3:10 ulischinz: uhhhh how nice, thank you a lot

3:27 thanks again, its workig in my dev-environment with my production data...

3:30 Kneiva: (inc luma)

3:30 :/

3:33 yunfan: what do you guys recommend for using clojure developing website?

4:32 TEttinger: yunfan: depends what you want

4:33 a lot of people prefer to avoid using a stack of existing libraries that must be used together (ruby has this with rails, it has good and bad sides)

4:34 if you want a stack like that but a little more clojure-y, there's caribou

4:34 ~caribou

4:34 clojurebot: Excuse me?

4:34 TEttinger: I think luminus is also a thing

4:35 otherwise, the various ring stuff may be what you're after, maybe look at how Om examples are hosted

4:35 yunfan: well i dont need rails like TEttinger

4:36 it should be better to use a flask like one for me

4:36 TEttinger: http://www.clojure-toolbox.com/

4:50 qsys: yunfan: I usually use vert.x, which is not clojure. However, client-side I like clojurescript (rum) a lot, client side, I call clojure code from Java. vert.x just makes all kind of auth, communication, ... extremely easy. vert.x 2 could handle clojure. There's a clojure implementation on the way in vert.x 3, I hope :p.

4:50 ... server side, I call clojure code from Java...

5:09 yunfan: qsys: thanks

8:31 neoncontrails: I think this is syntactically okay: (sql/db-do-commands "postgresql://localhost:5432/sandboxâ€ť (sql/create-table-ddl :testing [:data :text]))

8:32 I got it from the Heroku Clojure/Postgresql quick start guide.

8:32 But I'm getting the following error:

8:32 BatchUpdateException Batch entry 0 CREATE TABLE testing (data text) was aborted. Call getNextException to see the cause. org.postgresql.jdbc2.AbstractJdbc2Statement\$BatchResultHandler.handleError (AbstractJdbc2Statement.java:2762)

8:34 How do I call getNextException? (and on what?) I found some solutions, but the wrapper they used is since deprecated.

8:34 justin_smith: neoncontrails: you get the exception object e, and call (.getNextException e)

8:35 you get that object by catching it, or in the repl, it will be bound to *e

8:36 neoncontrails: That asterick might be what was throwing me off. I'll try that

8:36 justin_smith: neoncontrails: *e is just the magic value in the repl

8:37 in real code you would do (try .... (catch BatchUpdateException e (println e) (println (.getNextException e)))) -- something like this

8:40 neoncontrails: also, I think the root issue is that db-do-commands does a transaction, and transactions and ddl don't mix

8:41 neoncontrails: justin_smith: weird. Let me make sure it's the same command I borrowed from Heroku

8:44 Yeah, that's the same command as here: http://webcache.googleusercontent.com/search?q=cache:EOVSDgZ_WHgJ:https://devcenter.heroku.com/articles/clojure-web-application+&cd=1&hl=en&ct=clnk&gl=us (original seems to be down at the moment)

8:44 justin_smith: neoncontrails: https://clojure.github.io/java.jdbc/#clojure.java.jdbc/db-do-commands

8:46 neoncontrails: maybe ddl can be done in a transaction? anyway, getNextException will show you more info, if you catch the exception, log it, and then do the same with the nested exception

8:48 neoncontrails: Good idea. Thanks for telling me about *e, I had tried it the way and couldn't understand why it wasn't working

8:48 *the other way

10:45 justin_smith: amalloy_: so did that compojure GET trick with runtime symbols work?

11:32 kungi: I am trying to compile an uberjar and keep getting "Method too large" errors from my compojure routes ...

11:33 Any Idea what I might be doing wrong?

11:33 tcrayford____: kungi: do you have lots of routes? Do they call lots of code?

11:34 justin_smith: kungi: put the body of the handler in a function, and call the function in the route

11:34 kungi: justin_smith: I do that everywhere.

11:34 justin_smith: unless the problem is having thousands of routes...

11:35 kungi: No not thousands. Less than 100.

11:35 justin_smith: kungi: are you using any macros like core.match or core.async inside the route definitions?

11:35 kungi: justin_smith: no

11:36 Firstly I wrapped all routes in a record to use them as components. Which worked fine.

11:36 I usually compile my application to an uberjar.

11:37 Then I added a small middleware function and the compilation started to fail.

11:37 justin_smith: maybe it would help to make sure you are not destructuring in the route definitions, and move the destrucuring into the individual handler functions

11:37 kungi: So I put all routes back into defroutes and eleminated the wrapping records etc...

11:37 justin_smith: or to split up the routes - you can define a set of routes as a handler

11:38 kungi: justin_smith: I did this. But it still fails.

11:39 I had the same problem a couple of days ago with my api routes (depending on compojure-api). I unwrapped them from their records and put them in compojure-api/defroutes* and it worked fine.

11:41 Somehow building an uberjar merges all the handlers together or ... something

11:43 ikitommi_: kungi: pre 1.0.0 compojure-api uses compile-time route resolution, which might cause that. With 1.0.0, the route tree is resolved at runtime. Should remove these issues

11:43 kungi: ikitommi_: there is a 1.0.0 compojure api?

11:44 I am using 0.24.4

11:44 ewilazarus: hey there guys. i need a little help with this function: http://pastebin.com/W3dDne9k - how could i break out of a for loop?

11:44 MJB47: you cant in clojure

11:44 luma: ewilazarus, for isn't a loop

11:44 MJB47: if you need to you can use loop recur, or reduce/reduced

11:45 luma: it's a list comprehension

11:45 MJB47: or just normal recursion

11:45 ikitommi_: kungi: soon, see https://github.com/metosin/compojure-api/blob/runtime-route-resolution/CHANGELOG.md#100-snapshot

11:45 luma: if you want a loop, use recursion or loop/recur

11:45 ewilazarus: ok, but in that case would i be able to break?

11:47 kungi: ikitommi_: I'll try compiling it with 1.0.0-SNAPSHOT

11:47 ikitommi_: 1.0.0. is not on clojars yet?

11:47 ikitommi_: kungi: not at clojars yet, will finalize things on weekend

11:48 justin_smith: ewilazarus: in a loop, all you need to do is not call recur, and it won't continue

11:48 lambda-11235: Are clojure's symbols the same as other lisps in that they have a comparison time of O(1)?

11:48 ikitommi_: need to write migration guide & make better error messages.

11:49 justin_smith: ewilazarus: if you use for, and generate a comprehension, it's lazy, so you can just top taking values from the list comprehension when you get "enough", whatever that means in your case

11:49 ewilazarus: justin_smith thanks

11:49 justin_smith: ewilazarus: also, the for list comprehension has a :while key where you can specify a condition that makes the results stop

11:49 but it's not a loop, it's generating a list

12:20 orz: Are there any software engineers here who might be willing to answer a few career-related questions from someone just starting out? I promise not to take up much of your time.

12:35 kungi: orz: sure

12:38 blake__: orz: Sure.

12:42 mpenet: ikitommi_: compojure-api looks sweet

12:43 anyone cared to bench compojure routing ("clout") vs bidi for instance, I am curious?

12:58 blake__: I've got ClojureScript added into my Compojure project: Yay, me.

12:58 bitfx: affirmative :)

12:58 blake__: I created a clojure function called "log-message".

12:58 And I'm calling it from Compojure like: :onchange "cmart.core.log_message.call(null, 'Hello from Clojure!')"

12:59 bitfx: ahh, the exiting moments when trying out a new new language.

12:59 lokien: exiting :^)

13:00 blake__: Is that about how it goes? I know inside of cljs I can be all Clojure-y. But to talk from Compojure, I need the ugly Javascript?

13:01 Or is there some way to alias?

13:03 ridcully: blake__: just to have it asked: does this still work with :advanced compilation?

13:06 blake__: ridcully: Dunno, but thanks for asking. I wondered about name-mangling.

13:07 I'll have to check it out.

13:07 So what does one do?

13:11 Or am I the only one doing this? We either go big, all ClojureScript, or go home (to Javascript, shudder).

13:30 ikitommi_: mpnet: thanks ;) there is some bench at bidi readme https://github.com/juxt/bidi/blob/master/README.md#contributing

13:32 amalloy: justin_smith: yeah

13:33 (apply routes (for [uri [...]] (GET [uri] ...)))

13:34 justin_smith: cool

13:34 I'm guessing that feature came after we did our own wacky solution

13:36 blake__: So, :advanced compilation doesn't seem to change anything, which makes me think I did it wrong.

13:36 But maybe it doesn't name mangle?

13:36 justin_smith: advanced should definitely be name mangling

13:38 amalloy: justin_smith: tbh i'm guessing that features has been there for a long long time. weavejester's stuff tends to support arbitrary inputs, and then additionally optimize for compile-time-known inputs

13:39 blake__: Maybe it's too simple a case.

13:39 amalloy: like how (html [:div foo]) compiles to like (str "<div>" foo "</div>"), but (let [tag :div] (html [tag foo])) still works, by analyzing the tag at runtime

13:45 blake__: OK, so I'm thinking the safe, clean way to do this is to export my clojurescript functions.

14:34 itruslove: scgilardi you're back!

14:48 TimMc: \o/

14:49 Mr. Scenario C. Gilardi

14:51 amalloy: haha

15:17 lokien: how are you guys so quiet today? now I feel bad about that I'm procrastinating

15:18 not reading interesting irc stuff or anything

15:23 TEttinger: heh. I'm complaining about Firefox crashing constantly in #perl6 to someone I suspect may be a Mozilla fan

15:25 lokien: and you're.. a chromium fan?

15:25 kwladyka: is any nicer method to write ((first coll-f)) ? something like (run (first col-f)) or something less confuse?

15:27 TEttinger: lokien: if Firefox didn't crash for me and use hefty memory since an update several years ago, I would still be a firefox fan

15:27 lokien: TEttinger: several years ago and you're still mad at it? oh man

15:29 TEttinger: well I still need to open it occasionally

15:29 uptime: 54 milliseconds before crashing

15:30 lokien: aand you're on windows?

15:42 domgetter: I'm having trouble understanding namespaces. I'm trying to make a Luminus app, and when I'm in the repl, I can access myapp.views.index/html, but in the code in myapp.routes, I can't access that function unless I (ns myapp.routes (:require [myapp.views.index :refer :all]))

15:42 Does the repl behave differently than my code does when I lein run it?

15:47 tdammers: depends how you start the repl, but yes

15:59 domgetter: Is there something like a let-ns which lets you do something in a namespace, but when the form ends, goes back to the previous namespace?

16:00 justin_smith: domgetter: wanting to write code in another ns is a symptom of a design problem, from what I have seen the solution is usually that you need another ns that accesses both of them

16:01 domgetter: justin_smith: I'll admit I may be doing something problematic. I'm trying to make a web framework that will be familiar to Rails developers.

16:02 That is, this framework will be "opinionated"

16:03 justin_smith: well surely one can be opinionated without being wrong, and wanting to put code in another namespace is usually a sign you are doing it wrong

16:04 perhaps you need to inject a dependency, protocols are good for this

16:04 lokien: aren't our frameworks good enough though?

16:05 domgetter: lokien: Yes, I'm just trying to make something with the explicit goal of feeling familiar to Rails devs

16:06 justin_smith: I'm trying to make it so that when a route is generated from, say {:get "/photos"}, a helper is available in the views for (photos-path) that makes a link to that route

16:07 justin_smith: domgetter: then I would create the namespace using create-ns and use intern to create the values, and make it clear that the ns is a runtime thing only and has no static file corresponding to it

16:07 it's still ugly, but at least that way it's possible

16:08 domgetter: also, consider that instead of an ns you could have a simple hashmap of keys to functions

16:08 especially since it would not be meant to map to any ns that actually exists

16:08 (as a file, that is)

16:19 domgetter: justin_smith: ah interning is the solution for which I was looking. I do promise to consider the hashmap with keys to functions solution.

16:20 justin_smith: domgetter: a pattern that has worked for me in the past is attaching keys to the request object, containing hash maps that the request handler can look in to find runtime resources, or custom handler functions that can't be provided at compile time

16:20 eg. a map that you can look in to find a cache of db results, or the current db config, or an asset pipeline the handler should invoke

16:24 hiredman: domgetter: you are not the first person to come from rails to want something like that, https://github.com/macourtney/Conjure comes to mind, but no one who uses clojure regularly seems to want that

16:47 domgetter: hiredman: Interesting. I like what they did with generators, but I think I have a pretty slick idea for routing. We'll see how it pans out

16:58 nanuko: anyone know why prismatic has moved to plumatic on github?

17:02 justin_smith: nanuko: google fu, the libs interfering with the result standing of their product?

17:03 nanuko: maybe this is a sign ... http://getprismatic.com/home

17:04 nanuko: "On December 20 2015 the company closed its consumer-facing apps and focuses on offering its machine learning algorithms to publishers and hedge funds.[5]" https://en.wikipedia.org/wiki/Prismatic_(app)

17:11 nanuko: justin_smith: yeah, after poking around a bit, i found an article http://venturebeat.com/2015/12/11/prismatic-is-shutting-down-its-news-app-for-ios-android-and-web-on-december-20/

17:42 princeso: justin_smith: are you into caribou man?

17:59 justin_smith: princeso: I am one of the caribou devs, but we haven't been working on it very actively lately

18:19 domgetter: How come + is available everywhere without requiring clojure.core?

18:20 Is it possible to make something like that myself? Or would I have to modify Clojure itself?

18:20 (I'm not saying I want to, I'm just trying to understand)

18:20 justin_smith: domgetter: the ns macro implicitly calls refer-clojure

18:20 which is basically (require '[clojure.core :refer :all])

18:21 domgetter: vinyasa has tools for doing similar stuff with your own stuff for dev

18:21 domgetter: ahh I see

18:29 WickedShell: Gotta be a stupid question: I'm porting some Java code to clojure and woking with interop i have a case where in java I would pass Rectangle.class what would the equivlent be in clojure?

18:30 amalloy: ,String

18:30 justin_smith: Rectangle

18:30 clojurebot: java.lang.String

18:30 WickedShell: just pass it directly? well thats farrrr more convient

18:51 justin_smith: is it possible to request that clojure.data.xml be more lax about input? or perhaps there is anotherl lib that similarly does lazy sax based parsing and is flexible about input validity?

18:52 amalloy: justin_smith: tagsoup or a relative?

18:55 justin_smith: amalloy: the "lazy" option of clj-tagsoup is not actually lazy in terms of consuming the input, or even parsing.

18:56 amalloy: just fixed a thread leak in my app caused by the thread clj-tagsoup uses to generate elements never exiting if you don't fully consume the stream it creates

18:56 (doall x) - wow, 4000 threads is now 400 threads

18:56 amalloy: well, when you have a clojure library that wraps a java library badly, go to the source

18:57 justin_smith: right, right

18:57 amalloy: tagsoup alleges to expose a sax-like api

18:57 justin_smith: I spent a little time reading tagsoup, and ... yeah, I guess I know what's going to be giving me a headache this weekend :)

18:57 amalloy: but i can't easily find api docs

18:57 justin_smith: yeah, looks like I'

18:57 ll be making that wrapper

18:58 amalloy: well, "badly". arguably it wraps the java library in a way that is just at a different place on the convenience/correctness spectrum

19:00 justin_smith: right, right. I need specific features it wasn't providing.

19:01 but "create a thread that never exits unless you consume all the elements of this lazy seq" is a hell of a gotcha

19:02 amalloy: you'd be surprised how many people have created lazy seqs that assume you will fully consume them

19:05 hiredman: :(

20:25 oracle: how to split [1 2 3 5 6 7] into [1 3 6] [2 5 7]

20:25 split by position

20:27 justin_smith: ,(apply map list (partition-all 2 [1 2 3 5 6 7]))

20:27 clojurebot: ((1 3 6) (2 5 7))

20:27 justin_smith: ,(apply map list (partition-all 3 [1 2 3 5 6 7]))

20:27 clojurebot: ((1 5) (2 6) (3 7))

20:27 oracle: great, thx

20:31 ridcully: ,(apply map list (partition-all 2 (range 7)))

20:31 clojurebot: ((0 2 4 6))

20:33 justin_smith: ,(apply map list (partition 2 (range 7)))

20:33 clojurebot: ((0 2 4) (1 3 5))

20:33 justin_smith: aha! a case where partition is a bit better behaved than partition-all

20:36 TEttinger: ,(take-nth [1 2 3 4 5 6 7] 2)

20:36 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

20:36 TEttinger: ,(take-nth 2 [1 2 3 4 5 6 7])

20:36 clojurebot: (1 3 5 7)

20:36 TEttinger: oh there was no 4

20:39 ridcully: ,(let [r (range 6)] (map (partial take-nth 2) [r (rest r)]))

20:39 clojurebot: ((0 2 4) (1 3 5))

20:39 ridcully: ,(let [r (range 7)] (map (partial take-nth 2) [r (rest r)]))

20:39 clojurebot: ((0 2 4 6) (1 3 5))

20:47 pilne: i blew up my clojure >.<

20:48 although it actually might be leiningen

20:49 ridcully: errors?

20:50 pilne: installed lein per the website, then ran "lein" and then when i tried to run "lein repl" i get all sorts of java.security.* errors

20:53 justin_smith: pilne: what lein version?

20:53 pilne: 2.5.3

20:54 justin_smith: os and java?

20:54 pilne: ubuntu 15.10 openjdk 1.8

20:54 64bit

20:54 justin_smith: hmm

20:55 pilne: i concur

20:56 lein run in a made project gives: Could not transfer artifact org.clojure:clojure:pom:1.7.0 from/to central (https://repo1.maven.org/maven2/): java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

21:00 pilne: you the man

22:00 kenrestivo: i wonder how much time could be saved if IDEs had a "google" button that copied/pasted the error message into google

22:01 i have to think that's the #1 debugging approach around. amazed it hasn't been automated yet

22:13 pilne: pretty sure it can be added to atom somehow, it has hoogle integration for haskell

22:40 amalloy: do people really google entire stacktraces?

22:40 TEttinger: yes.

22:40 me.

22:41 TimMc: "do people really google \$FOO?" "yes"

22:41 TEttinger: normally you need to take some of it out

22:42 yeah amalloy, why are you asking that question? "do people really google twerking dogs?" might be more interesting

22:50 * TimMc duckduckgoes that

23:36 sdegutis: Is there a way to combine cond and let somehow?

23:37 I'd like to have a ton of conditions in the cond, and guard against bad values early on, and if they're good values, transform them and continue with the conditions.

23:37 I'm 99% certain it's not possible, but if it can be done, I'm 100% certain justin_smith would be the one to come up with the way :D

23:38 lambda-11235: sdegutis: You mean like if-let?

23:38 sdegutis: Kinda, but within cond, so I don't have to have another cond within a cond.

23:38 I've seen cond-let, but I'm pretty sure it's one-shot like if-let is.

23:39 I'm thinking more like (cond (nil? email) :error, bind 'user (get-user email), (nil? user) :error, ... )

23:39 Or something weird.

23:40 justin_smith: sdegutis: I assure you good sir, your high esteem of my knowledge in all things clojure is undeserved, and on this question I must disappoint you. I'd probably end up making some terrible concoction using delay and deref chains. There might be something like what you want hidden in the depths of flatland/useful though.

23:40 sdegutis: Haha

23:41 amalloy: nah, this massive let is not really a style we love. it exists, though, as egamble/let-else

23:42 sdegutis: Hmmm interesting.

23:43 But yeah, it's a bit gross.

23:43 I'll just have to get comfortable with nested conds.

23:43 Or an if-let at top.

23:43 Meh, nothing's perfect.

23:44 justin_smith: sdegutis: in all seriousness, in cases where I have complex logic that decides which bindings should be realized, I've found a let block full of delays, (some of which derefing other delays internally), combined with a cond block that decides which ones to deref given the runtime conditions works out OK

23:45 sdegutis: Hmm. Interesting idea.

23:46 amalloy: flatland/useful *does* have let-later, to manage that for you

23:47 sdegutis: Very neat.

23:55 Good night amalloy and justin_smith.

Logging service provided by n01se.net