#clojure log - Jun 23 2013

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

1:24 clizzin: navgeet: pretty sure friend doesn't actually handle oauth2 provider logic, it only provides a framework into which you can plug in different authentication/authorization logic

1:27 tomjack: has oauth2 changed in the last 10mo?

1:27 maybe clauth is OK? :)

1:27 clizzin: maybe it is!

1:27 i'll try it out, seeing as how there doesn't seem to be much else. the readme claims to have implemented everything but refresh tokens.

1:29 dyreshark: how can i turn a string into a list of unresolved symbols (i.e. (= '(foo bar baz) (??? "(foo bar baz)")))

1:31 tomjack: read-string or clojure.edn/read-string

1:31 if you trust or don't trust, respectively, the string

1:32 dyreshark: thanks!

1:41 ak5: hey guys, I am doing 4clojure and when doing this: (I figured it out, but I do NOT understand the syntax of the problem) http://www.4clojure.com/problem/71 aren't (= (count (sort (rest (reverse [2 5 4 1 3 6])))) and (-> [2 5 4 1 3 6] reverse rest sort count) the same?

1:43 tomjack: sounds like you understand it to me

1:43 ak5: tomjack: the page is broken then I guess

1:44 normally there would be 2 unit test "lights"

1:44 ?

1:44 tomjack: it's one big equality

1:44 ak5: oh

1:44 lol

1:44 tomjack: what you type goes in both blanks

1:44 ak5: haha ok I missed that

1:44 thanks sorry for wasting your time

1:44 tomjack: = can take multiple args

1:45 ak5: got it

1:45 tomjack: no need to apologize :)

1:46 ak5: tomjack: BTW, this all seems fairly academic, where do I start learning about clojure for the web?

1:47 dyreshark: ak5: if you can grab an ebook version of the joy of clojure, that was my first resource

1:47 it's a great read imo

1:48 ak5: dyreshark: cool, thanks

1:55 tomjack: Clojure Programming has two chapters about the web

1:57 I think I'd start here though https://github.com/ring-clojure/ring/wiki

2:07 ripplebit: guys is clojure better than racket?

2:08 Foxboron: I'd say nothing is "better"

2:08 krig_: racket is a better racket than clojure, but clojure is a better clojure than racket

2:08 Foxboron: different tools, different job.

2:10 dyreshark: https://www.google.com/search?q=racket+vs+clojure <

2:18 tomjack: anyone have good indentation in *nrepl*

2:18 (and more)

2:26 derek_c: in terms of style, when you want to declare a number of variables built on top of one another, what are you guys' take on nesting a bunch of `let` versus using `do` with a series of `def`?

2:28 tomjack: are you talking about inside a fn/defn?

2:29 derek_c: yeah

2:29 tomjack: don't use def inside a fn/defn

2:29 derek_c: tomjack: why not?

2:29 tomjack: it is for defining top-level variables

2:30 aka "vars"

2:30 let is not about vars

2:30 derek_c: let defines an immutable binding, right?

2:30 tomjack: right

2:31 derek_c: I just realize that in a let, you can refer to a binding in another binding

2:32 so you don't really have to nest let

2:32 (let [a 1 b (+ a 1)] b)

2:32 scottj: tomjack: briefly sampling nrepl.el fork network I didn't see any commits fixing indentation in *nrepl* fwiw

2:32 derek_c: tomjack: thanks!

2:32 scottj: I wish there were a way to search all commit messages of all forks of a repo

2:33 tomjack: ah, I didn't think to check the fork network, good idea, thanks

2:33 scottj: good project idea

2:33 "a way to search.."

2:33 scottj: tomjack: yeah, the other feature I want is a way to view them w/o hovering the mouse of tiny dots :)

2:33 tomjack: yeah god it's horrible

2:34 derek_c: so is it idiomatic to use vectors as tuples?

2:35 tomjack: yes

2:35 derek_c: is it more efficient to pattern match against vectors than other collection types?

2:37 tomjack: nrepl just told me "you're bound to be unhappy if you optimize everything -- Knuth" :)

2:38 the cost of destructuring rarely enters my consideration - but perhaps your load is different

2:38 derek_c: tomjack: yeah I guess you are right :P

2:38 SegFaultAX: scottj: You can.

2:39 scottj: But why do you want to?

2:40 scottj: SegFaultAX: which feature are you responding to, the searching or the viewing?

2:41 SegFaultAX: derek_c: When you say pattern match do you mean destructuring or core.match?

2:41 scottj: Searching.

2:41 scottj: SegFaultAX: I see a way to search code for all of github or a repo. I don't see how to search commit messages for all forks of a repo. Can you point me where to look?

2:41 derek_c: SegFaultAX: I meant destructuring

2:41 SegFaultAX: scottj: Oh for all forks.

2:42 scottj: I misread, sorry.

2:43 derek_c: that said, I just checked out core.match; looks pretty cool. reminds of of OCaml

2:43 *reminds me of

3:07 SegFaultAX: derek_c: To answer your previous question, yes destructuring vectors is quite fast.

3:18 tomjack: consider a function which takes a destination channel as an arg and puts messages asynchronously, returning a channel which indicates that it's done putting

3:19 is there no easy way for this function to indicate that it's done if the destination channel is closed?

3:20 i.e. the function will either be responsible for closing the dest itself, or its 'done' channel will potentially block forever

3:21 (or the dest will never be closed)

4:16 derek_c: I'm doing some Java interop and just ran into a problem: so I'm trying to do this:

4:16 (apply .register dir watcher types)

4:16 .register is a method of dir

4:16 but the compiler says it's unable to resolve .register

4:17 I could do (.register dir) with no problem

4:17 but apparently I can't use apply with .register

4:18 anyone knows how I would use apply in this case?

4:33 amalloy: you can't apply java methods: they are not functions

4:34 you just have to figure out what args to call with, and manually unpack the seq yourself

4:39 derek_c: amalloy: is that the only way? I don't think in my case it's possible to manually unpack the sequence, since it could be of any size

4:39 amalloy: derek_c: but there are only a limited number of overloads of the java method

4:40 derek_c: amalloy: hmm you are right

4:41 mthvedt: derek_c: you can do a non-varargs call with into-array

4:41 derek_c: mthvedt: what do you mean?

4:41 mthvedt: (.register dir watcher (into-array types))

4:42 varargs methods have non-varargs overloads that take arrays

4:42 it's been a while since i last used java though, don't quote me on anything

4:44 derek_c: mthvedt: into-array doesn't seem to do what I want

4:44 (+ (into-array [1 2 3]))

4:44 I thought this would return 6

4:45 mthvedt: clojure varargs are not the same as java varargs

4:46 derek_c: wow man it actually worked

4:47 I still don't understand what's going on though

4:47 how come the java method would accept an array?

4:49 mthvedt: derek_c: varargs in java is just syntax sugar

4:49 the underlying method takes an array

4:50 tomjack: whenever the javadocs say ...

5:23 calvinx: hey guys, I am trying out a super simple new clojure project created via "lein new app learnclojure" and I am not sure why my compiled jar fails to work - http://pastebin.com/dyUMadEJ

5:25 what am I missing here?

5:28 Foxboron: calvinx: try "lein uberjar"

5:28 compile Compile Clojure source into .class files.

5:28 uberjar Package up the project files and all dependencies into a jar file.

5:28 calvinx: ok. so what's the difference? between "lein compile; lein jar" and "lein uberjar" ?

5:29 lein compile - ok, understood.

5:29 lein jar?

5:29 Foxboron: uberjar also adds the clojure dependency

5:29 lein jar&compile dosnt

5:29 i think, i am not sure.

5:29 calvinx: ok

5:31 so what's the point of compile and getting .class files? (sorry, I am new to java)

5:31 Foxboron: i got no clue of java either :3 sorry

5:32 AFAIK, .class files only contains the actuall compiled code, but the code relies on the clojure api/lib.

5:32 calvinx: ;D

5:32 Foxboron: so if you dont run the compiled code with the clojure dependency, clojure wont run.

5:32 again, i am not sure ^^

5:32 calvinx: so you always do "lein uberjar" to test your project?

5:32 Foxboron: or use lein run

5:33 or write tests!

5:37 calvinx: ok

5:37 another question

5:37 is there an auto documentation tool in clojure land?

5:37 Foxboron: good question.

5:37 calvinx: in python land (where I come from), we use sphinx to extract docstring

5:38 and make any modifications to the documentation source as restructured text

5:38 which can be compiled into html as needed.

5:38 Foxboron: well, java got javadoc

5:38 but i am not sure if there is something for clojure

5:38 (also python guy btw)

5:38 calvinx: oo. nice. :)

5:38 I see that when I start a new project with lein,

5:38 a "doc" directory is created.

5:38 and inside it is one single markdown file.

5:39 so my question is, what is a systematic way of extending more documentation files

5:39 and whether there's an "docstring" extractor.

5:39 Foxboron: well, i don't know. So i am googling atm

5:39 calvinx: http://stackoverflow.com/questions/5334525/state-of-the-art-for-clojure-documentation-tools

5:39 Foxboron: http://tomfaulhaber.github.io/autodoc/

5:40 oh, nice. Gotta save that tool for later

5:55 schmir: how do I catch any exception? does (try ... (catch Exception err ....)) do that? or are there other classes of exceptions that could be thrown?

5:57 tomjack: http://docs.oracle.com/javase/6/docs/api/java/lang/Throwable.html

5:57 generally you should not catch all throwables

6:04 schmir: tomjack: thanks.

6:47 fikusz: I'm working on a huge messy parsed html structure right now and it's really hard to explore in the repl (because even the subtrees are very large and are full of junk)

6:48 It would help if I could explore it like I would with firebug

6:48 anything like that for clojure objects?

8:25 sandbags: I'm doing the clojure koans and come to the first map example and hit a snag -- https://gist.github.com/anonymous/ee47d4ef24f9c2a04c9b -- i'm sure i've just done something stupid but i can't see it, can anyone help me?

8:34 hyPiRion: sandbags: It's actually very easy

8:34 ,(hash-map :a 1 :b :2)

8:34 clojurebot: {:a 1, :b :2}

8:34 hyPiRion: note the colon before the 2?

8:34 sandbags: yes

8:34 ah goddamnitall

8:34 hyPiRion: heheh

8:34 sandbags: thank you

8:35 hyPiRion: those darn small mistakes, egh

8:35 *eh

8:35 sandbags: the eye does not see what the brain does not want to see :)

8:35 hyPiRion: yeah

8:35 sandbags: thanks again

8:35 the worst part is that i typed it that way at least once more

8:36 when i tried to verify it in LightTable

8:36 stupid brain

8:36 i shall kill you with beer

9:05 jballanc: hmm...what do people usually do when they have config that applies only to "test" mode?

9:07 callen: jballanc: config of what?

9:08 jballanc: typically you're talking env vars.

9:13 jballanc: yeah, currently I have a configs.clj that switches on a env var

9:13 just seems slightly inellegant

9:14 hmm...I wonder if I could use lein profiles to load only one version of config.clj depending on the profiles used?

9:27 ah, this seems like it might do the trick: https://github.com/weavejester/environ

9:28 mpenet: yup, environ is perfect for that

10:00 Okasu: ,(resolve 'call-cc)

10:00 clojurebot: nil

10:00 Okasu: &(resolve 'call-cc)

10:00 lazybot: java.lang.SecurityException: You tripped the alarm! resolve is bad!

10:02 Okasu: &(eval 1)

10:02 lazybot: java.lang.SecurityException: You tripped the alarm! eval is bad!

10:08 Okasu: &clojure.core$resolve

10:08 lazybot: java.lang.SecurityException: You tripped the alarm! resolve is bad!

10:32 Okasu: &((defmacro meh [] `(~(symbol (str "res" "olve")))) '() '())

10:32 lazybot: java.lang.SecurityException: You tripped the alarm! def is bad!

12:11 jjttjj: I'm trying to use lein-beanstalk and am pretty clueless. I have template .html files in my src directory that don't seem to be getting included in the WAR. How do I include them?

12:13 llasram: jjttjj: Usually those sorts of files would go into a `resources` directory. That may not be the problem though, as generally everything in `src` would also end up in your JAR/variant

12:14 jjttjj: llasram: yeah I guess I was just wondering if that sounded like it might be the problem. Thanks for the input I'll mess around some more

12:29 is there any obvious reason I might be getting a FileNotFound exception on a file in my src directory when deployed with lein-beanstalk, when things work fine locally?

12:29 n_b: Probably something funky with relative v. absolute paths?

12:30 Or file case sensitive FS on dev but not prod, or the opposite

12:30 xpe: what is the recommended way to rename something from clojure core in your namespace?

12:30 I see `(:refer-clojure :exclude [ancestors printf])` that's not quite it

12:30 n_b: Those are the first two things I check jjttjj

12:30 xpe: I also see `refer` + :rename

12:30 jjttjj: n_b: thanks!

12:31 n_b: xpe: http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/refer

12:33 xpe: n_b: thanks. I think I like (ns my.core (:refer-clojure :rename {inc core-inc}))

12:36 n_b: if you only need to change stuff in core, it's the way to go

12:37 Though I think it runs the risk of others having to check the docs to figure it out, I'm always of two minds about using shortcuts like that

12:38 jjttjj: sorry for the stream of noob questions, but what IS the ideal way to refer to files in a project-relative way?

12:39 I was just using relative path to the project which works locally

12:39 n_b: jjttjj: I honestly don't know, I was hoping someone would chime in, since I have a similar problem!

12:42 tmciver: n_b, jjttjj: I believe you use resource: http://richhickey.github.io/clojure/clojure.java.io-api.html#clojure.java.io/resource

12:43 I believe it searches for the given resource on the classpath and you can give it a path relative to one of the paths on the classpath.

12:49 noncom: anyone is familiar with Quil?

12:53 llasram: noncom: A tiny bit

12:55 noncom: llasram: the trouble is when i call like quil/rect from another thread, it gives an NPE coz, i guess, *applet* is null

12:56 i think it's more about dynamic vars but still..

12:57 calling it from the same thread/namespace is fine

12:58 llasram: Yep. The API isn't designed to support calling sideffecting functions from multiple threads

12:58 You might be able to cheat by passing the *applet* around and `binding` it in your other thread, but I don't know if the underlying Processing calls are thread-safe

12:59 Why do you want to draw from multiple threads though?

13:00 noncom: llasram: I am using processing to display some info on my application, but it is not the main screen, the main screen is a different opengl engine. I use processing because of it's simplicity here. all is fine except for this issue.

13:01 llasram: Could you just deliver what needs to be drawn to the Processing thread, and let that thread handle it?

13:03 noncom: llasram: if i know how to do it. actually the drawing functions themselves must be made in another thread. i mean, i do not know what drawing functions will be ahead of tie

13:03 *time

13:04 llasram: if you tell me the clojure way to handle this, i'll use it

13:05 the basic problem that i envision is that idk how will it resolve like "rect" function to belong to quil if it is created in another ns and passed to that obe

13:05 *one

13:05 llasram: Maybe an agent? Your processing rendering function get the agent state to know what to draw. Heck, that "state" could even just be functions to call. You can then update that state from any other threads

13:09 noncom: llasram: right, but how to make it understand that the "rect" function present in the agent state refers to the quil function, that very quil which is required in the namespace?

13:09 llasram: Uh. Well, the `rect` function you call needs to be the quil rect function. Require the namespace, call the function

13:13 noncom: llasram: so, I req the ns both in the processing thread and in the other thread. I create the call '(quil/rect) in the other thread, and when unqoted and executed in the processing thread, it will automatically resolve all as needed?

13:13 or maybe better store it like #(quil/rect)?

13:14 llasram: You seem to have some confusion regarding threads and namespaces

13:14 Namespaces aren't tied to a thread

13:15 Whatever functions you have now which perform quil rendering, you just need to ensure that those functions are called by the thread quil/processing sets up as the rendering thread

13:15 (Or restructure if rendering is mixed in with other logic, obvs)

13:23 noncom: llasram: ok i'll try

13:31 llasram: what is the syntax to pass several expression for evaluation in a different thread?

13:31 or, what is the same in this case - in a different ns

13:32 bbloom: (doc future)

13:32 clojurebot: "([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block, unless the variant of deref with timeout is used. See also - realized?."

13:33 noncom: bbloom: oh, not any thread, but a particular one. acually, i have to somehow pass expressions to another namespace so it executes them with it's own var bindings

13:34 bbloom: noncom: eval in a namespace and in a thread are two different things

13:34 xpe: using `recur` inside `lazy-seq` doesn't work. looks like I have to use the named function instead

13:34 bbloom: xpe: yes, becuase lazy-seq creates a (fn [] …thunk….)

13:34 xpe: recur is turned into a loop, but you want laziness, not a loop

13:35 xpe: you won't overflow the stack that way, since the thunk is evaluated later, after the original function has been popped off the stack

13:35 xpe: bbloom: thanks… a little unexpected at first, but I think I'll get it soon

13:36 noncom: ehh...

13:39 bbloom: xpe: try a macroexpand, it will make it obvious :-)

13:39 ,(macroexpand '(lazy-seq [1 2 3]))

13:39 clojurebot: (new clojure.lang.LazySeq (fn* [] [1 2 3]))

13:40 xpe: bbloom: we might have differing ideas of obviousness

13:40 haha

13:40 but thanks, I've making good headway

13:40 bbloom: (doc recur)

13:40 clojurebot: It's greek to me.

13:40 bbloom: &(doc recur)

13:40 lazybot: ⇒ "Special: recur; Evaluates the exprs in order, then, in parallel, rebinds\n the bindings of the recursion point to the values of the exprs.\n Execution then jumps back to the recursion point, a loop or fn method."

13:41 xpe: good headway, without holding my head, too

13:41 bbloom: just gotta be unafraid to explore in your repl & these things will become clear

13:42 ,(macroexpand '(lazy-seq (recur 1 2 3)))

13:42 clojurebot: (new clojure.lang.LazySeq (fn* [] (recur 1 2 3)))

13:42 bbloom: ,(fn* [] (recur 1 2 3))

13:42 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 0 args, got: 3, compiling:(NO_SOURCE_PATH:0:0)>

13:42 bbloom: ,(fn* [] (recur))

13:42 clojurebot: #<sandbox$eval85$fn__86 sandbox$eval85$fn__86@1ca1bde>

13:42 bbloom: ,((fn* [] (recur)))

13:42 ^^ timeout

13:42 clojurebot: Execution Timed Out

13:44 xpe: bbloom: thanks for the suggestions. I got it worked out now

13:45 it was a set combinatorics function slightly different than math.combinatorics. a fun problem

13:55 lynaghk`: Is there any strong reason to use Nginx in front of Jetty for a Compojure app? I've already got Jetty configured to gzip responses.

14:04 bbloom: lynaghk`: nginx won't modify the http requests you proxy through without extra instruction

14:04 lynaghk`: so it's only useful if your config does something interesting

14:05 llasram: Static resource files -- nginx or apache can serve static files from disk much more efficiently

14:05 bbloom: lynaghk`: also useful if you want to virtualize your 80 and 433 ports by post for backends that are not all jetty

14:06 s/post/host

14:06 or hostname rather

14:12 lynaghk`: llasram: I've heard that but never actually seen numbers anywhere

14:12 bbloom: not sure what you mean---load balancing?

14:13 bbloom: lynaghk`: i'm saying that if your server is running multiple services on a virtual host, ie foo.com and bar.com both on port 80, then you should have nginx do that

14:16 lynaghk`: bbloom: oh, yeah. totes. Nah, this is for a site that I expect to just get a few hundred or thousand hits a day that I can just throw on a vps all by itself

14:16 bbloom: yeah, jetty can do the job just fine

14:16 lynaghk`: so I don't need anything like that; I'll give plain Jetty a shot

14:16 bbloom: do you have any experience setting up SSL certs with Jetty?

14:16 bbloom: lynaghk`: no, and that brings up the MOST IMPORTANT REASON to use nginx instead of jetty wherever possible: no xml :-)

14:17 lynaghk`: bbloom: ha

14:18 hiredman: if you terminate ssl before jetty it is harder to do things like authenticate via client side certs

14:19 llasram: lynaghk`: that's a good point, but it at least in theory could be significant. Linux (and I think *BSD?) have a `sendfile` system call which allows the kernel to directly copy data from one file descriptor to another, entirely bypassing user space and skipping at least one extraneous copy

14:20 bbloom: lynaghk`: the absolute easiest way to configure ssl is with stunnel

14:20 lynaghk`: the config file is like 4 lines

14:21 it's like path-to-cert, path-to-key, in-port, out-port. DONE!

14:26 lynaghk`: bbloom: I'll take a look at that if Jetty gives me trouble, thank

14:26 *thanks.

14:47 derek_c: I'm trying to translate a piece of Java code to Clojure. here is a part of it:

14:47 FileSystems.getDefault().newWatchService()

14:47 should this be: (.newWatchService (.getDefault FileSystems))

14:47 ?

14:47 bbloom: (doc ..)

14:47 clojurebot: "([x form] [x form & more]); form => fieldName-symbol or (instanceMethodName-symbol args*) Expands into a member access (.) of the first member on the first argument, followed by the next member on the result, etc. For instance: (.. System (getProperties) (get \"os.name\")) expands to: (. (. System (getProperties)) (get \"os.name\")) but is easier to write, read, and understand."

14:48 bbloom: but i think you need: (.newWatchService (FileSystems/getDefault))

14:52 derek_c: bbloom: ah I didn't know that

14:53 how is (.. FileSystems (getDefault) (newWatchService)) different from that you suggest?

14:53 bbloom: (doc .)

14:53 clojurebot: Excuse me?

14:53 bbloom: &(doc .)

14:53 lazybot: ⇒ "Special: .; The instance member form works for both fields and methods.\n They all expand into calls to the dot operator at macroexpansion time."

14:53 bbloom: notice it says "fields and methods"

14:53 it probably should say INSTANCE fields & methods

14:54 you use / for static stuff

14:54 with static stuff, think of the class name as being a mini-namespace

14:56 noncom: ok, I can't make it. what is the way to request a *variable* binding from some thread to be valid in another thread?

14:56 bbloom: by *variable* do you mean a dynamic var?

14:56 noncom: yeah

14:57 bbloom: see the docs for binding, bound-fn, with-bindings, etc

14:57 but what are you trying to accomplish anyway?

14:58 noonian: are you trying to share data between threads?

14:58 derek_c: hmm the compiler is giving me this strange error:

14:59 IllegalArgumentException No matching method found: get for class java.lang.Class clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53)

14:59 it doesn't even give me a line number

14:59 does anyone know what could be going on?

14:59 bbloom: derek_c: try to invoke smaller and smaller bits of code in the repl until you narrow it down

15:04 noncom: the quil library is structured in a way that every drawing function refres to the local binding of the graphics context. somehow i need to be able to execute drawing instructions, created elswhere, from another thread. what is the syntax to pass them to the quil thread so they execute at their time and with the correct context binding... sorry this may sound obscure..

15:05 i guess i can use an atom or an agent to pass the instructions between threads, ok

15:10 avishai: hi

15:10 how do i force realization of a lazy-seq?

15:10 Bronsa: call seq on it

15:10 avishai: specifically (map str (partition 6 "TESldjdflsdjflkjdsflkjalkfdjfkljadsfkljadklfj"))

15:10 will return a list of lazy seqs

15:10 Bronsa: or doall

15:11 avishai: doall doesn't work

15:11 tried it

15:11 noonian: try (into [] (map str (partition ...)))

15:11 avishai: ugly

15:11 doesn't work either

15:12 Bronsa: ,(map pr-str (partition 6 "TESldjdflsdjflkjdsflkjalkfdjfkljadsfkljadklfj"))

15:12 clojurebot: ("(\\T \\E \\S \\l \\d ...)" "(\\d \\f \\l \\s \\d ...)" "(\\f \\l \\k \\j \\d ...)" "(\\f \\l \\k \\j \\a ...)" "(\\k \\f \\d \\j \\f ...)" ...)

15:12 Bronsa: it's not lazyness your problem

15:13 avishai: whats pr-str?

15:13 Bronsa: ,(doc pr-str)

15:13 clojurebot: "([& xs]); pr to a string, returning it"

15:13 Bronsa: ,(doc pr)

15:13 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"

15:14 avishai: (map str (partition 6 "TESldjdflsdjflkjdsflkjalkfdjfkljadsfkljadklfj"))

15:14 ("clojure.lang.LazySeq@c83101f1" "clojure.lang.LazySeq@e55b0b10" "clojure.lang.LazySeq@e918b335" "clojure.lang.LazySeq@e918b2d1" "clojure.lang.LazySeq@f14932e7" "clojure.lang.LazySeq@f334f775" "clojure.lang.LazySeq@f1a05820")

15:14 noonian: (partition 6 "TESldjdflsdjflkjdsflkjalkfdjfkljadsfkljadklfj")

15:14 ,(partition 6 "TESldjdflsdjflkjdsflkjalkfdjfkljadsfkljadklfj")

15:14 clojurebot: ((\T \E \S \l \d ...) (\d \f \l \s \d ...) (\f \l \k \j \d ...) (\f \l \k \j \a ...) (\k \f \d \j \f ...) ...)

15:15 avishai: i thought this was due to repl expanding lazy-seqs

15:16 so, how do i convert character list to string? map str?

15:17 Bronsa: oh, that's what you want

15:17 avishai: hmm reduce str

15:17 Bronsa: ,(map (partial apply str) (partition 6 "TESldjdflsdjflkjdsflkjalkfdjfkljadsfkljadklfj"))

15:17 clojurebot: ("TESldj" "dflsdj" "flkjds" "flkjal" "kfdjfk" ...)

15:17 noonian: yup

15:17 avishai: (map (comp reduce str) (partition 6 ...

15:17 a bit ugly

15:17 but works

15:21 is there a function to get the arity of a function?

15:23 (comp reduce str) doesn't work

15:23 i get ArityException Wrong number of args (1) passed to: core$reduce'

15:23 noonian: ,(map #(apply str %) (partition 6 "TESldjdflsdjflkjdsflkjalkfdjfkljadsfkljadklfj"))

15:23 clojurebot: ("TESldj" "dflsdj" "flkjds" "flkjal" "kfdjfk" ...)

15:23 dnolen_: avishai: you want (apply str ...) anyway

15:26 avishai: isn't apply unefficient with big lists?

15:26 my actual use case is partition 60

15:26 dnolen_: avishai: it is efficient

15:27 avishai: i read in the clojure book that apply performance starts to degrade after list size of about 4

15:27 dnolen_: especially apply str as it will use a StringBuilder internally

15:27 avishai: huh

15:27 nice to know

15:28 noonian: functions that take arbitrary numbers of args see those args as a seq, which I sure hope are efficient in clojure :p

15:28 dnolen_: avishai: in general reduce is the way to go, but apply str is optimized

15:28 avishai: what i don't get

15:28 is why #(apply str %) works

15:29 and (comp apply str) doesn't

15:30 noonian: you want partial, not comp, (comp f g) is like (fn [x] (f (g x))) I believe (I've never used comp so I could be wrong)

15:30 gfredericks: avishai: (comp apply str) is roughly equivalent to #(apply (str %))

15:31 xilo: i'm using vim-fireplace and wondering what's the best way to get lein repl headless to start so i don't have to do it manually

15:31 noonian: so (partial apply str) returns something like (fn [args] (apply str args))

15:31 avishai: ah

15:31 got partial and comp mixed up

15:31 sorry

15:32 10x a billion

15:36 creese: Has anyone tried python/fn?

16:21 weavejester: I'm considering writing a library for generating unique fingerprints for Clojure data structures. Any ideas for names? The best I can think up is "fingerprint" or "data-fingerprint" :)

16:21 fbernier: how would you explain in a couple of sentences how immutable and persistent data structures help with concurrency?

16:23 weavejester: Concurrency issues occur when data changes.

16:23 noonian: if a data structure is immutable, you can freely pass it between threads without worrying about it ever changing

16:23 no need for locks, etc.

16:24 fbernier: makes sense, thanks

16:30 amalloy: weavejester: more unique than hashes? like actually-unique?

16:31 technomancy: weavejester: I'd suggest loop, whorl, or arch, but two of those are taken

16:32 amalloy: weavejester: gfredericks has some code that you could probably get some interesting ideas from, even if there's nothing you can steal outright: https://github.com/fredericksgary/bijector

16:32 weavejester: amalloy: Essentially it would walk a tree and replace maps and sets with sorted versions in order to get a canonical ordering, and then it would serialize and hash the result.

16:33 fbernier: so... clojure sequences ... is it a data structure ?

16:34 weavejester: technomancy: Whorl might be a good name. There's a js project on github, but it has only 3 watchers and hasn't been touched in 3 years.

16:35 fbernier: More like an abstraction I guess.

16:39 fbernier: weavejester: I'm having difficulties finding the easiest words to describe what it is.

16:39 both for myself and for the crowd to whom I'll try to explain it.

16:41 weavejester: fbernier: Not sure. Perhaps say it's an interface that allows a data structure to be iterated over sequentially, though that's not the complete truth.

16:42 fbernier: yeah I think that's what I'll go with

16:43 SegFaultAX: Sequences provide the base iterator protocol for Clojure.

16:43 Similar to #each in Ruby, or __iter__/__next__ in Python.

16:44 weavejester: But better :)

16:44 noonian: a particular sequence is a data structure, but many different types of data structures are sequences

16:44 SegFaultAX: As long as some data type implements that protocol correctly, it benefits from the vast number of functions that also speak the protocol.

16:44 clojurebot: your random number generator is brokem

16:44 weavejester: I think there are some slides about the deficencies of the classic iterator model

16:44 SegFaultAX: Like Enumerable in Ruby.

16:45 fbernier: great I get it better now

16:45 thanks

16:45 SegFaultAX: In Ruby, if I simply implement #each, I can mixin a huge amount of functionality for free.

16:45 And the only thing I've described is how to emit values from my data type.

16:45 It implies nothing about the structure of that data, ordering, etc.

16:46 Clojure sequences have the same benefit (as does Python's __iter__/__next__) but, as weavejester said, it's even better.

16:46 fbernier: Improving my knowledge of ruby while learning Clojure, nice.

16:47 SegFaultAX: :)

16:47 Just doing my part.

16:48 weavejester: I guess the main benefit of seqs over iterators is that they're effectively stateless.

16:49 SegFaultAX: weavejester: Well I'm talking about the /process/ of iteration. Not iterators as such.

16:49 fbernier: SegFaultAX: "Writing a talk about Clojure for Ruby developers is slightly less than than I had originally anticipated. #clojure"

16:49 got slides? :)

16:50 SegFaultAX: fbernier: Still working on them!

16:50 fbernier: ok

16:50 will be doing a similar talk to a half-ruby crowd too tuesday

16:51 SegFaultAX: fbernier: Then I would at least start by drawing the similarities between seqs and Ruby's internal iteration protocol via #each

16:51 And the tremendous benefits therein.

16:51 fbernier: Unsure I want to go in such details

16:51 other than the couple sentences definition you gave

16:52 SegFaultAX: fbernier: You can do it in 5 sentences, as I did above.

16:52 fbernier: ah ok

16:52 SegFaultAX: fbernier: Feel free to copy paste. Just throw an @SegFaultAX in the credits. :)

16:52 fbernier: haha great ;)

16:54 SegFaultAX: fbernier: Not sure the context of your talk, but I expect the people I'm presenting to to have a relatively high degree of understanding of Ruby. So I can lean pretty hard on that assumption when explaining things like this.

16:54 fbernier: Tailor your presentation to suit your expected audience.

16:54 fbernier: It'll be a mixed crowd ... so I won't be assuming so much

16:55 some .net, php devs

16:55 but mostly rubyists or ruby enthusiasts

17:01 I thought after solving 76 problems on 4clojure I would have the required knowledge to give a presentation to newbies

17:01 But I realize I can't explain lots of stuff without reading on it :P

17:03 bbloom: 4clojure is great for learning clojure in the small, but the only way to learn clojure in the large is to work with it for a while

17:03 fbernier: Yeah probably.

17:03 bbloom: did you watch the videos we recommended?

17:04 fbernier: I wouldn't be here trying to learn more about it if it wasn't for 4clojure though :)

17:04 bbloom: not yet :( ... will do

17:05 kmicu: unicorns are real, but php devs exist!? http://i.imgur.com/NQHKSVE.gif

17:07 fbernier: we need them to make all those wordpress sites while we work on cooler stuff

17:08 this gif is so overused but it represents exactly what learning clojure feels like: http://i.imgur.com/UmpOi.gif

17:09 SegFaultAX: fbernier: Relevant xkcd http://xkcd.com/224/

17:10 rurumate: Where's the 'clojure compiler in clojure' project?

17:11 kmicu: $google clojure in clojure

17:11 lazybot: [Clojure - todo] http://clojure.org/todo

17:11 kmicu: I have another google https://github.com/cosmin/clojure-in-clojure

17:12 rurumate: looks not overly active

17:13 Needs proper bytecode generation library first, I think

17:14 kmicu: https://groups.google.com/forum/#!topic/clojure-dev/puJ1PBEEsow

17:14 Bronsa: kmicu: I'm working on completing Aaron's CinC as my GSoC project

17:15 kmicu: And GSoC...

17:15 Bronsa: https://www.google-melange.com/gsoc/homepage/google/gsoc2013

17:18 kmicu: tmux select-window -t :0

17:20 rurumate: what about rich hickey, he not interested in that

17:21 bbloom: rurumate: he is, but he's got a lot of stuff to work on :-)

17:21 rurumate: bbloom: at least he could mentor it or something

17:22 bbloom: and to be fair, he basically already DID write clojure-in-clojure when he wrote clojurescript ;-)

17:22 SegFaultAX: bbloom: Does he still hack on cljs?

17:23 bbloom: SegFaultAX: git log says his last commit was in 2011

17:24 SegFaultAX: I wonder if he's like 100% focused on trying to make Datomic happen.

17:24 I really wish it was open source. :(

17:24 bbloom: SegFaultAX: well, he's been actively contributing to core.async

17:27 jtoy: what is the recommended time/date library to use with clojure, it seems like clj-time ?

17:28 bbloom: jtoy: the ONLY correct answer for java is joda time & clj-time is a Joda wrapper

17:29 i dunno if clj-time is good, but joda is great, so that's a good start

17:29 SegFaultAX: clj-time mostly does a pretty good job.

17:29 jtoy: bbloom: ok thanks, i've never really used java until clojure, and im not even sure if this counts as "using java"

17:29 SegFaultAX: Joda is excellent.

17:29 jtoy: It's all just Java :)

17:35 jtoy: does clojure have a debugger? it seems painful to debug when i want to just inspect a data structure

17:36 manutter51: jtoy: seen the clojure.inspector namespace?

17:37 jtoy: manutter51: i havent, thx

17:37 kmicu: REPL is not good enough?

17:38 manutter51: must be pretty good, I almost never hear anyone talk about using clojure.inspector.

17:38 noonian: i'd never heard of it either

17:39 jtoy: kmicu: how? sometimes the code is nested deep, i do use the repl for everything, but it is painful when dealing with many layers

17:39 instead it would be so much easier to be at the point right before the error happens

17:39 noonian: but seems useful for inspecting deeply nested structures

17:52 jtoy: do you guys see a better way to do this in clojure: https://www.refheap.com/16043 i want to have integers in the format of YYYYMMDD so I can compare them, sort them, etc

17:53 SegFaultAX: jtoy: Use a date/time format.

17:54 jtoy: If you're using clj-time's formatter.

17:54 jtoy: SegFaultAX: i was thining that earlier, im not using the formatter at all

17:55 SegFaultAX: jtoy: You should be.

17:55 jtoy: ok

18:06 how can I return a hash-map from a mapping call? Im trying to do (map #( {:date (first %) :count (-> % last count) }) (group-by identity favs)) ; but get ArityException Wrong number of args (0) passed to: PersistentArrayMap clojure.lang.AFn.throwArity (AFn.java:437)

18:06 bbloom: jtoy: #() implies a call, you're trying to call a map

18:06 ,'#({:foo :bar})

18:06 clojurebot: (fn* [] ({:foo :bar}))

18:06 bbloom: see?

18:07 you can use #(hash-map …) or use fn directly

18:07 there is also the -> trick

18:07 jtoy: bbloom: so #() must run a function?

18:07 bbloom: what would i do with the -> trick here?

18:08 bbloom: ,(map (fn [x] (vector x)) [5 10 15])

18:08 clojurebot: ([5] [10] [15])

18:08 bbloom: ,(map #(vector %) [5 10 15])

18:08 clojurebot: ([5] [10] [15])

18:08 bbloom: ,(map #([%]) [5 10 15]) ; ugh oh!

18:08 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentVector>

18:08 bbloom: ,(map #(-> [%]) [5 10 15]) ; ugh oh!

18:08 clojurebot: ([5] [10] [15])

18:08 bbloom: get it?

18:09 hyPiRion: oh just, (shocker) ##(map vector [5 10 15])

18:09 lazybot: ⇒ ([5] [10] [15])

18:09 bbloom: hyPiRion: heh, well yes. of course

18:09 jtoy: ,(map #(-> {%}) [5 10 15])

18:09 clojurebot: #<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>

18:09 jtoy: ,(map #(-> {:test %}) [5 10 15])

18:09 clojurebot: ({:test 5} {:test 10} {:test 15})

18:09 jtoy: ah, cool

18:09 bbloom: ,(map #(-> [1 (inc %) 2 (dec %) 3]) [5 10 15]) ; just for hyPirion

18:09 clojurebot: ([1 6 2 4 3] [1 11 2 9 3] [1 16 2 14 3])

18:10 xpe: what's a good way to fork a clojure library and use one's modifications? e.g. I want to apply this patch: http://dev.clojure.org/jira/browse/MCOMB-2

18:10 bbloom: jtoy: some people think that the #(-> thing is an ugly evil sin. I don't :-P

18:10 xpe: i don't really want to push to clojars

18:10 jtoy: xpe, you can require any library on clojars including your own even if it is a fork

18:10 bbloom: why? I loveusing -> for everything

18:10 hyPiRion: bbloom: ##(map (juxt (constantly 1) inc (constantly 2) dec (constantly 3)) [5 10 15])

18:10 lazybot: ⇒ ([1 6 2 4 3] [1 11 2 9 3] [1 16 2 14 3])

18:10 hyPiRion: ~juxt

18:11 clojurebot: juxt is a little hard to grok but it's the best thing ever

18:11 xpe: jtoy: is there an easy way just to pull from a local git repository without pushing to clojars?

18:11 bbloom: hyPiRion: i knew you'd try that, that's why i added those constants in there: to make your approach seem ridiculous :-)

18:11 hyPiRion: hrm

18:11 bbloom: jtoy: people think that (-> x) is stupid b/c it's equiv to just x

18:11 jtoy: xpe, im not sure, i havent tried it

18:12 bbloom: #(-> %) is basically just identity

18:12 jtoy: bbloom: oh, i see

18:12 bbloom: but #() CALLS SOMETHING

18:12 n_b: xpe: Check out "checkouts" in the lein docs

18:12 bbloom: so calling -> to get identity is an ugly hack to some people. they would rather you use (fn [x] {:foo x})

18:12 jtoy: #() vs (fn[x]) are things i dont really want to care about

18:13 hyPiRion: ,(map (comp (partial interleave [1 2 3]) (juxt inc dec)) [5 10 15])

18:13 bbloom: yeah, use whatever makes sense to you :-)

18:13 clojurebot: ((1 6 2 4) (1 11 2 9) (1 16 2 14))

18:13 jtoy: i like the -> % trick bc its shorter

18:13 hyPiRion: oh dangit.

18:13 I give up this time.

18:13 bbloom: heh :-)

18:13 n_b: xpe: Note it's a Bad Thing™ to do production stuff like that, you should push it to a local maven repo or something if at all possible

18:13 xpe: n_b: trademark noted thanks :)

18:25 jtoy: if i have to vectors of hashmaps such as [{:a 1 :b 2 } {:a 3 :b 2 ] and [{:a 1 :c3}{:a 2 :c 2 }] how can I merge them so I get [{:a 1 :b 2 :c 2} {:a 2 :b 0 :c 2} {:a 3 :b 2 :c 0} ] ?

18:26 bbloom: map accepts mutliple sequences to map in parallel

18:26 jtoy: i think i have to do a group by and then merge?

18:27 bbloom: ,(map - [5 10 15] [2 3 4])

18:27 clojurebot: (3 7 11)

18:27 jtoy: they are unordered, i dont think i can use map in this situation

18:28 bbloom: then your example is not clear

18:28 n_b: so you want to merge each map?

18:28 jtoy: how about now: [{:a 1 :b 2 } {:a 3 :b 2 }] and [{:a 2 :c 2 } {:a 1 :c3}] how can I merge them so I get [{:a 1 :b 2 :c 2} {:a 2 :b 0 :c 2} {:a 3 :b 2 :c 0} ]

18:28 n_b: can you not map merge-by across both seqs?

18:29 jtoy: I want to gropu-by a key (a) so i have a b c, then for each of the a's, I want to merge in the results from b and c

18:30 a is unique in each vector

18:42 i wrote some really ugly code to do it

18:43 (map #(-> {:a (first %) :b (reduce + (map (fn[x] (x :b 0)) (-> % last))) :c (reduce + (map (fn[x] (x :c 0)) (-> % last))) }) (group-by :a (concat cs bs)))

18:44 xpe: what's up with projects like https://github.com/clojure/math.combinatorics/ that don't have a project.clj ?

18:44 jtoy: that is uggggggllllyyyyy

18:44 xpe: is there a good reason to not have one or are they pre-lein?

18:45 amalloy: xpe: clojure.contrib projects are managed by clojure.core, and they seem uninterested in adopting lein

18:45 jtoy: just write a version of group-by that takes two functions, one for grouping and one for combining

18:45 xpe: amalloy: ok, so if I want to fork and test, run the repl, etc. what do I do?

18:46 pom.xml. smells bad.

18:46 amalloy: sob, really. but mvn package probably makes a jar

18:46 mvn test will run tests

18:46 jtoy: i have one of those around somewhere, but i dunno where

18:46 xpe: amalloy: thanks, I won't blame the messenger :)

18:47 jtoy: amalloy: write my own group-by? does that mean i need to understand the original group-by so i can write a new version, or can i add my functionality to it?

18:47 amalloy: you should understand the original group-by whether you're rewriting it or not

18:47 it's a pretty basic, important technique

18:48 jtoy: cool

18:48 ivaraase1: amalloy: isn't there a snippet to convert a pom.xml into project.clj as well?

18:48 amalloy: *shrug*

18:53 xpe: ivaraase1: that would be nice. I just rearranged math.combinatorics to work with a project.clj I just made

19:03 hyPiRion: this is why we all should change to lein-pom

19:05 *lein-xml, rather

19:05 https://github.com/technomancy/lein-xml

19:08 ivaraase1: hyPiRion: sorry, not enterprise grade at all. too few tags.

19:36 Morgawr: best way to return a dictionary with only the specified keys?

19:36 ghadi: Morgawr: select-keys

19:37 Morgawr: thanks

19:43 bpr: cemerick: ping

20:33 xpe: does clojure or clojure test have a wrapper compare doubles within some precision? or I'll just do - and < 0.001

20:42 n_b: ,(doc with-precision)

20:42 clojurebot: "([precision & exprs]); Sets the precision and rounding mode to be used for BigDecimal operations. Usage: (with-precision 10 (/ 1M 3)) or: (with-precision 10 :rounding HALF_DOWN (/ 1M 3)) The rounding mode is one of CEILING, FLOOR, HALF_UP, HALF_DOWN, HALF_EVEN, UP, DOWN and UNNECESSARY; it defaults to HALF_UP."

20:43 xpe: n_b: that's useful but I'm going with: https://gist.github.com/xpe/5847084 for functions that return doubles

20:44 I seem to recall reading that with-precision is about presentation only -- I will need to verify that

20:46 tomjack: &(= 2M (with-precision 1 (+ 1.1M 1.1M)))

20:46 lazybot: java.lang.SecurityException: You tripped the alarm! pop-thread-bindings is bad!

20:47 tomjack: ,(with-precision 1 (+ 1.1 1.1))

20:47 clojurebot: 2.2

20:49 xpe: ,(with-precision 1 2.7182818284590455)

20:49 clojurebot: 2.7182818284590455

20:54 cbp`: how can i abort evaluation in lein repl

21:14 derek_c: I'm doing some Java interop and just got a problem. So I have this overloaded Java method that takes either a String or another type. I'm calling this Java method with a string, but for some reason the Clojure compiler insists on using the version of the method that takes another type. Does someone know what I should do?

21:17 bbloom: derek_c: use type hints and/or a casting function

21:17 if you want an int, for example (int x) there are functions for all the primitives & primitive arrays.

21:17 if you have a class instance, use (cast TheClass x)

21:18 derek_c: so I want to use the String version, should I do this?

21:18 (Paths/get (cast String path))

21:19 doesn't seem to work; it's still calling another version

21:19 amalloy: bbloom: (cast foo bar) doesn't do anything

21:19 bbloom: amalloy: oh… derek_c ignore me

21:19 amalloy: for reflective lookup, that is

21:19 bbloom: then he has to use a type hint?

21:19 amalloy: yes

21:19 bbloom: i was under the impression that the compiler hinted cast calls. i guess i just imagined that

21:20 i guess int, long, double, etc must be hinted b/c the types are known statically

21:20 derek_c: wait what do I do?

21:20 amalloy: (Paths/get ^String path)

21:22 bbloom: oh, that won't work

21:22 derek_c: the issue you have is that you're trying to call a variadic function

21:22 derek_c: hmm yeah... still the same error

21:22 bbloom: the signature of get is (String first, String… more)

21:22 which is just suggar for (String first, String[] more)

21:22 there is no 1-arg version (String first)

21:22 Raynes: I suspected that.

21:23 bbloom: (java.nio.file.Paths/get path (make-array String 0))

21:23 s/suggar/sugar

21:24 derek_c: bbloom: aha now that works

21:24 thanks man

21:24 bbloom: np

21:25 derek_c: it's weird cuz the Java code I'm looking at is simply calling the function with one string

21:25 bbloom: yes, the java compiler handles that automatically

21:25 derek_c: bbloom: oh I see

21:25 bpr: syntax sugar causes cancer of the semicolon... or something like that

21:33 hyPiRion: yeah, clojure can't do reflection that "well" on varargs

21:33 bbloom: arguably, perf is a major motivator for java interop, so making arbitrary array allocations obvious isn't a bad thing

21:41 dnolen_: core.match now also ridiculously fast when targeting CLJS - https://gist.github.com/swannodette/5847224

21:42 matching red black trees as arrays now close to 2X of the JVM when running under JavaScriptCore

21:45 derek_c: when we say let introduces an immutable binding, we don't mean that the thing that let binds to won't change, right?

21:45 so if I bind x to a Java class

21:45 I mean, an instance of a Java class

21:46 potentially x's inner state can still change, right?

21:48 dnolen_: derek_c: correct

21:49 derek_c: thanks. just verified

22:37 jouiswalker: is there a nice function that counts the number of keys in a map up to a certain depth?

22:38 or better, keys within a certain depth range?

22:38 ex {:a {:b c} {:d e} {:f {:g 'h}}}

22:39 (count m (range 1 2)) would be 4

22:42 Raynes: amalloy wrote something similar at some point but consistently denies it.

22:42 I was in fact in the same room with him at the time, but he cannot remember it.

22:42 jouiswalker: lol

22:44 amalloy: jouiswalker: i don't think that would be a very good function to build all as one piece. why not build a few smaller pieces, and then glue them together?

22:45 eg, start with a function that, for a given map, produces all legal key-seqs present in that map. so you'd get '((a) (a b) (a d) (a f) (a f g))

22:45 then from that you can filter out the ones you want, and count them

22:46 jouiswalker: the filtering is what makes it weird though :/

22:46 ideally i would just be able to filter things outside of a certain depth

22:46 and get something like a slice of the map

22:47 ({a 'b} {c {e 'f}} ) or something

Logging service provided by n01se.net