#clojure log - Jan 29 2014

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

0:46 fowlslegs: ,(= (reverse [:foo : bar :foo]) (seq [:foo : bar :foo]))

0:46 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: :>

0:47 fowlslegs: I thought the type metadata didn't matter when using =, just that the values were the same.

0:54 andyf: fowlslegs: Metadata is ignored by =

0:54 fowlslegs: andyf: I thought so, but why the errors

0:55 andyf: space between : and bar

0:55 fowlslegs: ,(seq [:foo :bar :foo])

0:55 clojurebot: (:foo :bar :foo)

0:55 fowlslegs: ,(reverse [:foo :bar :foo])

0:55 clojurebot: (:foo :bar :foo)

0:55 fowlslegs: haha

1:04 voldyman: i can't seem to connect to sqlite db here is the code that i used http://pastie.org/8677589

1:16 tpope: devn: actually I gave up and switched to sexp.vim. much better

1:23 seancorfield: voldyman: what's in your project.clj as a dependency for SQLite and what platform are you on?

1:24 voldyman: seancorfield: on ubuntu 13.10 dependency -> org.clojure/java.jdbc org.xerial/sqlite-jdbc

1:25 seancorfield: what version?

1:25 you shouldn't need the :classname btw, java.jdbc can figure the right thing out from the :subprotocol

1:25 voldyman: clojure "1.5.1" jdbc "0.3.2" sqlite-jdbc "3.7.2"

1:26 seancorfield: hmm, that's the version of SQLite that java.jdbc is tested against so that should be ok

1:27 voldyman: seancorfield: know of some project where i could find some sample code?

1:28 seancorfield: sample code for what, exactly?

1:28 voldyman: using sqlite db

1:28 seancorfield: regular java.jdbc documentation should apply

1:28 on clojure-doc.org

1:29 http://clojure-doc.org/articles/ecosystem/java_jdbc/home.html

1:29 and the tests in java.jdbc exercise SQLite and other DBs

1:30 one thing you might try as a sanity check is to clone the java.jdbc repo and run: lein test

1:30 that will show whether the basics are working on your system

1:30 voldyman: ah, great idea

1:30 seancorfield: if that doesn't work, it might be something environmental...

1:33 it should say Ran 70 tests containing 445 assertions...

1:34 (that's what it just produced on Windows 8.1 with Java 7 for me)

1:34 voldyman: seancorfield: same and 0 failures and 0 errors

1:35 but i don't even have postgres installed (which it checks)

1:35 seancorfield: not by default it doesn't :)

1:35 by default it tests apache derby, hsqldb, and sqlite

1:35 clojurebot: I don't understand.

1:36 seancorfield: so that proves that sqlite "works' so something about the way you're invoking it in the repl is the issue

1:36 cat paste up your project.clj somewhere?

1:38 voldyman: seancorfield: http://pastie.org/8677653

1:39 seancorfield: thx

1:40 i'll try that in a project locally with your repl session and see what happens

1:43 heh, well, the good news for you is i can repro your exact issue...

1:43 ...so i guess my question is: gave you actually created that test table?

1:47 ok, the problem is that you should say: (query db ["select * from test"])

1:48 i'm surprised the driver dumps

1:49 i'll open a ticket to add better validation for the query function to check it is passed a vector of sql statement followed by optional parameters... or it packages a string up as a vector for processing

1:51 voldyman: seancorfield: thanks a lot. i tried rewriting some code in repl it it worked!!

1:55 seancorfield: for reference here's the issue i created http://dev.clojure.org/jira/browse/JDBC-89

1:57 sm0ke: how does one contributes to clojure, do they accept pull reqests on github?

1:58 seancorfield: read http://clojure.org/contributing

1:58 no pull requests, just patches attached to JIRA tickets, from folks with signed Contributor's Agreements on record with Clojure/core

2:00 sm0ke: whoa! so much work

2:00 deadghost: is it?

2:01 from what I read, it sounds like all you need to do is sign over your soul to rich hickey

2:01 sm0ke: who sends a postal mail!

2:01 deadghost: you don't even need a goat sacrifice like other languages

2:01 sm0ke: crap and all i wanted to do was add serialization ids

2:01 seancorfield: as you can see from that page, hundreds of people have happily signed and mailed the CA...

2:02 you can always open a ticket on JIRA with a description of what you had in mind and let the project maintainer decide if / how to implement it :)

2:03 sm0ke: well there is already a bug which i want someone to take up http://dev.clojure.org/jira/browse/CLJ-1327

2:03 seancorfield: the legal protection of a signed CA is necessary for Clojure to be usable by companies

2:03 sm0ke: but the project maintainers have made it minor

2:09 seancorfield: sm0ke: you could always add comments to that issue explaining why you think it's more important than minor - that would likely get an explanation from Clojure/core about it

2:12 carlo_au: Is there any way to see debug info from Light Table? The InstaRepl doesn't work, the box thing in the bottom-left corner keeps spinning.

2:12 seancorfield: ok, outta here for the night

2:13 carlo_au: 'lein repl' works fine on the command line

2:13 seancorfield: voldyman: thank you for finding that issue - definitely not an intuitive problem!

2:14 TEttinger: carlo_au, I have the same problem.

2:15 actually I've had it for more than one version...

2:15 carlo_au: TEttinger: no luck on any other platform?

2:16 I'm trying it on a plain Ubuntu 13.10 VM as it doesn't compile on Debian Wheezy due to some libc version issue.

2:16 TEttinger: I'm on windows 7... hm.

2:16 carlo_au: hmm

2:16 TEttinger: I thought it might have been a threading thing, since when I tried it I was doing stuff with Swing

2:17 chippie: If I want to read an environment variable, such as $HOME or $PATH, is there a core function to do this easily? Searching with "env" with find-doc I didn't spot much, so have started down the path of (clojure.java.shell/sh "/usr/bin/env") passed through a series of conversions to get a map back. This feels bad and wrong.

2:17 carlo_au: I can't evaluate (+ 1 2) in the instarepl, so that's not a threading issue ;)

2:17 chippie: Have seen the environ library, but would prefer not to have to install a dependency just to read a simple environment variable.

2:18 TEttinger: well my problem was I could evaluate (+ 1 2) at an early point, but after evaling some long-running (?) code, it wouldn't do any more

2:20 chippie, you can call into java for this. https://github.com/niwibe/env-config/blob/master/src/env_config/environ.clj#L20

2:20 ,(System/getenv)

2:20 seangone: chippie: (System/getenv "HOME")

2:20 clojurebot: eval service is offline

2:21 TEttinger: uh... what did I miss?

2:21 chippie: TEttinger, seangone - Ah, thanks! I was so caught up in searching for Clojure-specific solution I never even thought to look for a Java solution.

2:21 seangone: g'nite!

2:33 elarson: I'm pretty sure I'm missing something here... but is this a typical pattern (def foo {}) (def foo (assoc foo "bar" "baz")) when you want to update some hashmap?

2:34 cark: that's wrong

2:34 why don't you do it right away ?

2:35 well i suppose you could do that when playing in the repl

2:36 but if you want to mutate foo in a program ... put the map in an atom

2:36 then (swap! foo assoc "blah" "bleh")

2:37 elarson: cark: well here is my use case. I'm writing a craps game to learn clojure (not that it matters that much) so each player has a bank. when that person wins a bet, they get their bank updated. the bank is just a hashmap with player -> total. so I want to update the total

2:38 cark: well

2:38 there are several ways to do that, without using any mutable state

2:38 elarson: I'm totally open to different ways of thinking about it, so just saying that is a bad idea is helpful ;)

2:38 cark: but it's quite usual to use an atom to hold the full state of the game

2:39 a single atom for the full state should suffice

2:40 (def game-state (atom {:hands {"player1" [hand here] "player2" []}}))

2:40 mkuitune: hmm, if one would like to store the entire state history I suppose you could store those map references to a list

2:40 then you could have a history browser functionality "for free"

2:41 cark: could do that, with shared structure, clojure will do that in the most efficent way possible

2:41 kinda

2:41 =)

2:41 mkuitune: If I've understood the current persistent map correctly once the map grows large enough most of the reference cells remain same between versions

2:41 ?

2:42 cark: yes

2:42 mkuitune: Is it still using bagwells hash array mapped tries or something else?

2:42 cark: not sure about the bagwells part, but for the rest that sounds correct

2:43 elarson: mkuitune, cark: that sounds like doing {"elarson": [14 10 26]} and using sum to get the total

2:43 * elarson assumes there is a sum function...

2:44 elarson: is that what you guys meant?

2:44 mkuitune: Is this still the container used for the map implementation? http://lampwww.epfl.ch/papers/idealhashtrees.pdf

2:45 cark: elarson: not at all ! but do not worry about this

2:46 mkuitune: looks like it at first glance

2:46 mkuitune: elarson: no i meant storing the heads of the maps like [map1 map2 map3] ... but your version is probably more legible :)

2:46 cark: elarson: just know that once you've created a var with def, it should remain as is

2:46 if you want to mutate it, make it hold an atom

2:47 and mutate the atom contents

2:47 elarson: cark: ok, so I gather the atom is meant to mutable

2:47 * elarson will read up a bit more on the atom

2:47 cark: elarson: yes

2:48 (let [a (atom 1)] (swap! a inc) @a)

2:48 ,(let [a (atom 1)] (swap! a inc) @a)

2:48 clojurebot: 2

2:48 elarson: ah and the @a dereferences the atom?

2:48 cark: right

2:49 elarson: ah ok

2:49 akurilin: bbloom: ping.

2:49 cark: ,@(atom 2)

2:49 clojurebot: 2

2:49 cark: ,(deref (atom 2))

2:49 clojurebot: 2

2:49 ssafejava: elarson: have you seen rhickey's talk on clojure datastructures & concurrency? it's absolutely worth the 45min, blew my mind

2:49 elarson: that must have been what rich hickey meant in this talk when he mentioned reference in haskell/clojure http://www.infoq.com/presentations/Simple-Made-Easy

2:50 ssafejava: I think I have a while back, but I'd love to watch it again. did you have a link offhand?

2:50 * elarson can google ;)

2:50 ssafejava: yeah one sec, I just sent it to a friend yest

2:51 elarson: http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey

2:51 elarson: (inc ssafejava)

2:51 lazybot: ⇒ 1

2:51 ssafejava: ahaha

2:51 elarson: ssafejava: thanks :)

2:52 ssafejava: new to the channel, btw - is there a guide to what any of the bots do?

2:52 cark: i think the source code is on github, no idea where

2:53 ssafejava: I guess, more specifically, what's the difference between clojurebot & lazybot?

2:53 cark: clojurebot is the father

2:53 https://github.com/hiredman/clojurebot

2:54 ssafejava: clojurebot: how much do you know?

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

2:59 ddellacosta: ,(+ 1 2)

2:59 clojurebot: 3

2:59 ddellacosta: &(map + [1 2 3])

2:59 lazybot: ⇒ (1 2 3)

3:00 ddellacosta: whoops

3:00 &(map inc [1 2 3])

3:00 lazybot: ⇒ (2 3 4)

3:00 ddellacosta: ssafejava: https://github.com/flatland/lazybot

3:13 elarson: atoms are super cool

3:13 the (swap! some-atom (fn [n])) pattern is so great

3:14 hhenkel: Hi all, trying to fetch some info from a server and recieving an error: https://www.refheap.com/29252

3:15 The errror occurs imho when the query-params are not used.

3:16 ssafejava: ddellacosta: thanks, nice link. clojurebot appears to have no docs besides its own source, but there's some fun stuff in there

3:18 quizdr: elarson and very useful, too. for instance, we are all, every one of us, made of atoms.

3:18 ssafejava: they are an elegant solution to existence

3:19 quizdr: ^ what he said

3:32 ddellacosta: If I spit a Clojure data structure out to a file, with no attempt at preprocessing whatsoever, is the resultant format EDN?

3:34 llasram: ddellacosta: As long as you don't have any e.g. random Java objects in the mix, then generally yes

3:37 ddellacosta: llasram: okay, thank you. I guess the proper way to do this, generally, would be to ensure that all Java objects were stripped out or otherwise converted to something that could be read by Clojure's reader, huh?

3:38 llasram: ddellacosta: You can define `print-method` and add tagged literal form readers for anything which isn't already readable

3:38 But yeah -- in general you just have to know what's in your data

3:38 s,for anything,for any specific things,

3:38 ddellacosta: llasram: gotcha, thanks. I'll have to read up on this, been lazy about the details.

4:32 d11wtq: WARNING: key already refers to: #'clojure.core/key in namespace: workkit.redis.jobs, being replaced by: #'workkit.redis.jobs/key

4:32 Is there a way to suppress that warning, besides changing the function name?

4:33 llasram: d11wtq: You can fix the underlying problem with a `:refer-clojure` form in your `ns` form

4:34 Or import the other namespace with an `:as` prefix alias instead of slurping it in

4:34 Usually you do the latter, and save the former for when writing namespaces which define functions w/ the same names as clojure.core functions

4:35 d11wtq: llasram: Yeah, so I've defined a ns that has a key function, which also exists in clojure.core. I'll look at refer-clojure, thanks!

4:35 llasram: Cool beans

4:36 d11wtq: Ah yes, (:refer-clojure :exclude [key])

4:37 hhenkel: Anyone around who can help me out with http-kit ?

4:37 d11wtq: hhenkel: Maybe. What's the question?

4:37 hhenkel: d11wtq: https://www.refheap.com/29252

4:37 Seems like I got a params problem when accessing the page.

4:38 d11wtq: hhenkel: If you perform the get without your callback, do you get the same error?

4:39 hhenkel: Just looks like an http-kit issue more than anything in your code.

4:39 hhenkel: d11wtq: I'll give it a try.

4:41 d11wtq: hhenkel: Also curious what JDK version you're using, and if this happens for all URLs.

4:42 hhenkel: d11wtq: Yes, still seeing the error when I use something like (def resp (client/get url options))

4:43 d11wtq: OpenJDK "1.7.0_45", the error is "normal" as long as the param "ignoreErrors=true"

4:44 is not used within the url

4:44 d11wtq: The error is kind of an feature of "jolokia" and you can get rid of it with this option

4:44 noncom: hi! what is way to close aleph's tcp client properly?

4:45 d11wtq: hhenkel: Ah I see. I'm not sure, sorry :-)

4:47 hhenkel: d11wtq: No prob, would you expect it to work in the way I use it? I tried to follow: http://http-kit.org/client.html

4:50 d11wtq: hhenkel: Ah, sorry now I'm looking at your :query-params, no, I wouldn't ;)

4:51 hhenkel: It's supposed to be a map of key-value pairs. So you'd want: {"ignoreErrors" true}

4:51 I'm not sure what the "none" is. How would that look in the URL?

4:54 hhenkel: d11wtq: I updated https://www.refheap.com/29252 with the opts.

4:54 d11wtq: hhenkel: If your query string is ?ignoreErrors=true&none, I think you need {"ignoreErrors" "true", "none" ""}

4:55 hhenkel: d11wtq: okay, I'll try

4:56 d11wtq: That looks much better! Thanks!

4:57 d11wtq: hhenkel: No dramas, apologies for the initial confusion :P

5:03 noncom: what is the easiest way to navigate the xml element emitted by clojure.data.xml/parse ?

5:03 it is in defrecords now, but on each level I have to descend into the :content node

5:13 luxbock: when I do C-x C-e to evaluate a form in a file, I get a complaint that the namespace hasn't been defined yet (since I haven't evaluated the ns-form)

5:14 how can evaluate the form in the user namespace?

5:14 or rather evaluate it in whatever ns the nrepl buffer is set to at the moment

5:18 tim_: anyone know if congomongo uses connection pooling?

5:20 not to worry, just found the info.

5:29 noncom: anyone familiar with aleph here?

5:29 ucb: noncom: somewhat; what's up?

5:29 noncom: ucb: do you know what'd the proper way to close a tcp client?

5:30 ucb: if it's like the server, then it's a future

5:30 sorry; never used the client itself.

5:30 noncom: idk.. and how would you deal with a future that way?

5:30 i just need to release the port

5:31 ucb: let me take a look one sec.

5:37 noncom: hrm; I can't figure it out. Normally with aleph servers you @(server) to stop serving requests. I can't find any similar mechanism for clients though.

5:39 noncom: ucb: well, ok, thanks anyway! :)

5:40 ucb: no worries :)

5:40 noncom: looks like it all goes back up to netty java classes..

5:40 ucb: let me know if you figure it out; I'm curious now.

5:40 yeah, that's as much as I could gather

5:46 d11wtq: What would be a tyical naming convention for something like to-string/from-string? Those names seem too much like method names bound to something with context.

5:46 read-string/write-string?

5:47 ucb: sounds reasonable

5:48 d11wtq: ucb: Except for the fact read-string is a core function that reads in lisp. I suppose that's fine though :)

5:48 llasram: d11wtq: Typically you'd just piggy-back on the reader

5:48 So you'd define `print-method` to get a `read`able printed representation of your object

5:49 d11wtq: llasram: Yeah, I'm parsing and dumping json payloads, but don't want to reveal that they are just json.

5:49 llasram: Huh

5:49 d11wtq: llasram: I mean, I don't want to reveal the implementation to the end user.

5:49 llasram: parse/unparase?

5:50 d11wtq: llasram: unparse sounds odd. Parse/dump? :)

5:50 Haha, naming things!

5:50 llasram: Next let's do cache coherency

5:50 d11wtq: Hehehe!

5:50 http://classnamer.com/

5:53 noncom: i heard arrows are recommended too, like ->string

5:54 d11wtq: noncom: Yeah, I've seen that for converting between data types. I think the semantics of that are more around casting though.

5:54 llasram: noncom: Yeah, but usually that would just be spelled `str` :-)

5:54 noncom: haha :)

5:54 llasram: This seems to be something a bit more specialized

5:55 d11wtq: parse-str/dump-str

5:55 I particularly like dump-str. Say it fast :_

5:55 :)

5:55 (dump-str :fire)

6:01 llasram: heh

6:11 hhenkel: d11wtq: still around?

6:12 I tried to modify some example code of http-kit but I'm currently failing to return an object from my code: https://www.refheap.com/29307

6:15 I'm also unsure what this exactely does: (let [{:keys [status headers body error] :as resp} @(client/get url options)

6:16 It fetches a object and derefences it...so far so good...

6:16 d11wtq: hhenkel: What output is your code producing? I've never checked the error field before, but your code looks ok.

6:16 hhenkel: d11wtq: The code is okay...

6:17 d11wtq: hhenkel: The {:keys [x y z]} thing is Clojure destructuring syntax. It's like pattern matching in other languages and lets you extract elements from complex data structures.

6:17 hhenkel: d11wtq: But if I try to work with the returned stuff I fail

6:17 d11wtq: http://clojure.org/special_forms#Special Forms--Binding Forms (Destructuring)

6:17 hhenkel: d11wtq: jolokia-client.core=> (get-data url options) resuluts in nil

6:18 d11wtq: hhenkel: Do you need an else clause in your callback?

6:18 (if error (...) resp)

6:19 hhenkel: Because otherwise your callback always returns nil.

6:19 hhenkel: If you don't need the callback, don't pass one. http-kit will return a map to you anyway.

6:19 hhenkel: d11wtq: I tried that...then I get a strange error.

6:20 hmm ,with call back your referring to the "if error" ?

6:21 d11wtq: hhenkel: Yes

6:21 hhenkel: Your callback is used as a filter on the response, before it is returned from client/get

6:21 And your callback returns nil.

6:22 hhenkel: d11wtq: I updated what I tried: https://www.refheap.com/29307

6:22 d11wtq: hhenkel: Not (resp), just resp

6:23 (resp) will try and call it as a function.

6:24 hhenkel: d11wtq: You're right....thanks again... :)

6:24 d11wtq: hhenkel: No worries. You should definitely learning how the destructuring syntax works too, as that is used all over in Clojure :)

6:24 s/learning/learn/

6:26 hhenkel: here's an article that seems to explain it quite well http://java.dzone.com/articles/clojure-destructuring

6:27 hhenkel: d11wtq: I will try...started with clojure in September, then was forced to pause for four months and now warming up again... ;)

6:34 d11wtq: hhenkel: Good luck :)

6:42 katox: is (into [] lazy-seq) much faster than (vec lazy-seq) ?

6:47 logic_prog: https://gist.github.com/anonymous/8686317 <-- is there some builtin function for changing "fucked up names" to readable names? i.e. util.chan$chan_open_QMARK_ ==> util.chan/chan-open?

6:48 llasram: logic_prog: I believe the mangling is not generally reversible

6:48 logic_prog: llasram: it's not a 1-1 mapping? :-)

6:48 llasram: ,(munge "cool-beans_fun_times")

6:48 clojurebot: "cool_beans_fun_times"

6:49 llasram: logic_prog: Correct

6:49 logic_prog: ,(munge "a-b a_b")

6:49 clojurebot: "a_b a_b"

6:49 logic_prog: hmm, does "a-b" and "a_b" get mapped to the same var ?

6:51 llasram: ~tias

6:51 clojurebot: Try it and see! You'll get results faster than asking someone in #clojure to evaluate it for you, and you'll get that warm, fuzzy feeling of self-reliance.

6:51 llasram: :-)

6:51 logic_prog: ,(munge "a?")

6:51 clojurebot: "a_QMARK_"

6:51 logic_prog: (,munge "a_QMARK_")

6:52 ,(let [a-b 20] (println a_b))

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

6:52 Ember-: http://i.imgur.com/WGDg5KB.jpg

6:52 logic_prog: so clearly either a-b is not mapping to a_b or a_b is not mapping to a_b

6:52 so it seems like munge is lying

6:52 llasram: logic_prog: Well, the mangling doesn't need to happen on locals

6:52 logic_prog: ,(let [] (def a-b 20) (println a_b))

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

6:53 logic_prog: ,(let [] (def a-b 20) (def a_b 30) (println a-b a_b))

6:53 clojurebot: 20 30\n

6:53 logic_prog: clearly a-b and a_b, being globals this time, are not clashing

6:53 llasram: Ah, but

6:54 Actually, the example I was going to give showed them also still not colliding :-)

6:54 Yeah, so the vars don't colide

6:54 collide

6:54 But the names of the generated classes holding the function implementations will

6:55 So you'll see freaky weirdness if you AOT compile

6:55 And have names which munge to the same thing

6:55 logic_prog: llasram: I don't understand why, but out of respect for you, I'll trust it.

6:55 llasram: This was actually a bug which got a bunch of discussion on the clojure-dev list recently

6:55 logic_prog: ah

6:55 tell those guys the easiest way to solve th eproblem is to make munge 1-1

6:56 so we can also unmunge

6:56 llasram: heh

6:57 I'll let you carry that charge :-)

6:57 Unfortunately it would be difficult to change the munging algorithm -- the ability to map namespaces to existing AOT'd class files depends on it

6:58 Would be a breaking change

6:58 pyrtsa: ,(defrecord Oops [uh-oh uh_oh])

6:58 clojurebot: #<CompilerException java.lang.ClassFormatError: Duplicate field name&signature in class file compile__stub/sandbox/Oops, compiling:(NO_SOURCE_PATH:0:0)>

6:58 llasram: pyrtsa: Good thinking!

6:58 pyrtsa: ,(defrecord Oops [uh-oh])

6:58 clojurebot: sandbox.Oops

6:59 pyrtsa: ,(.uh-oh (Oops. "!"))

6:59 clojurebot: "!"

6:59 pyrtsa: ,(.uh_oh (Oops. "!"))

6:59 clojurebot: "!"

6:59 pyrtsa: There. :)

7:00 logic_prog: Alright, time to compose email. to clojure mailing list. "llasram agrees me, but wants me to carry the charge ... " :-)

7:00 llasram: heh

7:03 silasdavis: I'm using timbre for logging in a web application. Most but not all activity is triggered by an incoming request, I was thinking about adding a request uuid to all my log messages when the code path up until the logging invocation started with a request

7:03 I don't want to have to explicitly add this or change my existing log messages

7:03 can anyone suggest the best way to do this

7:03 logic_prog: llasram: dumbass question -- why can't we just hex encode all clojure names

7:03 llasram: it's not every efficient, but it should solve this issue

7:04 silasdavis: some kind of thread-local variable?

7:05 set by ring middleware

7:05 llasram: logic_prog: It is nice if a human can figure out what a name is from the mangled version, but yeah -- something akin to URL-style hex encoding of otherwise illegal characters would totally work

7:07 silasdavis: A dynamic var would provide the scope you want (thread-local, bound within the dynamic scope of the request), but I don't know enough about timbre to propose an obvious way of getting it into the log messages

7:13 silasdavis: It has middleware sitting between log messages and appenders that will do it easily I think, I'll look at a dynamic var

7:36 sobel: can someone help me understand what they're asking on http://www.4clojure.com/problem/19#prob-title ?

7:37 i get 'last' but i don't get the point of doing that one without 'last'. what approach are they trying to get me to take?

7:37 llasram: sobel: Think about how `last` might be implemented, and so implement it :-)

7:45 sobel: llasram: thx, the hardest part was eventually finding 'count' (len? length? size? google?)

7:55 llasram: Interesting -- I hadn't thought of that approach. Now try doing it without `count` :-)

8:01 sobel: last is an nth

8:01 what are you thinking, (first (reverse x)) ?

8:02 lvh: Hello

8:02 llasram: Well, so some Clojure data structures know how long they are, but the general seq abstraction is more like a single-linked list -- you need to walk the whole thing to `count` it

8:02 sobel: maybe this tutorial isn't demanding enough of a clever cheat-monkey like myself. if i can turn the light green i move on.

8:02 llasram: There's (several) ways you can walk the structure yourself and just keep the last value

8:03 lvh: I am trying to figure out core.unify/logic; can someone epxlain why core.logic constraint functions ("relations") are special? like membero

8:03 sobel: yeah, i was actually wondering if count is legit on seqs, because what if it's a nonterminating seq

8:03 lvh: The docs suggest that they wouldn't be useless anywhere else.

8:03 I don't understand why; == seems to work fine

8:03 Morgawr: is there a let-keys macro or something like that to wrap around multiple (let [{:keys [whatev]} map]) calls?

8:03 I think it would be fairly useful

8:03 lvh: so I don't understand why membero can't just be contains?

8:04 sobel: using nth count did feel hacky. so reverse is generally preferred?

8:05 lvh: is it because membero understands how to deal with lvars?

8:06 llasram: sobel: well, think about what you'd need to do to reverse a link list (hint -- you'd be doing even more work, so no)

8:06 I mean, none of these are "preferred" -- obviously for real you can just call `last`

8:06 But for learning, these are useful things to think obout

8:06 about even

8:07 tbaldridge: lvh: yes, but it's also more than that. membero can say "is this value a member of this collection" or it can also say stuff like "give me all possible collections where this value is a member" or "what are all the members of this collection.

8:09 sobel: was first reverse the conceptual solution you were thinking of, after i used nth count?

8:09 or is there still another approach to understand

8:18 lvh: tbaldridge: Yes, I think my mind just exploded

8:19 voldyman: any idea how i can access the last row id after doing insert! in clojure.java.jdbc. insert! returns ({:last_insert_rowid() 3})

8:20 lvh: voldyman: At the risk of stating the obvious, (:last_insert_rowid() result)?

8:20 (Is that a syntax error or something?)

8:20 voldyman: lvh: :) i tried it. it return nil

8:20 no actually

8:20 it still returns the same object

8:21 lvh: voldyman: No idea, sorry :(

8:22 algernon: lvh: if you want to understand core.logic, I suggest reading The Reasoned Schemer. It is truly enlightening. (and makes it so much easier to understand core.logic, too)

8:22 Morgawr: opinion on this macro? https://gist.github.com/Morgawr/8687711

8:22 I don't know if it exists already or not but I always have to destructure my data with :keys and this seems really useful to me

8:23 (also the map-indexed thing looks horrible to me, maybe there's a better way to do it)

8:23 lvh: algernon: okie

8:28 mishok13: hi all, ran into a problem using Korma: https://gist.github.com/mishok13/8687718

8:29 basically, there's some funky quoting in the where macro happening, but I can't figure out a way to make it work

8:29 does anyone have any tips as to how passing your own quoted form to korma.core/where could be done?

8:30 llasram: sobel: Another approach :-)

8:34 sobel: llasram: i'm out

8:39 llasram: ,((partial reduce (fn [_ x] x) nil) [:foo :bar :baz])

8:39 clojurebot: :baz

8:39 llasram: Or anything similar using loop/recur etc

8:40 mdrogalis: mishok13: Maybe try looking into HoneySQL.

8:41 Runtime constructed queries aren't Korma's strength

8:41 sobel: ok, i don't know partial or reduce or _ yet but i was just reading reduce

8:41 (docs)

8:42 and recur occurred to me but i thought better of that approach

8:42 llasram: Oh, `_` is just a convention for "I need an identifier here, but I'm going to ignore it"

8:42 sobel: oh _ isn't special

8:42 llasram: nope

8:42 ,(let [_ :fun!] _)

8:42 clojurebot: :fun!

8:43 llasram: `reduce` is your friend though. `reduce` holds the key to all Clojure awesomeness

8:43 sobel: map and filter are familiar from python use

8:44 hyPiRion: `for` as well, actually

8:44 mdrogalis: llasram: I thought #= holds the key to awesomeness.

8:44 hyPiRion: [x * 2 for x in y] is the same as (for [x y] (* x 2))

8:44 mishok13: mdrogalis: yeah, I'm considering it, but then how would I execute the queries?

8:44 hyPiRion: "the same" meaning ignoring laziness etc.

8:44 mishok13: jdbc, I presume?

8:45 mdrogalis: mishok13: I believe so, yeah.

8:45 mishok13: that would suck, since it means doing unrelated refactoring in the middle of the project

8:45 mdrogalis: Pick your poison. Either that, or unrelated derpy-ness with Korma.

8:45 lvh: Hi

8:46 mdrogalis: lvh: Morning

8:46 lvh: first/rest makes sense on sets, right?

8:46 mishok13: lvh: not really :)

8:46 lvh: also is (loop [x x] ...) okay? Since Iw ant to start with the current value of x, but I'm rebinding in recur

8:47 so, my use case is that I have a set of people, I want to deal with them one at a time, and I need efficient disj.

8:47 hyPiRion: lvh: first/rest doesn't really "make sense", but first returns any value in the set, and rest returns the rest of the set as a seq

8:47 lvh: okay, so, it doesn't make sense in the sense that the set has no particular first element

8:48 but if I want *any* element, and all the other elements for recur, then first/rest is how I spell that

8:48 ?

8:48 hyPiRion: lvh: yeah, that's what I tried to convey :p

8:48 lvh: hyPiRion: Gotcha. Just checking if this is something I should be doing :)

8:49 (I understand that sets don't really have a meaningful numbered first element)

8:49 hyPiRion: lvh: yeah, if you want to do something for all the people, first/rest is okay. I'd try to use map/reduce first, but if you need some accumulator value, that's usually a tad hard.

8:50 lvh: Also, if I have that first element, want it out of the set, as well as a related element, should I spell that (disj (rest my-set) the-other-element), or (disj my-set the-first-element the-second-element)

8:50 hyPiRion: s/tad/bit/

8:50 lvh: hyPiRion: Yeah I am writing a lot of code that I am pretty sure could be written as a reduce

8:50 hyPiRion: lvh: the latter. The first one won't work

8:50 lvh: but I don't understand reducers enough yet to be able to turn my code from one to the other

8:50 hyPiRion: ,(rest #{1 2 3 4})

8:50 clojurebot: (2 3 4)

8:50 lvh: hyPiRion: the output of rest isn't a set?

8:50 egads.

8:50 Okay thanks :)

8:51 hyPiRion: ,(disj (rest #{1 2 3 4}) 3) ;; Poor lazybot :(

8:51 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentSet>

8:51 lvh: (def any-elem first)

8:51 hyPiRion: ,(disj #{2 3 4} 1 3)

8:51 clojurebot: #{2 4}

8:51 hyPiRion: lvh: comma first :)

8:51 lvh: hyPiRion: I didn't mean to get the bot to execute that

8:51 hyPiRion: ah

8:52 lvh: (Also I would guess that that isn't persistent so it wouldn't do much?)

8:53 hyPiRion: well, someone changed that. It's a 5 min cleanup for clojurebot I think

8:53 lvh: oh, cool.

8:53 hyPiRion: ,(def any-elem first)

8:53 clojurebot: #'sandbox/any-elem

8:53 hyPiRion: ,(any-elem #{1 2 3})

8:53 clojurebot: 1

8:53 lvh: so, whenever I do cider-jack-in, I get java.lang.IllegalAccessError: pp does not exist

8:54 I'm guessing that means there's some site file I accidentally typed some junk into

8:54 I can't figure out where.

8:54 mdrogalis: lvh: It can't find clojure.pprint apparently.

8:55 lvh: mdrogalis: Oh. Okay. How do I get that?

8:55 Do I have to add it to each project.clj?

8:56 mdrogalis: lvh: No, it's in core. Google the error, you'll find something.

8:57 lvh: Okay, thanks :)

8:57 hyPiRion: usually (:require [clojure.pprint :as pp]) should resolve that if you add that into the ns form.

8:57 mdrogalis: Anytime.

9:01 lvh: mdrogalis: I found something that suggests putting in (sit-for 1) into a repl init defun. That sounds a bit silly :)

9:01 hyPiRion: Which ns form?

9:02 noncom: hi, i am getting error "javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.MXParser Factory not found" upon trying to parse an XML string with clojure.data.xml library... any ideas on how to fix this?

9:02 mdrogalis: Weird. Can't say I actually know how to fix it.

9:02 hyPiRion: lvh: well, the (ns my-namespace.here) in top of your clojure files

9:03 lvh: hyPiRion: oh. even if that source file doesn't actually use pp?

9:03 hyPiRion: lvh: uh well, no. If that's the case, then something's weird is going on

9:06 mdrogalis: noncom: Do lein deps :tree and check the top for version collisions.

9:07 noncom: thanks, will check it out!

9:07 silasdavis: is there away to use git repositories as dependencies in leiningen?

9:08 CookedGryphon: silasdavis: checkouts?

9:09 noncom: mdrogalis: it gives advices on adding exclusions and stuff.. you think I should try it? whats funny, it runs fine in Eclipse CCW, but fails as a standalone jar on another machine..

9:09 (i mean the xml parsing fails)

9:10 mdrogalis: noncom: Yes, exclusions will help.

9:10 lvh: hyPiRion: It may be because I told cidr to pretty-print things

9:10 hyPiRion: perhaps it is expecting pretty print to always be available

9:10 silasdavis: CookedGryphon, sort of, I was hoping for something a bit slicker than that, sort of like how you can provide git urls in ruby gemfiles

9:11 hyPiRion: lvh: yeah, then you should probably tell cider to execute `(require '[clojure.pprint :as pp])` when jacking in. Not sure how you do that, though

9:13 CookedGryphon: silasdavis: nothing that I know of. What's stopping you just deploying it to clojars if it isn't there already?

9:14 silasdavis: it is there already

9:15 I have just serviced some pull requests that were left open on at-at

9:15 if I push to clojars will it namespace it under my name?

9:16 CookedGryphon: yep

9:17 llasram: silasdavis: You need to modify the project file to use a group-id you control

9:17 silasdavis: If you've done that, then you're gold

9:17 daGrevis: hi! can someone help me with clojure deps?

9:17 CookedGryphon: i think if the group id in project.clj is already taken, it'll do that automatically for you?

9:17 daGrevis: i'm using lein exec and I want to use contrib string

9:17 i have found this https://github.com/kumarshantanu/lein-exec#getting-dependencies-from-within-script

9:17 llasram: CookedGryphon: Nope -- it'll just reject your push

9:17 daGrevis: but I don't know how can I apply it together with http://richhickey.github.io/clojure-contrib/string-api.html

9:17 CookedGryphon: oh, I'm sure I've done that before without having to edit the project.clj

9:18 llasram: CookedGryphon: *shrug* I may be mistaken, but that is at odds with my understanding of the system

9:19 daGrevis: (a) anything clojure.contrib is ancient history and unlikely to work, unless you're stuck on Clojure 1.2 for some reason

9:19 (b) The official Clojure github repos are under the `clojure` org now, not the richhickey user

9:19 daGrevis: llasram, ohh. well I would like to use string.substring?. where could I find it?

9:19 CookedGryphon: llasram: it might depend whether the project.clj already specifies a group-id or you let it pick the default one

9:19 llasram: (doc subs)

9:19 clojurebot: "([s start] [s start end]); Returns the substring of s beginning at start inclusive, and ending at end (defaults to length of string), exclusive."

9:20 llasram: daGrevis: ^ that?

9:20 daGrevis: llasram, not subs. substring? like to check if "xy" is in "xyz"

9:20 llasram, tried with (some) but it has a lot of boilerplate

9:22 llasram: ,(#(not (neg? (.indexOf %1 %2))) "xyz" "xy")

9:22 clojurebot: true

9:22 daGrevis: llasram, and I think that some won't work with strings, only with integers

9:22 llasram, yes, that's an option. can I do it w/o Java?

9:23 llasram: Given that Clojure strings are Java strings, not technically, no :-)

9:23 Avoiding JVM method interop to avoid it is a way to be very unhappy writing JVM Clojure

9:23 devn: ,((complement neg?) (.indexOf "xyz" "xy"))

9:23 clojurebot: true

9:23 daGrevis: too bad, I'm not a big fun of Java

9:23 devn: i like that a bit better, just nitpicking

9:23 hyPiRion: people

9:23 daGrevis: *fan

9:24 hyPiRion: ,(.contains "xyz" "xy")

9:24 clojurebot: true

9:24 llasram: hyPiRion: Dorb

9:24 devn: oh, was that was he was trying to do?

9:24 mdrogalis: daGrevis: I don't think any of us are 'fans' of Java, but you're gonna have a bad time if you don't leverage the runtime better.

9:24 llasram: I knew that was there. I just couldn't remember the method name

9:24 daGrevis: you see, I like to imagine clojure as an standard not implementation. might as well run my code on clojure-py

9:25 mdrogalis: Better get on that, tbaldridge.

9:25 llasram: daGrevis: In my experience, so dreams are not yet to be :-)

9:25 s,so dreams,such dreams,

9:25 tbaldridge: daGrevis: come to the dark side, we have super fast JITs with the best GCs on the planet :-P

9:26 devn: daGrevis: i think what you're saying is correct long-term

9:26 but right now the reality is: use the jvm

9:26 daGrevis: lets hope it happens :)

9:26 hyPiRion: daGrevis: I have a coworker who refuses to write Clojure for that reason. Problem is, creating such a "standard" is super hard if you want to compete with the JVM, and I don't think rhickey and friends got time to compete with that.

9:26 devn: no one does

9:27 daGrevis: well jvm is good and bad at the same time

9:27 it's stable and fast, but it's huge

9:27 atyz: Hey guys. I'm trying to use core.async to validate a collection of entities asynchronously. However its not returning the collection I expect it to. Infact tis not returning anything at all. I feel that I'm doing somethign obviously wrong. https://www.refheap.com/694be39810dace491121144d2

9:27 tbaldridge: daGrevis: hyPiRion: is right. I've spent way to much of the last 3-4 years researching this sort of thing. Without the features the JVM offers, getting code that runs even close to the speed of the JVM is very very hard.

9:27 atyz: Is anyone willing to take a look at that for a second? Just want a step in the right direction

9:28 daGrevis: what about contains fn that uses java contains if the code is run on jvm, but uses X if the code is run on X runtime?

9:29 i really dislike explicit calls of Java fns, that's all

9:29 llasram: daGrevis: Why?

9:29 lvh: actual: java.lang.NullPointerException: null

9:29 Woo!

9:29 llasram: I mean, in practice?

9:29 daGrevis: llasram, because it means that my code will work only on jvm

9:29 hyPiRion: Perhaps for strings, just to bridge clj/cljs better.

9:29 llasram: Yes, but where else are you going to run it?

9:30 hyPiRion: Problem is overhead, probably.

9:30 daGrevis: llasram, for now, nowhere else. but you know, if clojure gets successful, there will be other runtimes

9:31 i could compare it to javascript. it would be awful to call v8 specific-fns in js

9:31 llasram: And after the Singularity, none of our code will ever be run again

9:31 tbaldridge: daGrevis: when that happens, move those functions into a differend ns and port to CLJS or clojure-clr or something. At least in my code, only about 5% is host interop

9:31 daGrevis: what is this Singularity you are talking about, llasram ?

9:31 lvh: How do I spell (thing map) except when thing is nil? Is (get thing map) good?

9:32 hyPiRion: daGrevis, llasram: Actually, I'd rather just write Java calls and then use use contrib.tools.analyzer to rewrite the code for the other runtime. I'm sure bronsa is at it already :p

9:32 Granted, that would be interesting for me, not sure if it suits you.

9:35 llasram: hyPiRion: Oooh. That would be fancy.

9:35 daGrevis: http://en.wikipedia.org/wiki/Technological_singularity

9:36 CookedGryphon: atyz: <!! is the blocking version for use outside of go blocks, inside a go block use <!

9:37 so you're probably locking all your threadpools before they've done anything

9:37 atyz: CookedGryphon: Thanks for the reply. I still don't get the collection back. it just returns the channels

9:38 CookedGryphon: threads*

9:38 okay, so go returns a channel

9:39 sorry, I'm not sure I follow the code

9:39 why aren't you putting the entities onto the challen

9:39 c is an empty channel with nothing on it

9:39 so nothing is ever going to come out of it...

9:40 atyz: I thought that the (async/map< #(f entities) c) would put them onto the channel?

9:40 CookedGryphon: no, map< will apply the function to each item as it passes through the channel

9:40 and returns a channel with your transformed values coming out of it

9:41 onto-chan puts the contents of a collection onto a channel

9:41 atyz: Oh, so I would need to (map #(async/!> %) entities) ?

9:41 or (async/map> entities c)

9:42 CookedGryphon: step back, what's the basic idea here

9:42 you have a list and you want to validate them one by one and have the items come out of a channel once they've validate

9:42 d

9:42 atyz: Correct

9:43 lvh: I have a bunch of persons, defined as: {... :partner other-person}. Is there a group-by :partner, except that I know everything should be 1:1, so group-by except dont put things in a vector + complain loudly when an association already existed

9:44 CookedGryphon: so, you want to do (onto-chan c entities)

9:44 llasram: lvh: Nothing exactly like that that I'm aware of, but easy enough to do in a `reduce`

9:44 CookedGryphon: (let [validated (map< valid-entities c)] ...

9:44 and then pull the values out of that new validated channel

9:45 sorry, map valid-entity?

9:45 in fact you don't want to map at all do you, you want to filter<

9:46 atyz: You're very right

9:46 CookedGryphon: then you can use async/into to pull the results out into another collection, or you could pull them out one by one with <! or feed that channel into something else

9:47 atyz: Thanks so much! Youv'e been a great help. I'm going to try this

9:47 CookedGryphon: not sure what you really gain by doing this with core async though, if this is all there is to the problem

9:47 you might be better looking at reducers for parallel filtering with much less boilerplate and confusion

9:48 atyz: CookedGryphon: Its a simple problem I'm using to try out the library

9:48 CookedGryphon: in that case carry on :)

9:52 lvh: llasram: Okay. How do I break out of a reduce by raising an exception? I'm guessing it's return an exception from the reducing function?

9:53 llasram: lvh: No -- if you throw an exception, the exception will propagate normally

9:54 lvh: I didn't realize I could throw in clj :)

9:55 llasram: ,(throw (ex-info "Alaram!" {:bells :many}))

9:55 clojurebot: #<ExceptionInfo clojure.lang.ExceptionInfo: Alaram! {:bells :many}>

9:56 hyPiRion: alaram sounds like character

9:56 *some character

9:56 like Radagast.

9:56 llasram: Yeah, I meant to say "alarum". Alaram the Red sounds pretty badass though

9:57 hyPiRion: hehe

9:57 sandbags0: i may be imagining it but isn't there already a way of breaking out of a reduce? I'm sure I read some such just a few days ago

9:57 Bronsa: sandbags0: reduced

9:57 sandbags0: Bronsa: thank you

9:59 daGrevis: lazyness rules so much

10:00 thought my code is super fast but actually it wasn't evaluated. :( :D

10:03 shep-werk: daGrevis: can't get much faster than that!

10:03 daGrevis: from instant to 7s :(

10:03 shep-werk: only thing faster would have been to not write it in the first place :-)

10:03 daGrevis: http://vpaste.net/u0pzI

10:05 ddellacosta: daGrevis: why are you doing three filters like that, rather than composing your predicates together and doing it in one, any reason?

10:06 and holy heck what is up with that range

10:07 daGrevis: ddellacosta, i don't know any other way. can you show me?

10:07 ddellacosta: daGrevis: ah, okay

10:07 daGrevis: ddellacosta, are you talking about step being 2013?

10:07 ddellacosta: daGrevis: naw, just complaining 'cause my repl is spitting out numbers endlessly

10:07 heh, one sec

10:15 tim_: i'm confused about the map function with an anonymous function, for example: '(map #(format "<p>%s</p>" %) ["1" "2" "3"])' What does the last '%' represent? the input list??

10:15 lazybot: tim_: Uh, no. Why would you even ask?

10:15 tim_: :-)

10:16 arkh: anyone have any opinions on using Future vs. CompletionHandler for java.nio.channels.AsynchronousSocketChannel ?

10:16 RickInAtlanta: tim_ when declaring a function with #() the % is a standin for a passed parameter

10:16 hyPiRion: tim_: the last % represents the first input value given. In this case, it is "1", "2" and "3", respectively

10:17 RickInAtlanta: (map #(* 2 %) [1 2 3])

10:17 ,(map #(* 2 %) [1 2 3])

10:17 clojurebot: (2 4 6)

10:18 dkinzer: ,(map #(% 2 4) '(+ - *))

10:19 clojurebot: (4 4 4)

10:19 dabbeling_in_clo: hello there i'm just starting with clojure , if I start a new project with leiningen and then go into the project with lein repl, how do I "re evaluate " I my namespace if I make changes to my file?

10:19 dkinzer: that didn't work as expected :)

10:20 tim_: ok, thanks. So if i wanted to replace the anonymous function with a named function, such as (defn f2 [keyword] (str "<p>" keyword "</p>")), would it need to take the list as an argument as well?

10:20 dkinzer: ,(map #(% (% 2 4)) '(+ - *))

10:20 clojurebot: (nil nil nil)

10:20 llasram: tim_: The first % in your original is just part of the format string

10:20 It has nothing to do with the anonymous function

10:20 dkinzer: ,(map #(-> (% 2 4)) '(+ - *))

10:20 clojurebot: (4 4 4)

10:21 tim_: @llasram Sorry, was interested in the last '%'

10:21 RickInAtlanta: ,(map #(% 2 4) [+ - *])

10:21 clojurebot: (6 -2 8)

10:21 arkh: dabbeling_in_clo: are you using a repl at the command line or through an editor like emacs?

10:21 dabbeling_in_clo: arkh: I use the command line

10:21 dkinzer: (inc RickInAtlanta)

10:21 lazybot: ⇒ 1

10:21 dabbeling_in_clo: arkh: I use the command line, and a seperate text editor

10:22 tim_: (use 'namespace :reload-all) may help

10:22 RickInAtlanta: jcrossley3: did you have to drive anywhere yesterday?

10:22 ToxicFrog: dabbeling_in_clo: IME, without using additional libraries, quitting and restarting the repl is the only reliable way; (use 'namespace :reload-all) works sometimes.

10:22 llasram: tim_: Ok -- thought I sensed some confusion there. Otherwise you can just do e.g. (fn [x] (format "<p>%s</p>" x))

10:22 ToxicFrog: dabbeling_in_clo: people have in the past recommended using tools.namespace (https://github.com/clojure/tools.namespace) and then using its (refresh) function.

10:23 jcrossley3: RickInAtlanta: i did! i had to save a few of my neighbors. :)

10:24 dabbeling_in_clo: ToxicFrog: thanks that will do until now :)

10:24 RickInAtlanta: glad to hear you didn't get stuck any where. I didn't leave the house

10:25 jcrossley3: RickInAtlanta: i heartily recommend honda ridgelines in freezing snow, fwiw

10:26 ddellacosta: daGrevis: this isn't much of an improvement but it's a bit easier to read I think: https://www.refheap.com/29352

10:26 RickInAtlanta: I'll remember that if I ever move back north. Down here, I just don't go out in it.

10:27 daGrevis: ddellacosta, why did you choose rem over mode?

10:27 s/mode/mod/

10:27 and why do you dislike zero?

10:27 ddellacosta: daGrevis: oh, I don't have any great reason for it, was just playing around

10:28 daGrevis: what's the benefit for using distinct instead of set?

10:28 ddellacosta: daGrevis: oh, did I leave that in? yeah, I don't know if it's any better than your solution. Again, just playing around with those two, seeing if there were other ways to do it.

10:28 daGrevis: ddellacosta, thanks for (all fn).

10:29 ddellacosta: daGrevis: still wicked slow though. I take it you're just playing around in the repl though?

10:29 daGrevis: ddellacosta, what do you mean?

10:30 ddellacosta: daGrevis: well, if you force evaluation it's going to be doing a linear search through a buttload of numbers, I believe

10:31 daGrevis: ddellacosta, force-eval with and, you mean?

10:32 distinct is **much** slower than set.

10:32 ( :D

10:32 * surrealanalysis (~kevin@23-25-48-173-static.hfc.comcastbusiness.net) has joined

10:32 * aspotashev has quit (Ping timeout: 272 seconds)

10:32 * sputnikus has quit (Ping timeout: 260 seconds)

10:32 * zan-xhipe has quit (Remote host closed the connection)

10:32 * federkasten (~federkast@ad046065.dynamic.ppp.asahi-net.or.jp) has joined

10:32 * eraserhd (~jfelice@ has joined

10:32 * aaronj1335 is now known as aaronj1335_

10:32 <shep-werk> daGrevis: can't get much faster than that!

10:32 <daGrevis> from instant to 7s :(

10:32 <shep-werk> only thing faster would have been to not write it in the first place :-)

10:32 <daGrevis> http://vpaste.net/u0pzI

10:32 * animated has quit (Ping timeout: 252 seconds)

10:32 ddellacosta: daGrevis: what's going on there

10:32 daGrevis: * goodger has quit (Ping timeout: 272 seconds)

10:32 * bertrandk (~bertrandk@135-23-72-39.cpe.pppoe.ca) has joined

10:32 <ddellacosta> daGrevis: why are you doing three filters like that, rather than composing your predicates together and doing it in one, any reason?

10:32 * lnostdal (~lnostdal@2001:8a0:4925:6801:8bd:21b9:afe1:1184) has joined

10:32 llasram: Obviously a paste error

10:32 daGrevis: * TEttinger (~notostrac@76-217-24-241.lightspeed.irvnca.sbcglobal.net) has joined

10:32 * federkasten has quit (Remote host closed the connection)

10:32 * baoist has quit (Quit: baoist)

10:32 <ddellacosta> and holy heck what is up with that range

10:32 <daGrevis> ddellacosta, i don't know any other way. can you show me?

10:32 <ddellacosta> daGrevis: ah, okay

10:32 ddellacosta: llasram: yep.

10:32 daGrevis: <daGrevis> ddellacosta, are you talking about step being 2013?

10:32 * john2x has quit (Remote host closed the connection)

10:32 sorry....

10:32 ddellacosta: I'm having flashback

10:32 daGrevis: 25s vs 7s

10:33 lnostdal: well hello #clojure

10:33 ddellacosta: *a

10:33 daGrevis: sorry for spam, missclicked middle-click on Linux

10:33 surrealanalysis: It made me feel important, at least :)

10:33 ddellacosta: hahaha

10:33 lnostdal: :D

10:33 goodger: what in satan's glorious name

10:33 gfredericks: (inc daGrevis)

10:33 lazybot: ⇒ 1

10:33 AeroNotix: Can I (require) code from other test/*.clj files when using core.test?

10:33 ddellacosta: sh*t happens

10:33 llasram: AeroNotix: Why would you not be able to?

10:33 AeroNotix: dunno, just asking

10:34 joegallo: maybe you should try it, and see

10:34 daGrevis: so why is set so much faster than distinct on a string?

10:36 llasram: daGrevis: With `distinct` you build the set anyway to make sure each item is distinct, but are repeatedly checking the set to see if each item is distinct, performing overhead to build the seq of distinct items which are returned, then you walk it again linearly to get the count

10:36 ddellacosta: daGrevis: well, distinct is actually filtering through stuff in Clojure whereas set is just creating a set (which is a Java object I believe)

10:36 or what llasram said much more eloquently ^^

10:36 llasram: daGrevis: With the set you just add everything, then get the stored count of items

10:37 daGrevis: I'm trying to apply and, but it splits out different results. any ideas why? http://vpaste.net/a9QQS

10:38 Morgawr: I'll ask again, maybe now there are different people, what do you guys think of https://gist.github.com/Morgawr/8687711 this macro? Is there something similar already?

10:38 llasram: daGrevis: You aren't actually calling `digits-unique?`

10:38 Morgawr: because I find it useful for my codebase but I'm not sure if it's safe and/or reasonable

10:38 llasram: Just including the (always truthy) value of the function itself in the `and`

10:39 daGrevis: llasram, ye, my bad. thanks

10:39 llasram: Morgawr: Why is that better than the standard binding form?

10:40 daGrevis: what what what !? it runs 7x faster than using three filters

10:40 Morgawr: llasram: because in my codebase I usually have to destructure a lot of maps and get their keys to use as variable (passing state around etc etc)

10:40 and it gets tiring when I write multiple (let [{:keys []} map1 {:keys []} map2] etc etc)

10:40 zerokarmaleft: daGrevis: why are you checking to see if your range is divisible by 2013 when you're stepping by 2013 anyway?

10:41 llasram: Morgawr: Sure, but it's like what -- 2 characters shorter? And you can't use it with any other binding forms

10:41 Morgawr: it's not 2 characters shorter when you have 4-5 maps to destructure

10:41 daGrevis: zerokarmaleft, good point

10:41 Morgawr: plus it looks tidier to read imo

10:42 obviously if I don't have maps but have something else to assign I have to use an inner (or outer) normal let but that's expected

10:42 zerokarmaleft: daGrevis: I'd replace (range 2013 9876543210 2013) with (iterate (partial + 2013) 2013)

10:43 llasram: Morgawr: I see. It might mean you are over-using maps :-) It's a bit too trivial for my taste, but I can see the argument. Consistency w/in a code base w/ that sort of thing is probably the most important

10:44 Morgawr: llasram: It's a game engine where entities are made of components, an entity is a map of components and components are maps of inner state, I can't really do it in another way :P

10:44 so usually I have code that extracts components from an entity, then extract individual fields from the required components, does some computation and then repackages everything

10:45 aka I deal with maps a lot

10:45 gfredericks: Morgawr: the f# name is unnecessary

10:45 Morgawr: gfredericks: is it?

10:45 llasram: zerokarmaleft, daGrevis: and probably then add a `first` or `take <n>`

10:45 Morgawr: oh well, since it's outside of the quote part I guess you're right

10:45 not going to conflict with anything

10:45 gfredericks: Morgawr: exactly

10:45 Morgawr: good point

10:45 same for i# and e#

10:46 I wrote that just to be safe but yeah, didn't think it through

10:46 gfredericks: Morgawr: I don't think this is a terrible macro; the impl might be slightly clearer with partition-all instead of map-indexed

10:46 but I think it's pretty obvious what it does

10:46 which is a good attribute for a macro I think

10:47 Morgawr: gfredericks: oh, right, I didn't like map-indexed myself so I was looking for a better way

10:47 partition-all might be useful

10:53 luxbock: https://gist.github.com/8690806

10:53 how do I unlazify this mess?

10:53 I thought doall was the solution but maybe it's not working because I'm using the threading macro?

10:53 Anderkent: doall realizes, but doesnt unlazify

10:54 i think you just want seq

10:54 ,(str (doall (map inc [1 2 3])))

10:54 clojurebot: "clojure.lang.LazySeq@7c42"

10:55 Anderkent: ,(str (seq (map inc [1 2 3])))

10:55 clojurebot: "(2 3 4)"

10:55 luxbock: alright thanks

10:56 hyPiRion: ,(pr-str (map inc [1 2 3]))

10:56 clojurebot: "(2 3 4)"

10:56 zerokarmaleft: daGrevis: if I'm correctly understanding what your snippet is trying to do:

10:56 lvh: What is the right way to interpolate some text into a string

10:56 zerokarmaleft: ,(take 5 (filter #(= (count ((comp set str) %)) (count (str %))) (iterate (partial + 2013) 2013)))

10:56 mdrogalis: ,(doc format)

10:56 clojurebot: (2013 4026 6039 8052 12078)

10:56 "([fmt & args]); Formats a string using java.lang.String.format, see java.util.Formatter for format string syntax"

10:56 lvh: mdrogalis: Thanks!

10:57 quizdr: ,(println "hi, christine!")

10:57 clojurebot: hi, christine!\n

10:59 lvh: mdrogalis: Is there an alternative that supports named keys instead of by-index?

10:59 mdrogalis: lvh: Not sure.

10:59 Anderkent: you mean in format? not in core java

10:59 Morgawr: gfredericks: https://gist.github.com/Morgawr/8687711 do you think this might look better? I don't like having to use that map to add {:keys } to the first element of all the pairs (is there a better way?) nor I like having to use flatten + vec

10:59 but I guess it's better than the previous one

10:59 Anderkent: i think java 8 brings that in?

11:02 maybe not. Pretty sure apache commons lang has something like that though ;p

11:03 stuartsierra: There's a string interpolating macro in core.incubator I think. Hasn't been touched in a while so beware.

11:14 gfredericks: Morgawr: you can use mapcat instead of map + comp, and then [~@key-bindings] instead of ~key-bindings

11:15 Morgawr: gfredericks: thanks

11:16 ghadishayban: Has anyone gotten friend + openID to work behind a load balancer?

11:16 I'm getting a 'No association found, contacting the OP for direct verification' failed inside OpenID4java

11:23 cemerick: ghadishayban: Should just work; there's an openid example at http://friend-demo.herokuapp.com, which of course always runs behind a load balancer

11:24 Anderkent: ghadishayban: do you pass a custom consumer manager to the workflow?

11:25 ghadishayban: if so, you might not be initializing it fully? See http://stackoverflow.com/questions/7645226 - similar error, friend does most of this in https://github.com/cemerick/friend/blob/master/src/cemerick/friend/openid.clj#L107 but only if it's building the manager itself

11:26 uh actually nvm, it's not even a similar problem, tricked by google's removal of literal quotes again!

11:27 ghadishayban: Anderkent: Huh?

11:27 Anderkent: just ignore me :P I searched wrong (no 'literal' option in search tools) and got that stack overflow question thinking it's related. blame google.

11:27 (s/literal/verbatim. Anyway)

11:30 ghadishayban: cemerick: are there multiple nodes behine the load balancer at friend-demo?

11:30 Anderkent: ghadishayban: do you get another error following that message? the 'no association' shouldn't abort the entire flow, it just means it can't verify the signature locally

11:31 ghadishayban: Anderkent: You're totally right, it continues with: No association found, contacting the OP for direct verification...

11:32 Anderkent: which returns a document with is_valid:false

11:32 cemerick: ghadishayban: no; friend's openid impl just uses the default in-memory backend for openid4java. You can either implement a distributed/cluster-aware component for the corresponding bit in its API, or restrict logins to a single node.

11:32 ghadishayban: Anderkent: Direct signature verification failed with OP: https://www.google.com/accounts/o8/ud

11:32 cemerick: ghadishayban: relevant lines: https://github.com/cemerick/friend/blob/master/src/cemerick/friend/openid.clj#L107

11:32 ghadishayban: cemerick: ty

11:33 cemerick: ghadishayban: oh, or you can just turn on session affinity (if your LB supports it)

11:33 ghadishayban: cemerick: but it still should be able to perform the direct sig verification, right?

11:34 cemerick: ghadishayban: Don't know, I try to forget as much as I can about openid, etc. :-P

11:34 ghadishayban: cemerick: heh yeah

11:34 cemerick: I'm guessing not, even "direct" verification requires a couple of redirects, so if you land on a different web server, you're SOL

11:35 Yamazaki-kun: anyone just get an email from Apress? "vbvhgvhg" "BUY OUR BOOKS" "Use promo code MKJKJH by MM/DD/YY"

11:35 I'll be disappointed if that promo code doesn't do anything.

11:35 slaps the copyeditor?

11:35 xnil: is that the actual promo code?

11:39 ghadishayban: cemerick: thanks for your help. The direct verif requires redirects in your own app (the Relying Party)? I guess I have to dig in to the spec

11:40 cemerick: ghadishayban: Honestly, no idea. If you can turn on session affinity, that's absolutely the easiest way to go.

11:48 bbloom: akurilin: pong

11:57 Pupeno_w: Does anybody remember that comic, black and white, where a guy learns that closures and poor man's objects and then learns that objects are poor man's closures?

11:59 Morgawr: Pupeno_w: no but I'm intrigued now haha

12:00 * Pupeno_w goes to #lisp to ask.

12:01 lvh: clojure.contrib.strint does what I want, but it appears to be a gnarly macro that takes a string at compile time

12:01 is there a runtime equivalent?

12:01 I'm reading templates from files.

12:03 devn: well, it's another macro, but there's: https://github.com/alandipert/interpol8

12:03 lvh: ^

12:03 S11001001: Pupeno_w: Yeah I remember it.

12:03 Pupeno_w: (not where I saw it, if you're asking :)

12:04 Anderkent: S11001001: remember a quote or title or something ? :P

12:04 Pupeno_w: I'm trying to find it.

12:04 Yamazaki-kun: xnil: I have no idea. Probably just a placeholder, unless they decide to play along and enable it

12:04 Pupeno_w: I already blew my partner's mind with Smalltalk... Clojure is next and the comic at the end so she goes into deep meditation.

12:04 Yamazaki-kun: what, Erlang's not enough for mind-blowing?

12:05 devn: lvh: is that at all what you're looking for?

12:06 lvh: one more for you: https://gist.github.com/blacktaxi/1676575

12:06 Anderkent: lvh: just wrap http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/text/StrSubstitutor.html if you can't find anything. I'd expect anything that wraps java.util.Format will be a macro (it'll pick out the names out of the string and replace them with ints)

12:06 RickInAtlanta: pupeno_w this isn't a comic, but it starts with a story http://c2.com/cgi/wiki?ClosuresAndObjectsAreEquivalent

12:07 devn: lvh: both call read-string, so maybe not ideal

12:07 but im mostly okay with it

12:07 Pupeno_w: RickInAtlanta: mmhh... that's definitely what I'm remembering. I wonder if someone turned it into a comic or it was my mind making shit up.

12:15 lvh: Anderkent: I have no problem that it is a macro

12:15 silasdavis: has anyone used timbre to write multiple logs

12:15 like a separate error log and request log?

12:15 llasram: log4j 4 life

12:15 lvh: Anderkent: Although I guess there's no good reason for it to be a macro if it's just doing straught interpolation

12:16 * llasram isn't helping

12:16 silasdavis: llasram, srsly?

12:17 llasram: silasdavis: Every single Java logging framework is overly complicated, but I can turn log4j into a homogonous stream of text-lines on stderr easier than I can with most of the others

12:17 gfredericks: lvh: macros can parse a format string ahead of time

12:17 llasram: even homogeneous

12:17 lvh: gfredericks: Right, I understand, but the thing is that I don't necessarily know the format strings ahead of time

12:17 gfredericks: I guess maybe I could make it so that I can? I guess?

12:19 gfredericks: It just seems to me that if it can be done at compiletime, there should be some easy way to just do it at runtime instead?

12:19 maybe I want apply-macro, except the docstring suggetss against it ;)

12:21 gfredericks: lvh: some macros with this goal will do compile-time if possible and runtime otherwise

12:21 can also accomplish such a thing using :inline metadata

12:21 but if this isn't a perf issue for you already them probably don't bother?

12:22 lvh: gfredericks: Right; I haven't written any code yet. It's my understanding that strint's (>>) simply does not work without a string literal

12:22 but I could be wrong :)

12:24 llasram: lvh: Nothing is purely compile time, because there is always "eval"

12:25 technomancy: eval is compile time =)

12:25 compile time is just a subset of runtime

12:25 gfredericks: lvh: yeah that's probably true; it could be rewritten to support both

12:26 llasram: technomancy: Fair enough

12:27 gfredericks: runtime is just a subset of time

12:27 ~time

12:27 clojurebot: time is limited

12:27 * technomancy nods sagely

12:28 gfredericks: ,(clojure.set/subset? (set "time") (set "limited"))

12:28 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>

12:28 gfredericks: &(clojure.set/subset? (set "time") (set "limited"))

12:28 lazybot: ⇒ true

12:29 gfredericks: if you have a sufficiently small universe of objects you can implement bags using prime numbers for elements and positive integers for bags; then inclusion and subbag? are both divisibility checks

12:30 union is LCM?

12:30 intersection is GCD

12:30 I doubt this is actually useful

12:41 elsen: Next time I'll need to use bit-strings to solve a problem I'll go for the prime representation instead

12:41 thanks gfredericks

12:46 gfredericks: bitstrings are for sets, not bags

12:54 just split the routing step out of the base ring handler so the middlewares know what route was matched

13:03 tim_: hi, is pedestal a widely used framework?

13:16 technomancy: tim_: I don't get that impression

13:16 not that I would know

13:17 tim_: thanks

13:28 akurilin: bbloom: was going to run a couple of ideas regarding cancan in clj by you, let me drop you a line later in the day when I'm at the office

13:28 bbloom: akurilin: ok

14:51 eyepatch: Could someone explain these results to me? I know that last is slow and linear time, but this seems outrageous. http://ideone.com/6vSlaN

14:57 edbond: eyepatch, time returns early because of laziness

14:58 eyepatch, compare (time (map (fn [_] (Thread/sleep 2)) (range 10)))

14:58 eyepatch, and (time (doall (map (fn [_] (Thread/sleep 2)) (range 10))))

14:58 ,(time (doall (map (fn [_] (Thread/sleep 2)) (range 10))))

14:58 clojurebot: "Elapsed time: 24.298924 msecs"\n(nil nil nil nil nil ...)

14:58 edbond: ,(time (map (fn [_] (Thread/sleep 2)) (range 10)))

14:58 clojurebot: "Elapsed time: 0.124207 msecs"\n(nil nil nil nil nil ...)

15:02 edbond: eyepatch, so you got time result first and then repl do the work of realizing lazy sequence

15:04 got time result => you measure time to create lazy sequence

15:05 eyepatch: edbond, that makes sense, but how do I tell it not to do that? conv to vec?

15:06 edbond: eyepatch, use dorun/doall/doseq

15:06 eyepatch, http://onclojure.com/2009/03/04/dorun-doseq-doall/

15:06 eyepatch, and https://stackoverflow.com/questions/9143837/in-clojure-is-there-a-doseq-like-function-that-receives-a-function-instead-of-b

15:08 bbloom: edbond: i've needed that several times. whenever i make it, i call it "each"

15:09 eyepatch: Wow. I've been working in the completely wrong areas.

15:09 Taking 1 ms down to < 1 ms instead of working the other 762 ms

15:10 xnil: Hey. I'm following the instructions for getting Clojure working in Emacs here http://clojure-doc.org/articles/tutorials/emacs.html and I've run into the following issue when running `M-x eval-buffer` on ~/.emacs.d/init.el : "error: Package `starter-kit` is not available for installation"

15:13 Any idea why?

15:15 cark: try X-x package-refresh ?

15:15 M-x

15:16 package-refresh-contents actually

15:22 xnil: cark: excellent, thanks

15:22 cark: yay !

15:43 CaptainLex: Is clojure still dependent on jre6?

15:44 hiredman: jre6 is the minimum required version of the jvm

15:45 well, I should say, whenever 1.6 is released it will be

15:45 CaptainLex: But we can use jre7 if we want to now? I seem to recall when I started there was an issue with use jre7

15:45 hiredman: sure

15:45 CaptainLex: Cool, thanks hiredman

15:51 ghadishayban: cemerick: got the OpenID woes sorted out. Turns out that openid4java will attempt to make associations with the provider, then fallback to a direct verification of a client's presented cert

15:52 cemerick: that is a violation of the spec, and Google will fail the verification if Association was already performed

15:52 cemerick: So I had to call .setMaxAssocAttempts -> 0 on ConsumerManager, which friend allows you to do

15:53 mercwithamouth: i could have sworn you could start the server like this with light table/compojure...can someone thump me on my head please? http://d.pr/i/niPh

15:53 ghadishayban: cemerick: that way both nodes behind the balancer will never Associate and instead call Google for direct verification. Good enough for our purposes

15:53 mercwithamouth: this is what i get for taking 2 week breaks from clojure

15:54 ghadishayban: mercwithamouth: (use) first, then (in-ns)

15:54 mercwithamouth: ahh oops

15:55 BobSchack: A zipper is the data structure I want to use if I need to get an element and the elements to the the left and right of it. I'm trying to implement the borderline sequence of Fortune's algorithm (http://blog.ivank.net/fortunes-algorithm-and-implementation.html)

15:56 mercwithamouth: ghadishayban: that gets me part of the way there. there was something i used to do where i could just (use 'fossacube.repl) then (star-server) why i didn't write it in my notes is beyond me

15:56 that still doesn't work for me either for some reason...

15:57 ghadishayban: mercwithamouth: so at this point you have to do a :reload

15:57 mercwithamouth: the first time you did (ns foo) it loaded foo, and now Clojure thinks it's loaded, so will no-op

15:58 mercwithamouth: (use 'foo :reload) , then (start-server)

16:01 mercwithamouth: ahh got it!

16:01 that's it...

16:01 if i start a instarepl from handler.clj then everything loads as it should

16:01 thank you

16:21 bobajett: noob question - what am I missing here? (let [f 'print] (f "hello"))

16:21 dnolen: bobajett: just doesn't work

16:21 sdegutis: bobajett: ##(let [f println] (f "hello"))

16:21 lazybot: ⇒ hello nil

16:21 edbond: looks like macro

16:22 dnolen: 'print is a symbol completely unrelated to print the function

16:22 sdegutis: Nobody knows why it works that way, it just does.

16:23 insamniac: Therefore aliens.

16:23 sdegutis: Wow, that response made my day.

16:23 (inc insamniac)

16:23 lazybot: ⇒ 1

16:23 insamniac: :D

16:23 bobajett: so if f has a function as a symbol in it - and I want to apply f. Do I need to eval it? apply it? ((eval f) "hello")?

16:23 stuartsierra: ,('+ 1 2)

16:23 clojurebot: 2

16:24 stuartsierra: ##('+ 3 4)

16:24 lazybot: ⇒ 4

16:24 sdegutis: bobajett: why not just store the function itself in f?

16:24 edbond: ,(let [- +] (- 2 1))

16:24 clojurebot: 3

16:24 SegFaultAX: bobajett: If you ever think to yourself "I need to use eval for this", you've probably gone horribly wrong somewhere.

16:24 stuartsierra: Oh, inlining arithmetic screws with that.

16:24 edbond: nice, should use somewhere :)

16:24 stuartsierra: ,('assoc {} :a 1)

16:24 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: Symbol>

16:24 SegFaultAX: Not always of course, but most of the time.

16:25 AimHere: Redefining arithmetic operations looks like the beginnings of an obfuscated clojure contest entry

16:25 bobajett: SegFaultAX: good to know. I guess Im trying

16:26 sdegutis: Oh wait, aren't symbols also functions to look themselves up in an associative coll?

16:26 Kinda like keywords?

16:26 That would explain why you can't just do (f "hello") in OP's original e.g.

16:26 cark: ,('hello {'hello "hello"})

16:26 clojurebot: "hello"

16:26 sdegutis: Okay that makes sense now.

16:27 stuartsierra: I don't think that's promised.

16:27 sdegutis: stuartsierra: better? ##(promise ('hello {'hello "hello"}))

16:27 lazybot: clojure.lang.ArityException: Wrong number of args (1) passed to: core$promise

16:27 cark: stuartsierra: you mean this symbol behaviour is unspecified ?

16:28 stuartsierra: I'm not sure.

16:28 It's been that way since 2008 at least.

16:29 sdegutis: Well, the great mystery is solved. Time to quit my job and move to the sunny islands.

16:29 shaungilchrist: bobajett: (let [f (resolve 'print)] (f "hello"))

16:29 stuartsierra: https://github.com/clojure/clojure/commit/3b7c161286fd469857ff66013f785bef742e3b07

16:29 cark: ah back in the days, we were young, ritch's hair was seemingly alive

16:30 bobajett: I guess Im trying to convert this lisp code into clojure and looking for the clojure way to do it: (let ((f '+)) (funcall f 1 2)) -> 3

16:30 shaungilchrist: would that imply lisp's funcall = clojure's resolve?

16:31 sdegutis: bobajett: ##(let [f +] (f 1 2))

16:31 lazybot: ⇒ 3

16:31 sdegutis: bobajett: Alternatively, ##(let [f +] (apply f [1 2]))

16:31 lazybot: ⇒ 3

16:31 mmitchell: technomancy: Regarding Leiningen and private repos... Is it possible to have Leiningen do a password prompt?

16:32 technomancy: mmitchell: yes, it should prompt for a password on deploy if none is given

16:32 mmitchell: technomancy: cool, so just setting the username in project.clj will trigger that?

16:32 bobajett: sdegutis: but isn't + the actual function itself in your code rather than a symbol? in the lisp code f is a symbol '+ and not the + function itself

16:32 technomancy: mmitchell: prompting for a password on reads I don't think is supported; I believe it would be too tedious.

16:32 sdegutis: bobajett: Yes, but I don't see how that matters. What is the higher-level goal you're trying to accomplish?

16:33 bobajett: You may want the var, which is Clojure's rough analogy to CL's symbol.

16:33 technomancy: bobajett: funcall does what clojure's resolve does, but also does more

16:33 sdegutis: bobajett: ##(let [f #'+] (f 1 2))

16:33 lazybot: ⇒ 3

16:35 shaungilchrist: but for the sake of insanity: (defn funcall [x & args] (apply (resolve x) args))

16:35 * sdegutis cries "nooooo!!!" into the moonlit rain

16:35 shaungilchrist: "one crazy trick that other clojure developers hate"

16:35 sdegutis: Oops sorry, it was actually streetlight-lit rain.

16:36 dsrx: shaungilchrist: https://pbs.twimg.com/media/BeoLcheCAAAiftC.png

16:36 sdegutis: "Clojure devs hate him! Transliterate your Common Lisp code in 21 days with this one weird function."

16:37 bobajett: sdegutis: Im working through The Little Schemer and they're trying to write a function like (filter your-test some-list) and trying to show that you can set your-test to some symbol and the definition of filter can just apply it via (your-test args)

16:37 sdegutis: ztellman: add that one to your stack

16:37 shaungilchrist: hahah

16:37 ztellman: ha

16:37 bobajett: technomancy: thanks! got it

16:39 mmitchell: technomancy: So for this: ":username :env/archiva_username" - Leiningen will look in the ENV for ARCHIVA_USERNAME?

16:40 technomancy: OK got it! It looks for an upper-cased version of :env/foobar, cool.

16:42 technomancy: right

16:43 gfredericks: access a value in your map with this one weird keyword

16:44 nwolfe: exit

16:44 ztellman: gfredericks: https://twitter.com/ztellman/status/368080217761251328

16:48 sdegutis: Might try out ClojureCLR soon.

16:56 ztellman: sdegutis: is that still alive and kicking?

16:56 sdegutis: no idea, but i hope so

16:56 last commit was 2 months ago, so maybe? https://github.com/clojure/clojure-clr/commits/master

17:01 xnil: Is it possible to do (case (type something) java.lang.SomeType return-value-1 java.lang.SomeOtherType return-value-2)

17:02 sdegutis: xnil: probably, since case just needs compile-time values

17:02 hiredman: no, java.lang.SomeOtherType is not a read time constant

17:02 sdegutis: ,(case (type "foo") java.lang.String 3 java.lang.Integer 4)

17:02 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching clause: class java.lang.String>

17:02 sdegutis: Oh.

17:02 hiredman: at read time it is a symbol that later is resolved to an instance of a class

17:03 xnil: Then how may I do what I'm trying to do?

17:03 sdegutis: xnil: cond

17:03 hiredman: (instance of the class Class)

17:03 xnil: ah okay

17:03 thanks

17:03 sdegutis: xnil: or use a hash-map and look it up

17:03 xnil: sdegutis: oh, i can use these as keys

17:04 sdegutis: Or you could make an RPC call to LaaS (lookups as a service)

17:04 xnil: i like the hash-map idea

17:04 sdegutis: I had a dream this morning where Apple and MS started DaaS (drawings as a service) as a new way to create GUI apps.

17:04 Basically you just draw the app you want on paper and mail it to them, and they make it for you.

17:05 I think that's the direction Apple's going.

17:05 fowlslegs: l

17:06 teslanick: This sounds like a great idea. They could put all those apps into a category on their respective app stores that I would never have to look at.

17:06 "Crap we built with the GUI builders in our IDE, then submitted to the app store."

17:06 sdegutis: It's even easier and cheaper than using Interface Builder OR Storyboards, since you only need a pencil and paper.

17:08 teslanick: Looking at my phone homescreen, all of the apps on it are either Apple-made, or (to one degree or another) ignore the cocoa touch UI

17:08 Except fucking Alien Blue. Shows how much time I spend on Reddit.

17:11 sdegutis: Woo, just found a new alternative to IRC: https://news.ycombinator.com/item?id=7147396

17:21 gfredericks: sdegutis: it links back to the hacker news homepage? is this some joke I don't get?

17:21 sdegutis: yes

17:21 gfredericks: it's a bad joke

17:21 I never learned how to make good noes.

17:21 *ones

17:22 gfredericks: I've made at least a hundred bad jokes in this channel

17:22 just this week

17:22 sdegutis: gfredericks: impressive

17:23 AeroNotix: For one of my projects lein uberjar doesn't finish

17:23 it's a project with a -main function, AOT is skipped for this file.

17:38 mmitchell: technomancy: Hey, I'm attempting to use encrypted credentials but getting this error, have you seen this before? Could not decrypt credentials from ~/.lein/credentials.clj.gpg

17:38 gpg: can't query passphrase in batch mode

17:38 gpg: decryption failed: secret key not available

17:41 technomancy: what's weird is that "gpg -d" successfully decrypts my credentials.clj.gpg file

17:42 technomancy: mmitchell: hm; not sure what's going on there

17:43 it should prompt you

17:43 mmitchell: technomancy: oh, I'm using gpg v 1.4.16 -- do I need >= 2 ?

17:43 it's the stock mac gpg

17:45 AeroNotix: https://github.com/AeroNotix/pismo

17:47 technomancy: mmitchell: there's a stock mac gpg?

17:47 I use 1.4 myself but I know lots of people use 2

17:48 mmitchell: technomancy: oh really? Weird, yes it came with my mac

17:52 Raynes: technomancy: I like the reds.

17:52 They are quite suitable.

17:53 technomancy: glad to hear it =)

17:54 I just discovered this project yesterday and have been unable to get it out of my head http://geekhack.org/index.php?topic=48718

17:54 kind of tempted to build another mech keyboard that's tiny so I can have one for home and one for the road

17:56 egghead: clojure.core.async.impl.timers.TimeoutQueueEntry cannot be cast to clojure.core.async.impl.timers.TimeoutQueueEntry

17:56 WELP

17:56 technomancy: clojurebot: we warned you about records

17:56 clojurebot: I don't understand.

17:56 technomancy: hrm; forgot the exact words

17:58 * egghead uses (Thread/sleep ..) instead

18:01 Raynes: technomancy: I think the reason that I'm cool with reds is because I pretty much pound on my keyboard.

18:01 So I always bottom out anywyas.

18:01 rasmusto: browns are the coolest

18:01 Raynes: anyways*

18:01 technomancy: Also, these are 100% definitely quieter than browns.

18:01 technomancy: I place a keyboard with browns side by side with it.

18:01 technomancy: Raynes: a das?

18:02 Raynes: The keyboard with browns wasn't a das, but why would it matter?

18:02 technomancy: I literally have a red switch next to a brown switch on the board I'm using right now and can't tell the difference in sound

18:02 well, plate-mounted switches are going to sound different from PCB-mounted ones, for starters

18:02 different placing of the circuit board will absorb the sound different wais

18:02 Raynes: technomancy: The keys on the red das are designed differently than the rest of the das line.

18:03 So perhaps that makes it seem quieter?

18:03 technomancy: could be, yeah

18:03 rasmusto: some people do that o-ring mod for bottoming out

18:03 AeroNotix: Oooo I'm in the market few a new keyboard. I've got a Cherry G80 at the moment, previously had a Unicomp Customizer.

18:03 rasmusto: im using a hhkb lite 2 that I stole off an oscilloscope

18:06 akurilin: Putting my vote in favor of Realforce. Been using one for 3+ years.

18:06 rasmusto: those are super top-end right? like $300?

18:07 akurilin: Yeah.

18:07 A bit cheaper these days.

18:07 rasmusto: I'll have to try one out at best buy sometime :p

18:07 akurilin: elitekeyboards.com I think has them for 240

18:07 Yeah I don't think you can find them at a store, they're imported from Japan.

18:07 Could be wrong though.

18:07 rasmusto: I was joking a bit :)

18:07 AeroNotix: Heathens and your tenkeyless boards

18:08 rasmusto: AeroNotix: tenkeyless "otaku" keyboardss*

18:08 akurilin: rasmusto: I get it now, sorry :P

18:08 AeroNotix: rasmusto san

18:08 so lame

18:08 hoi hoi me so korea

18:08 akurilin: AeroNotix: I used to hate it at first, then I got used to using the qwerty digits.

18:08 AeroNotix: qwerty digits, as in you don't even have the 1-9 keys?

18:08 rasmusto: I still have a printout of programmer dvorak in my drawer

18:09 akurilin: AeroNotix: I mean the regular digit keys, as opposed to the keypad

18:09 RickInAtlanta: there is a programmer dvorak?

18:09 akurilin: Used to love the keypad on my natural ergonomics 4000

18:10 rasmusto: RickInAtlanta: it's dvorak with a few of the symbols moved around, and you have to shift+1 to get digits from up there

18:10 akurilin: The leatherette on those things, yum.

18:10 rasmusto: RickInAtlanta: and it does 1234567890 -> 67584839201 or something weird

18:10 AeroNotix: so lame

18:11 RickInAtlanta: wow, I dont' understand reordering the numbers

18:11 rasmusto: paredit makes programmer dvorak obsolete

18:11 RickInAtlanta: yeah, it's done under the assumption that you use the lower digits more frequently, so you don't have to use your pinky

18:11 technomancy: I was shifting around the layout on my ergodox a couple times a day for the first week or so

18:11 * rasmusto uses a left-handed mouse

18:12 TimMc: Brown? Red? What?

18:12 rasmusto: I use a right-handed mouse with my left hand.

18:12 rasmusto: brown feels like a muddy version of blue

18:12 technomancy: TimMc: http://deskthority.net/wiki/Cherry_MX_Brown

18:12 RickInAtlanta: technomancy: i never heard of ergodox until you mentioned it yesterday. My first thought was "I could have dvorak on my laptop"

18:12 rasmusto: TimMc: I used my g5 wrong-handed for a while, wasn't fun

18:13 technomancy: RickInAtlanta: firmware-level turns out to be less convenient than it sounds unless you forgo the internal keyboard of your laptop entirel

18:13 y

18:14 RickInAtlanta: I suppose the easy solution would be to make new labels for my keys and use mapping at the os level.

18:14 rasmusto: RickInAtlanta: check out "otaku" keyboards (no labels haha)

18:15 RickInAtlanta: don't actually, I regret it everytime I have to type in a passphrase

18:15 RickInAtlanta: rasmusto: that is much better than wrong labels

18:15 picture password!

18:16 dkinzer: I have a Dell Model:SK8115 (not sure if it's mechanical or not, but it has all the keys I need. Oh, and it says in the in small print (Made in China).

18:17 RickInAtlanta: canadian language keyboard???

18:17 lazybot: RickInAtlanta: How could that be wrong?

18:18 sdegutis: Tip of the day: You can use two :as clauses when destructuring a map, one to get specific keys and one to name the map itself.

18:18 TimMc: technomancy: I... I see.

18:18 rasmusto: sdegutis: can you do that with :keys as well?

18:18 technomancy: TimMc: blues for life though, natch

18:19 rasmusto: technomancy: how's the tinnitus?

18:19 technomancy: rasmusto: glorious

18:19 sdegutis: I personally do (POST "/whatever" [param1 param2 :as {:keys [db user]} :as request] ...)

18:19 rasmusto: technomancy: <3

18:19 sdegutis: ... with some middleware to wrap the request with a DB instance and assoc a user if you're logged in.

18:21 rasmusto: ,(let [foo :as {:keys [a b]} {:a 1 :b 2}] [a b foo])

18:21 clojurebot: [1 2 :as]

18:21 rasmusto: oh, whoops

18:23 sdegutis: Sorry, wasn't trying to kill the conversation, just felt the need to projectile-vomit that code snippet into the channel.

18:23 I think that'll be my new verb in place of "offer" or "throw out there".

18:24 rasmusto: sdegutis: i confused myself, what's the :as getting bindings from?

18:24 param2?

18:24 sdegutis: ,(let [{:keys [a b] :as m} {:a 1 :b 2}] [a b m])

18:24 clojurebot: [1 2 {:a 1, :b 2}]

18:25 rasmusto: sdegutis: it looked like you were using :as outside of a map destructuring though

18:25 sdegutis: rasmusto: That's part of Compojure.

18:25 rasmusto: sdegutis: ahhh, gotcha.

18:25 sdegutis: Thank/blame weavejester for that.

18:25 rasmusto: I'm just unfamiliar is all.

18:26 sdegutis: Although he's never around. Out rakin the big bucks in. http://bit.ly/1ffUZuq

18:34 dkinzer: quit

18:34 oops..

18:52 sritchie: any core.typed + emacs users in the house?

18:52 looking for workflow advice

18:56 technomancy: sritchie: I don't use it, but I have opinions on how it should be used, does that count? =)

18:57 sritchie: haha, maybe even more so

18:57 technomancy: that is, I have ideas of how to build commands that you invoke from your editor but are implemented server-side

18:57 sritchie: I'm interested in the techtonic ideal

18:57 * technomancy clears his throat and wipes off a clear portion of the whiteboard

18:58 technomancy: actually I wrote most of my thoughts up here: http://p.hagelb.org/clojurewest-2014.org.html

18:58 tl;dr: with an agreed-upon convention for how to annotate vars, you can construct editor commands which feel first-class as if they were written in elisp, vimscript, etc but are actually pure-clojure

18:59 and this can help you avoid re-inventing the wheel for every editor

18:59 as well as letting you skip out on writing a bunch of elisp

18:59 sritchie: yeah man, I'm on board

18:59 technomancy: come see my talk, if it gets accepted =)

19:01 rasmusto: technomancy: at /west?

19:01 oh nm, saw the url

19:01 technomancy: yeap

19:01 sritchie: this clearly feels like the right approach for evaluating type-annotated code via emacs

19:02 technomancy: the current lein plugin runs the "compiler" as if it was a block of unit tests, it seems

19:03 technomancy: I don't think this should be a plugin

19:03 for basically this reason; not having it available in the repl is silly

19:06 akurilin: Is there a general pattern out there for retrying SQL transactions? Do you just give yourself a max num of tries / timeout period and hammer the DB until the transaction goes through?

19:08 sritchie: technomancy: yes

19:09 technomancy: I guess :injections could call check-ns?

19:09 technomancy: learned that lesson the hard way with lein test

19:10 sritchie: still hackish

19:10 technomancy: sritchie: once it's a proper dependency yo ushould just use an :alias to lein run -m whatever.typed

19:10 sritchie: sure, I meant if I wanted to run the checker every time I evaluated anything in the project

19:11 technomancy: oh hrm. every time you evaluate anything?

19:11 sritchie: I'm using Schema really heavily now; the runtime checking sort of gets at the feel of the core.typed repl integration you're talking about

19:11 technomancy: you could use :prep-tasks to invoke it on every lein invocation

19:11 sritchie: the same way the compiler type checks on every evaluation in a typed lang

19:12 technomancy: otherwise, no instant feedback on type signatures

19:12 technomancy: yeah, you would need an nrepl middleware for that

19:23 _eric: if I had an array of maps (like you would often get from a JSON API that lists things)

19:23 is there an easy way to pluck out two things from the map and turn the whole thing into a mapping of one of those values to the other?

19:23 (like a name to ID lookup table)

19:24 aperiodic: (into {} (for [{:keys [name id]} maps] [name id]))?

19:25 technomancy: ,(map (comp (partial into {}) (juxt :k :v)) [{:k 1 :v 2} {:k 3 :v 4} {:k 5 :v 6}])

19:25 clojurebot: #<ExceptionInfo clojure.lang.ExceptionInfo: Don't know how to create ISeq from: java.lang.Long {:instance 1}>

19:25 technomancy: dang it

19:25 _eric: sweet

19:26 x^2: hey guys, simple question

19:26 technomancy: ,(map (comp (partial apply hash-map) (juxt :k :v)) [{:k 1 :v 2} {:k 3 :v 4} {:k 5 :v 6}])

19:26 clojurebot: ({1 2} {3 4} {5 6})

19:26 x^2: if i am using a sequence, like (apply + [1 2 3 4 5])

19:26 _eric: technomancy: I'm looking to create a single map

19:26 x^2: is there any effective difference between that and (apply + '(1 2 3 4 5))?

19:26 or is it just convention

19:27 they seem to work the same

19:27 technomancy: _eric: gotcha; you'd need to either apply merge or switch to a reduce

19:28 x^2: they work the same if the list contains nothing but literals

19:28 x^2: if you have an expressions that evaluates to something else, they are different

19:28 x^2: okay that makes sense

19:28 technomancy: ,(apply + '(1 2 3 (+ 3 4))) ;frinstance, this won't work

19:28 x^2: so if i have expression that evaluate to something else i want to use '(stuff)

19:28 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.lang.Number>

19:28 AeroNotix: is there something like Erlang's make_ref() ?

19:28 x^2: right?

19:29 oh

19:29 technomancy: no, you would use a vector if you didn't want to prevent evaluation

19:29 aperiodic: ,(into {} (map (juxt :k :v) [{:k 1 :v 2} {:k 3 :v 4}]))

19:29 clojurebot: {1 2, 3 4}

19:30 technomancy: oh, much nicer

19:30 x^2: user=> (apply + [1 2 (+ 1 2)])

19:30 6

19:30 that works

19:30 is that the standard way of doingi t?

19:30 technomancy: x^2: typically you'd use a vector unless you have a reason not to

19:31 x^2: okay, cool.

19:31 are there other times when you really should use '(1 2 3) instead?

19:31 technomancy: sure, to prevent evaluation

19:33 or if you want to build up a list from the head; you can only efficiently grow a vector at the tail

19:34 x^2: interesting

19:34 i've just been playing with REPL a lot while i read this book, but i am trying to actually write something in clojure

19:38 tmciver: If anyone is interested in a Clojure job in Framingham, Massachusetts, feel free to PM me.

19:38 devn: tmciver: on site?

19:39 AeroNotix: ,(. clojure.lang.RT (nextID))

19:39 clojurebot: 27

19:43 yesac: howdy folks

19:43 I was wondering if anyone has experience or tips for clojure - scala interop

19:44 more precisely, on using scala libraries in cojure

19:44 bbloom: yesac: first, you need to be able to use scala libraries from java.... which it turns out, isn't easy

19:44 yesac: tell me about it

19:45 bbloom: yesac: https://issues.scala-lang.org/browse/SI-4389

19:45 yesac: other than that, it works exactly like calling java code

19:45 if possible, wrap the scala code in a lowest-common-denominator java interface, then call that

19:46 yesac: the library in question is https://github.com/snowplow/referer-parser/blob/master/java-scala/README.md

19:46 i'm half tempted to take the python port and hack it in jython

19:47 in this particular case, the interface is useable, it's just very ugly

19:47 a lot of boilerplate is required because the scala None class is truthy in clojure

19:47 bbloom: yesac: um, that says java-scala

19:47 it's written in java and is wrapped by scala

19:48 yesac: just use the java classes directly

19:48 noonian: lol, it should be pretty straightforward to write that java usage example in clojure

19:48 yesac: argh

19:48 you are so right

19:48 what the hell was I thinking this morning?

19:48 i guess I scrolled down to the Scala example. fun.

19:48 bbloom: ....

19:49 noonian: i think that is the base java classes, it's called java/scala because it is the java and scala interface to referer-parser

20:25 kristof: What?

20:25 clojurebot: What is sampling a random integers betwen 2, 12 s..t. P(X = i) = (7-|i-7|)/36

20:26 kristof: A day where bitemyapp isn't even idling?

20:28 devn: heh

20:28 technomancy: one too many senseless NPEs pushed him over the edge

20:28 devn: but you have devn and technomany

20:28 technomancy*

20:28 technomancy: it's OK; I contain multitudes

20:28 devn: we've been idling since practically the beginning

20:29 serious idlers.

20:29 metellus: not that serious, if you're talking

20:29 devn: well, i've been watching the channel all day

20:30 i think i'm allowed a few lines

20:32 kristof: technomancy: Wait, what happened?

20:32 rhg135: idling...

20:32 technomancy: kristof: pure speculation

20:32 * rhg135 sinks back

20:32 kristof: technomancy: Ok.

20:35 akurilin: So it looks like fireplace will wait for the remote command to complete before returning the output of it to the editor. As in, if I want to run a very lengthy operation printing progress as it goes, that won't work with fireplace since it will wait until the very end to return the output.

20:35 Is that more or less correct?

20:37 aperiodic: akurilin: that's consistent with my experience, yes. you could try writing progress out to a file and then tailing it in another terminal

20:38 mmitchell: technomancy: What would be the best way to have leiningen pull in username/password (for private repos) from a regular text file? A plugin?

20:38 akurilin: aperiodic: ok cool, thanks for confirming.

20:40 Bronsa: bbloom: btw surprisingly, it's faster to use `~@ than to flatten

20:40 bbloom: Bronsa: huh? how is that possible?

20:41 Bronsa: bbloom: probably because all the `~@ machinery only concats small vectors while flattening has to walk all the bytecode

20:42 bbloom: Bronsa: don't you need to walk all the byte code to output it anyway? you only need one flatten at the top level, right?

20:45 Bronsa: bbloom: right, but I cannot merge the flattening walking and the emit walking otherwise it would not be possible to implement e.g. `omit?` https://github.com/clojure/tools.emitter.jvm/blob/master/src/main/clojure/clojure/tools/emitter/jvm/transform.clj#L56

20:45 bbloom: Bronsa: ... hmm what's this do?

20:45 akurilin: aperiodic: well the workaround I tried was with just using lein repl :connect instead

20:46 aperiodic: as in, I'd write / reload the ns in vim and would actually runt he operation in lein

20:46 lame but oh well

20:46 Bronsa: bbloom: nothing fancy for now, just a POC. it's a dummy matching on the bytecode to eliminate some no-ops

20:47 bbloom: Bronsa: why can't you do this as part of the same traversal as the flattening?

20:47 Bronsa: also, you can use reducers to eliminate a whole bunch of overhead for intermediate structures

20:47 Bronsa: that's what i do in fipp & it performs great

20:48 Bronsa: bbloom: say I want to eliminate a double check-cast, if I'm emitting while flattening there's no way to know if the next instruction is a check-cast so that we can avoid emitting the current one

20:48 it would be possible to know if the previous one was a check-cast but at that point it would already have been emitted

20:49 bbloom: Bronsa: there are more peephole optimizations you can do too besides those with lookahead of N=1

20:50 Bronsa: look at https://github.com/brandonbloom/transduce

20:50 Bronsa: if you your loop variables in the state value of map-state, then you can stitch together the traversals either lazily or with reducers instead of using an eager loop

20:51 timvisher: it looks like ring-serve is no longer supported, what are people using nowadays?

20:51 bbloom: the lazy implementations are easier to read: https://github.com/brandonbloom/transduce/blob/master/src/clojure/transduce/lazy.clj

20:51 but the reducers implementations are much faster

20:52 timvisher: i'm specifically trying to start up an nrepl server _and_ a ring server via `lein run`

20:52 i used to do that via ring-serve but it depends on a very outdated version of ring-devel

20:52 and i use hiccup as well, so they screw eachother

20:52 bbloom: Bronsa: if i'm understanding you and this code right :-P

20:57 Bronsa: bbloom: sorry, internet connection died

20:57 bbloom: Bronsa: what did you get last?

20:58 Bronsa: or check logs :-P

20:59 timvisher: ah hah. there is apparently an :nrepl configuration knob in ring nowadays. looks like i can just use that.

20:59 bbloom: Bronsa: lmk when you're caught up :-)

21:03 Bronsa: in short, peephole optimizations can be implemented as mapcat-state with reducers & should perform quite well. you can use flatten on the source data, map-state and mapcat-state for optimization passes, then each at the end to call -exec

21:03 Bronsa: https://github.com/brandonbloom/fipp/blob/master/src/fipp/printer.clj for an example

21:04 Bronsa: anyway, i'm curious how a doseq/emit works without the omit? phase. if that's any faster than all the concats

21:05 Bronsa: bbloom: ok, I see what you mean, that's an interesting approach that I didn't consider

21:06 bbloom: Bronsa: can do much faster too if you give up on the pretense of being functional/pure and expose a "send to next pass" function

21:07 Bronsa: which is basically how reducers work internally anyway

21:11 Bronsa: bbloom: I don't have much time in the next few days but I'll think about it & try something out. I like the idea & I can see how it could simplify/speedup things

21:14 bbloom: Bronsa: cool. lmk if i can help

21:18 timvisher: would anyone else expect route params with + in them to have the + be converted to a ` ` character? it seems upgrading ring has stopped that from working as well.

22:34 akurilin: Random question: I'm trying to prevent double-submission of data on my ring app by storing a client-given UUID in redis and checking if it already exists in the application. Prob. of course is that fetch and check is not exactly thread-safe. I could either use redis' transactions or I could use an agent in clojure to something similar.

22:34 Should I prefer one or the other?

22:35 rhg135: I'd say do what you know best

22:39 brehaut: akurilin: any reason you cant use the common trick of doing returning a redirect to the same url?

22:40 akurilin: brehaut: do you 302 on a POST kind of thing?

22:40 brehaut: right

22:41 akurilin: In my case this is an iOS app callign into the API, it doesn't really speak redirects.

22:41 brehaut: ah. thats painful

22:41 akurilin: What is speaks very well is submitting shit twice :)

22:42 brehaut: haha

22:42 akurilin: Uhm doesn't look like Carmine does transactions.

22:42 brehaut: and you dont have control over the code to stop it there?

22:43 akurilin: brehaut: I don't because it's the hand of users for now and it might take months before they update versions.

22:43 brehaut: ah :/

22:43 its not a restful api is it?

22:43 akurilin: It's REST-style

22:44 No HATEOAS or anything of that genre.

22:44 brehaut: yeah

22:45 anyway, yeah you want some sort of transactional mechanism for serialize access to the critical region on a per client basis

22:45 akurilin: Yessir.

22:45 I was debating between agents and redis transactions.

22:45 brehaut: agents are async so i dont think thats appropriate

22:46 because then it wont occur within the same thread as the HTTP response

22:46 akurilin: That's a fair point.

22:46 brehaut: transactional redis would probably work fine

22:46 though ive not used it myself

22:48 akurilin: Sounds good, let me try that.

22:48 hiredman: I am just watching a video of a aphyr talk, seeing the word "transactional" just makes me wince now

22:49 brehaut: really?

22:49 akurilin: From a sanity standpoint, if I were to make POSTs idempotent for this one case, I should probably still return a 2xx on the ones that get NOOPed, right?

22:49 brehaut: sure

22:49 if its idempotent then its correct to post back the same thing multiple times

22:50 anyway i need to empty a garden shed

22:50 akurilin: That and I just don't know what's going to happen on the client if I 4xx :P Thousands of iOS apps dying at once.

23:10 fowlslegs: (loop [result [] x 1 y 5]

23:10 (if (zero? y)

23:10 result

23:11 Sorry that was a mistake

23:13 Can someone tell me why I'm getting a exception from this http://paste.debian.net/79142/ ?

23:16 ,(loop [result [] x 1] (recur (conj result x) (+ x (last result))))

23:16 clojurebot: #<NullPointerException java.lang.NullPointerException>

23:22 quizdr: ,(last [])

23:22 clojurebot: nil

23:22 quizdr: ( + 1 nil)

23:22 ,(+ 1 nil)

23:22 clojurebot: #<NullPointerException java.lang.NullPointerException>

23:23 quizdr: fowlslegs there you go ^

23:23 first iteration of loop, the last of result is nil

23:31 technomancy: akurilin: it depends on whether you are load balancing among several server processes

23:31 if so you're kinda forced to do it in the DB

23:35 ssafejava: clojurebot: botsnack

23:35 clojurebot: Thanks, but I prefer chocolate

23:37 akurilin: technomancy: from what I can tell, and I don't have too much redis experience so far, I can't actually do any sort fo complex operations on redis itself unless I were to write a sproc with LUA in it. As in, if I want to do "does key exist, does its val match what I see, otherwise update it" atomically.

23:37 technomancy: and yes what you said makes complete sense, I could do the above by serializing in clojure, but that'd fall flat on its face in case of multiple instances of the app

23:38 at that point I'd have to use stored procedures.

23:39 I'm semi-tempted to do this all in clojure and just never expire the keys, since there's a reasonable upper bound for now

23:40 I mean, just have a map in clojure and swap it, since for now it's only one server.

23:40 technomancy: just depends how long it will stay that way

23:40 akurilin: technomancy: do you see options outside of sprocs for a multi-server scenario?

23:41 or am I correctly reading this?

23:41 bbloom: akurilin: do you have a rough idea of volume of data and traffic?

23:41 akurilin: Yeah. It's low for now.

23:42 bbloom: akurilin: and you plan is redis plus postgres? or just redis or what?

23:42 technomancy: how long is "for now"?

23:42 akurilin: The only reason why I wanted redis was to expire keys when they get old, no other benefit really.

23:42 bbloom: akurilin: do you need that data to be durable?

23:42 akurilin: But that's also a premature optimization.

23:43 So essentially the situation is: I want to prevent a double-POST based on who does it and what data is in it. I want to keep when, who and what was POSTed for up to 5 mins to prevent double-submissions.

23:43 bbloom: you can expire stuff in postgres too. just run a cron job w/ a query :-P

23:44 if your planned volume is sub a few thousand simultaneous users, just do http://www.brandonbloom.name/blog/2013/06/26/slurp-and-spit/

23:44 technomancy: and you can't use a user-generated UUID as a primary key?

23:44 akurilin: technomancy: not right away because those iOS clients that are makign teh POST will take months to update

23:45 If they were web clients I'd have updated their logic in no time.

23:45 But with the fact that you're going through app stores and they're K-12 schools, they might be 6mos behind the latest verison.

23:45 (which is kind of atrocious, but what you going to do)

23:46 bbloom: I'll check that link out, thank you!

23:51 bbloom: that's a cool trick!!

23:51 bbloom: akurilin: the only trick is knowing when to go back to basics :-)

23:51 akurilin: I like the part where you make sure the file doesn't get corrupted, that's pretty nifty

23:51 In my case I don't need durability, but that's super handy for when I do.

23:51 I think raynes also made a lib for making temp files

23:51 so the two can probably work in tandem

23:52 bbloom: akurilin: if you don't need durability, don't bring postgres or redis in to it

23:52 akurilin: just use memory

23:52 akurilin: bbloom: again, I just wanted to feel good about old keys not staying in forever, but that's also not a big deal at this point

23:52 someone write an expiring thread-safe map in clo9jure

23:52 bbloom: akurilin: just run a cleanup task in a timer

23:53 just use java.util.Timer

23:54 or now i guess ScheduledThreadPoolExecutor :-P

23:56 akurilin: I think mikera was recommending something super basic like (future (loop [] (do-something) (Thread/sleep 20) (when (game-still-running) (recur))))

23:56 bbloom: yeah, that works too lol

23:57 akurilin: There's also TimerTask

23:57 I give up on knowing what the java libs offer at this point

23:57 I'm sure there's practically everything you'd ever want if you can stomach the naming :P

23:58 bbloom: pretty much

23:58 akurilin: bbloom: would it be heresy to dump that future straight into the namespace as opposed to having it in a "init" function somewhere?

23:58 Trying to think of all the ways that'd mess with the state.

23:59 On reloads etc.

23:59 I imagine reloading the namespace would generate a new future each time

23:59 so that'd suck.

23:59 bbloom: akurilin: sure, so what you do is you capture the function in a local and check if it changed, if so, you abort

Logging service provided by n01se.net