#clojure log - Aug 23 2011

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

0:01 icey: thanks ibdknox, technomancy, jli :) this gives me a good starting point

0:02 ibdknox: jli, icey: yeah, split the html into two parts, the "layout" and then the content

0:02 you share code between pages

0:02 it ends up much cleaner

0:02 smaller

0:05 pdk``: jli take a look at graham's lisp book and practical common lisp

0:06 they always have an example chapter stuffed in the back talking about writing a mini language to produce html from s expressions as a handful of macros

0:06 icey: ibdknox, jli: good feedback - i started using layouts recently once i transitioned to noir (although i am still making many of the mistakes mentioned here in my newer code - this code is from a few weeks ago)

0:07 jli: pdk``: hm?

0:07 pdk``: http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-interpreter.html for example

0:07 talks about writing a set of macros so you can write your page code in a lispy structure and have it spit out html from that

0:07 jli: he's already using hiccup (I think?) - it's just that the layout stuff is together with code for getting data

0:07 scottj: Does every loop/recur involve a function invoke?

0:08 is each recur a function invoke?

0:08 pdk``: you can use recur just to restart the loop it's in iirc

0:10 ibdknox: icey: if you're using noir, you should basically never return a map

0:11 dnolen: scottj: loop/recur is efficient, no more overhead than a for loop in Java.

0:13 icey: ibdknox: i'm a little better now (although I'm still not using :only here) - this is how i'm using noir: https://gist.github.com/1164329

0:14 (ignore the extra includes ;))

0:14 ibdknox: icey: the only thing I'd do is put all those links into collection

0:15 icey: and then map over them

0:16 basically anytime you're doing a list with similar items, you should split that out into a partial and map the partial over the collection :)

0:16 icey: ibdknox: hm okay. you have an example of that on one of the noir webpages actually

0:32 * srid is being confused with weird app engine errors; maybe best to run his web app elsewhere on a pure PaaS

0:35 scottj: dnolen: ok I'd heard that. I copied the scala version of that stupid josephus benchmark but was still about 5x of it and almost all the time was in my main function's invoke, and I had 2 loop w/ recurs in it so I thought maybe that was it

0:36 srid: nope, a fix is available at http://stackoverflow.com/questions/6182626

0:37 replaca: dnolen: loved your ClojureNYC talk (oddly it got me thinking about core.logic more than match, but hey)

0:38 dnolen: did you propose a conj talk?

0:38 dnolen: scottj: that's the most pointless benchmark ever IMO. the requirement to have a growable array is easily done by just writing a C++ vector like abstraction over Java primitive arrays.

0:39 replaca: interesting that the talk made you think of core.logic more.

0:39 replaca: yes, I pitched a talk on core.logic and on predicate dispatch.

0:40 replaca: dnolen: well, I just began to think of cases where relationships between elements matter in a way that seemed to be beyond match but in the wheelhouse of logic techniques

0:41 dnolen: mostly around producing explanations of how certain things change over time

0:41 which gets really ugly in normal code

0:42 dnolen: replaca: definitely. where predicate dispatch ends core.logic begins. and vice versa.

0:42 replaca: dnolen: yeah, it's like a numeric stack of logic

0:43 but I haven't done any logic programming since college, so I'm having to rekearn a lot

0:43 *relearn

0:44 if I really get something interesting, maybe I'll do a lightening talk about it

0:44 dnolen: I actually started up the predicate dispatch stuff because I wanted a pattern matcher to write the nominal logic version of miniKanren :)

0:44 of course I got carried away.

0:44 jli: replaca: where you at clojurenyc?

0:45 replaca: jli: no, I watched it on TV :) (also known as vimeo)

0:45 I'm in SF

0:45 scottj: dnolen: I wonder if the benchmark is really only measuring function invoke time. the main function only runs for 0.0067 millis each iteration

0:46 dnolen: scottj: the benchmarks measures array operations. that's about it as far as I can tell.

0:47 scottj: all the other langs benchmarked have mutable arrays. the OP had the audacity to post Clojure solutions that converted to seqs. I was going to respond but I lost interest, what's the point when the benchmark is that idiotic ?

0:52 jli: do you get an ack from rich when he gets your contributor agreement?

0:52 dnolen: jli: I think Clojure/core handles it now, and your name just appears on the list.

0:53 jli: okay, cool

0:54 dnolen: scottj: if you're doing it just for self education. Write a deftype over Java arrays that implements a push / pop interface that grows at the boundaries with System/arraycopy

0:54 it's will be absurdly fast.

0:57 scottj: dnolen: see I don't think it's the datastructure that matters bc scala version uses ArrayBuffer w/o primitives I think and even a java version using ArrayList is like 10x my clojure version that uses ArrayList

0:59 dnolen: scottj: what does your implementation look like? and what version of Clojure? *unchecked-math* etc.

1:07 scottj: dnolen: https://gist.github.com/1164383 clojure 1.3.0-beta1, just turned on *unchecked-math* it made very little diff

1:07 no reflection warnings

1:08 -server makes very little diff on this benchmark

1:08 dnolen: scottj: how long does it take on your machine?

1:09 scottj: timings at bottom, 8 seconds for a million iterations

1:09 in clojure, 0.8 for java

1:11 srid: is it not possible to get compojure automatically convert types of route arguments? example -- in ` (GET ["/:site/:tag/:n", ...` I want the `n` to be of integer type.

1:11 else, I have to manually Interger.parseInt it in all the route mappings.

1:12 dnolen: scottj: your using vectors for no reason

1:13 scottj: dnolen: the destructing part? yeah just noticed that when profiling

1:13 dnolen: vector instantiation, destructuring

1:13 you're paying for instantiations too

1:14 scottj: I'll try getting rid of it but I found in another version I have that's faster tha nthis that that amount of destructuring doesn't impact total time much

1:15 dnolen: scottj: you can't put primitives in vectors

1:15 so you've got boxing

1:15 you've got boxing so JVM can't inline

1:17 replaca: dnolen: has core.logic been pushed anywhere or do I have to build from source?

1:17 dnolen: replaca: hudson

1:17 org.clojure/core.logic "0.6.3" I think.

1:17 replaca: what's the latest version?

1:17 michaelr525: hey!

1:17 scottj: dnolen: I've got ArrayLists, isn't that itself going to prevent inlining?

1:18 replaca: cool, thanks!

1:19 dnolen: scottj: Just by glancing at your code I can see it's not going to be very fast.

1:21 scottj: there's no arithmetic on the contents of ArrayList so boxing is irrelevant there.

1:35 scottj: where's the Java ArrayList version?

1:37 scottj: dnolen: in that gist, second file

1:39 khaliG: I start lein swank from a screen session, and sometimes when something goes wrong i'll take a look at the terminal but i can't scroll up to see a complete stacktrace. Is there a fix for this annoying problem? :)

1:40 scottj: khaliG: screen has scrolling, C-a [ then pageup

1:40 patchwork: hey all, trying to get the whole swank-clj setup going and running into a problem with the package manager, marmalade?

1:41 I installed all of the slime and swank packages from M-x package-list-packages

1:41 but when I do slime-connect I get:

1:41 Symbol's value as variable is void: slime-clj

1:41 khaliG: scottj, thank you, i'll store that note somewhere handy for next time

1:42 patchwork: slime-clj-1.6.0 is in my elpa directory

1:42 and it finds the other packages fine that are in there

1:42 but this one fails for some reason?

1:42 anyone have any idea where to start?

1:43 I was under the impression that because it is a package manager I don't need to require anything from my .emacs

1:43 (besides the package.el of course)

1:44 hiredman: patchwork: you want swank-clojure

1:45 ~swank-clojure

1:45 clojurebot: see swank

1:45 hiredman: ~swank

1:45 clojurebot: swank is try the readme. seriously.

1:45 hiredman: ugh

1:45 ~google swank-clojure

1:45 clojurebot: First, out of 1030 results is:

1:45 technomancy/swank-clojure - GitHub

1:45 https://github.com/technomancy/swank-clojure

1:45 hiredman: ^- forget swank-clj

1:45 if you follow the instructions in the readme there you will be all set

1:46 ~blog posts

1:46 clojurebot: make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive

1:46 hiredman: ~blogs

1:46 clojurebot: make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive

1:46 hiredman: bleh

1:47 replaca: dnolen: ever seen "IllegalArgumentException No value supplied for key: true clojure.lang.PersistentHashMap.createWithCheck (PersistentHashMap.java:89)" when loading c.c.l.prelude?

1:47 patchwork: hiredman: interesting, those are the instructions I was trying to follow!

1:47 replaca: it works for me from the slime repl, but I can't load from the ns directive in my file

1:47 patchwork: hiredman: possibly, I don't need to install the slime stuff, only clojure-mode?

1:48 hiredman: patchwork: right, swank-clj is not swank-clojure

1:48 dnolen: replaca: Clojure version?

1:48 replaca: 1.3 beta1

1:48 hiredman: patchwork: you obviously did not follow the readme

1:48 patchwork: hiredman: gotcha, strange

1:48 hiredman: under "usage" there are three lines, nothing that mentions slime

1:49 patchwork: hiredman: I installed marmalade, then tried to install all the packages from there. I thought they were the same thing

1:49 hiredman: I will try your suggestion

1:49 dnolen: replaca: no, sounds really weird. can you open a ticket?

1:50 replaca: dnolen: I think it was pilot error with my :use

1:50 dnolen: replaca: ok

1:50 replaca: dnolen: when I break it up differently, it works fine

1:51 dnolen: the problem of looking at something new, is you never know where you're config problems are

1:53 patchwork: hiredman: okay, followed the readme precisely

1:54 M-x clojure-jack-in now returns:

1:54 Process swank exited abnormally with code 127

1:54 /bin/bash: lein: command not found


1:54 I have lein installed however

1:54 what path is it using?

1:54 hiredman: because you are on osx and osx doesn't source dot files so emacs doesn't have the PATH setup

1:55 patchwork: so...

1:55 get a new computer?

1:55 hiredman: you can use setenv to set your PATH in your emacs dot files

1:55 patchwork: hiredman: aha nice, never had to do that before

1:55 hiredman: (setenv "PATH" "/sbin:/Users/hiredman/bin:/usr/local/bin:/usr/local/sbin/:/Users/hiredman/apache-maven/bin:/usr/bin:/bin:/usr/sbin:/usr/local/git/bin:/usr/X11/bin:/usr/games")

1:58 dnolen: scottj: here's a version that runs in 2.8s on my Machine, the Java takes 1s, about to post some really ugly Clojure in a second which should be identical.

1:58 https://gist.github.com/1164447

1:59 patchwork: hiredman: PATH is set, now I get:

1:59 error in process filter: Symbol's variable is void: Process

1:59 (after all kinds of things happen in *swank*)

1:59 hiredman: what version of emacs?

1:59 patchwork: 23

1:59 hiredman: hmmm

2:00 patchwork: the gnu version

2:02 hiredman: have you tried restarting emacs?

2:03 replaca: b

2:08 dnolen: as promised Josephus in Clojure with identical Java performance, https://gist.github.com/1164458

2:09 scottj: ^

2:53 michaelr525: yo!

2:55 so, I've used compojure once. should I use anything else for a web framework?

2:55 what would you recommend?

3:12 scottj: khaliG: I had this screen stuck on scroll since I answered your question and I've been wondering why no one's said anything :)

3:13 khaliG: scottj, haha :)

5:11 slilo: >/part

5:16 agz: hey guys, http,agent is not working for me:

5:16 (http/string (http/http-agent "http://www.google.com"))

5:17 is not responding, the agent never finishes

5:17 (http/done? (http/http-agent "http://www.google.com")) is always false

5:18 anyone?

5:18 clojurebot: Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help.

5:21 michaelr525: agz: i'm not familiar with http-agent, but

5:21 I'm using fetcher to fetch some html pages

5:21 And it's greate

5:21 greate

5:21 great

5:23 agz: thx, goin try it

5:26 in project.clj I added [fetcher "0.0.5-SNAPSHOT"] - and got error

5:26 Caused by: Unable to resolve artifact: Missing:

5:26 ----------

5:26 1) fetcher:fetcher:jar:0.0.5-SNAPSHOT

5:28 michaelr525: agz: go to github, get this project and run "lein install", it will print errors for all dependencies it needs, go to github and get them all and run "lein install" in each one of them, then go back to fetcher and run "lein install"

5:29 agz: :michaelr525: you mean download the source, and run lein install in the library?

5:29 in the directory mean

5:33 michaelr525: yep

5:33 agz: you have the download button at the top right

5:34 or of course you could use git :)

5:45 agz: yeah I'm noobie :), I got progress, but:

5:46 getwoven-plumbing needs clj-json-0.3.2

5:47 I installed that but plumbing still doesn't see it

5:48 michaelr525: hmm

5:49 agz: I copied the compiled clj-json jar to the /lib of the plumbing

5:49 not work - that should work?

5:50 michaelr525: are you sure that "lein install" installs the jar into your repository?

5:50 the clj-json jar

5:51 what is the error message when you try to install plumbing?

5:51 agz: ate@mate-laptop:~/Desktop/downloads/firefox/mmcgrana-clj-json-6ac05dc$ lein install

5:51 Compiling 1 source file to /home/mate/Desktop/downloads/firefox/mmcgrana-clj-json-6ac05dc/classes

5:51 Copying 3 files to /home/mate/Desktop/downloads/firefox/mmcgrana-clj-json-6ac05dc/lib

5:51 Copying 4 files to /home/mate/Desktop/downloads/firefox/mmcgrana-clj-json-6ac05dc/lib/dev

5:51 Created /home/mate/Desktop/downloads/firefox/mmcgrana-clj-json-6ac05dc/clj-json-0.3.2.jar

5:51 Wrote pom.xml

5:51 [INFO] Installing /home/mate/Desktop/downloads/firefox/mmcgrana-clj-json-6ac05dc/clj-json-0.3.2.jar to /home/mate/.m2/repository/clj-json/clj-json/0.3.2/clj-json-0.3.2.jar

5:51 this is install

5:51 .

5:51 .

5:51 .I mean the clj-json

5:52 Exception in thread "main" Unable to resolve artifact: Missing:

5:52 ----------

5:52 1) woven:clj-json:jar:0.3.2-SNAPSHOT

5:52 Try downloading the file manually from the project website.

5:52 Then, install it using the command:

5:52 mvn install:install-file -DgroupId=woven -DartifactId=clj-json -Dversion=0.3.2-SNAPSHOT -Dpackaging=jar -Dfile=/path/to/file

5:52 this is the error of the plumbing lib

5:52 * babilen recommends a pastebin

5:52 agz: okay

5:52 sry

5:53 michaelr525: seems like it looks for -SNAPSHOT version

5:54 check github, maybe it's there

5:54 agz: http://pastebin.com/bG6hRB2S

5:54 ohh

5:55 the snapshot is already 0.4.0

5:55 michaelr525: take everything from here: https://github.com/getwoven

5:57 agz: btw how can I check out the snapshot with git??

5:57 lazybot: agz: Uh, no. Why would you even ask?

5:57 agz: yes :)

6:25 uhm I managed to lein install a clj-json.4.0.0 but plumber needs 0.3.2-SNAPSHOT

6:26 I tried to change it in the plumbers/project.clj to 4.0.0 from 3.2 but it had no effect

6:29 okay, maybe wrote wrong version number - it works now

6:57 * opqdonut bangs head on desk

6:57 opqdonut: _never_ make a record with a field named size

6:58 (and then try to access it with (.size thing))

7:11 michaelr525: opqdonut: why not?

7:15 opqdonut: michaelr525: go ahead, try it :)

7:16 michaelr525: :)

7:36 anyone knows of a jquery autocomplete plugin that mimicks as much of google instant?

7:41 Scorchin: What's the generic way to find out what kind of data structure you have? Looking for something similar to "map?" or "list?"

7:41 joegallo: http://docs.jquery.com/UI/Autocomplete

7:46 michaelr525: joegallo: not similar enough :)

7:47 actually i don't mind if it's not jquery

8:01 mbac: what's the authoritative zero-to-working-with-clojure-in-emacs howto?

8:01 google betrays

8:01 Pisketti: I'd like to know that as well ;)

8:01 thorwil: Scorchin: type

8:02 Scorchin: thorwil: thanks

8:03 mbac: clues indicate that this involves lein

8:04 Scorchin: another question, why does my "type" change from a vector to a named type when I wrap it in a (defn easy-name [PersistentVector in here]) ? Is there a more idiomatic way to do this?

8:17 If you have a vector of maps, how do you "remove" keys from the maps that the vector stores?

8:19 cemerick: Scorchin: You could use a zipper if appropriate, or there's a dissoc-in fn in old-contrib you can swipe: https://github.com/clojure/clojure-contrib/blob/b8d2743d3a89e13fc9deb2844ca2167b34aaa9b6/src/main/clojure/clojure/contrib/core.clj#L57

8:20 opqdonut: I'd just do (vec (map #(dissoc % :key) vector-of-maps))

8:20 chouser: ouch

8:20 opqdonut: oh okay, if you want to edit just one of the maps dissoc-in is pretty much the right thing

8:21 cemerick: opqdonut: good luck with that ;-)

8:22 opqdonut: hmm?

8:23 cemerick: I was commenting on the (vec (map …)) suggestion. That approach will hurt bad if the vector is large.

8:23 opqdonut: would (into [] ...) be faster?

8:23 cemerick: Or, even if it's small, and modified a bunch.

8:24 No. It's a full copy in any case.

8:24 opqdonut: well if he wants to update every map in the vector...

8:24 then that's inevitable

8:24 Scorchin: opqdonut: actually, that's pretty much what I wanted. Thanks!

8:24 What's the counter to that, where you just want to get a single key from each?

8:25 opqdonut: I'll leave that as an exercise

8:25 hint: use map

8:25 Scorchin: okay, thanks

8:28 is it just (vec (map #(get % :age) vector-of-maps)) ?

8:28 or is there a better way to do it?

8:28 cemerick: opqdonut: Yeah, in that case, if thing just absolutely have to be in a vector, then there's no choice. Most of the time, vectors are just not necessary tho.

8:28 opqdonut: that's it

8:29 cemerick: agreed

8:29 cemerick: Scorchin: (map :age vector-of-maps) is sufficient

8:31 Scorchin: cemerick: thanks, that's much cleaner

8:32 chouser: cemerick: ^{:line 42 :k :v} (quote (foo))

8:33 * cemerick can tell that chouser is trying to tell him something, but can't quite tell what…

8:33 cemerick: chouser: Some of Rich may have rubbed off on you, 'lo these many years. ;-)

8:34 (meta ^{:line 42 :k :v} (quote (foo))) => {:line 1}, which is (thankfully) consistent with the third example in the email

8:35 Scorchin: So lets say that I've now trimmed my crazy vector-of-maps into something easier to work with. I know what unique values exist with (distinct trimmed-vector-of-maps) however I now want to count how many times each one of those occurs to a map. Where's the best place to look at in the docs for that kind of operation?

8:35 If I was doing it in python, I'd just use a for loop and increment a counter within a dict, not so sure with clojure

8:36 chouser: cemerick: heh, sorry. '(foo) is read as (quote (foo)), so it's that outer list that's getting your metadata

8:36 opqdonut: Scorchin: have a look at group

8:36 sorry, group-by

8:37 cemerick: !! :-(

8:37 (meta (quote ^{:line 42 :k :v} (foo))) => {:k :v, :line 1}

8:37 chouser: thanks.

8:37 * cemerick facepalm

8:39 Scorchin: opqdonut: I've currently got a list of ages, which I want to make a normal distribution out of. (group-by (distinct ages) ages) doesn't seem to work

8:39 Is this because I need to make keys out of the distinct ages?

8:41 actually, looks like incanter might do what I need, will have a look in there :)

8:44 raek: Scorchin: you can use the 'frequencies' function to count how many times each element occurs in a sequence

8:44 opqdonut: Scorchin: group-by takes a function as its first argument, you might want to use = or something like #(* 10 (Math/floor (/ % 10)))

8:44 (the latter gives you bins of size 10)

8:46 Scorchin: oh, that's slick, I think I love clojure

8:46 ugh, but now I need to learn all these helper functions :/

8:46 opqdonut: but incanter probably offers lots of stuff like this

8:49 chouser: Scorchin: you don't have to learn them cold. You can do like the rest of us did and write the ones you need.

8:49 Just don't forget to ask "is there something like this already" so someone can point out its name. :-)

8:49 Scorchin: :D

8:49 yeah, I get that

8:50 it's just a shame that the repl isn't more playful like node or python

8:50 chouser: I think frequencies in particular I wrote several times before it was added to core

8:50 as did many others

8:53 cemerick: Scorchin: "playful"?

8:54 Scorchin: yeah, like the ability to just prod things to find out more

8:54 like in node how you can do var. (hit tab) and then see what you could do

8:55 cemerick: Clojure doesn't bind functions up with objects or values. That's integral to composability.

8:56 Beyond that, there's tonnes of ways to introspect the environment and see what's available.

8:57 joly: ,(apropos "count")

8:57 clojurebot: (*initial-report-counters* *report-counters* inc-report-counter ref-history-count counted? ...)

8:57 theignorati: is there a better way of doing this: (list (.getCommand m) (.getChannel m) (.getData1 m) (.getData2 m))?

8:57 TimMc: ,(apropos "^count")

8:57 clojurebot: ()

8:57 TimMc: hrmf

8:58 cemerick: ,(apropos #"^count")

8:58 clojurebot: (counted? count)

8:58 TimMc: yay

8:58 joly: I like find-doc as well

8:58 * cemerick had totally forgotten that apropos was there

8:59 cemerick: Quite the anachronism.

8:59 chouser: theignorati: hm, maybe (map (bean m) [:command :channel :data1 :data2])

9:02 theignorati: nope

9:03 vijaykiran: theignorati: you can use juxt ?

9:04 ,(doc juxt)

9:04 clojurebot: "([f] [f g] [f g h] [f g h & fs]); Alpha - name subject to change. Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]"

9:04 chouser: I don't think juxt will work because those are methods not functions

9:04 theignorati: bean doesn't work on that object?

9:04 theignorati: no

9:05 chouser: theignorati: Then I think you're done. A macro might help, but I don't think there's any in core that will help.

9:06 theignorati: and even if you wrote one yourself it wouldn't be any more efficient than what you have, and hardly any more succinct.

9:08 theignorati: ok

9:08 thanks

9:10 Scorchin: I currently have a sequence of strings: ("1" "3" "4" "s"). How do I strip out the non-integers and convert the actual integers into ints?

9:11 TimMc: theignorati: What you have currently is also pretty readable.

9:15 chouser: Scorchin: (->> ["1" "3" "4" "s"] (filter #(re-matches #"\d+" %)) (map #(Integer/parseInt %)))

9:15 agz: Schorchin: (map load-string (filter #(re-find #"[0-9]+" %) ["1" "2" "3" "s" "S"]))

9:15 pff :)

9:15 chouser: :-)

9:16 yours is shorter!

9:16 agz: yours more efficient! :)

9:16 Scorchin: :0

9:16 chouser: read-string would be a bit better than load-string

9:17 agz: chouser: yep, I though there is a better one :)

9:18 chouser: ,(re-find #"[0-9]+" "123xyz")

9:18 clojurebot: "123"

9:18 chouser: ,(read-string "123xyz")

9:18 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 123xyz>

9:18 chouser: ,(Integer/parseInt "123xyz")

9:18 clojurebot: #<NumberFormatException java.lang.NumberFormatException: For input string: "123xyz">

9:18 * cemerick mumbles something about turning off *read-eval*

9:19 chouser: ,(read-string "#=(java.lang.System/exit)")

9:19 clojurebot: #<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>

9:20 cemerick: "The sandboxes turn it off; it's not so hard for everyone else to as well!" </snark>

9:25 babilen: How would I find numbers in other scripts? E.g. -- (re-find #"????" "123xyz二四五") → "123二四五" ?

9:25 Scorchin: chouser, agz: that was really helpful, thanks. Although I'm now trying to work out how it works :/

9:26 michaelr525: how do you people work with git from emacs?

9:27 mprentice: michaelr525: magit

9:28 michaelr525: thanks, will check

9:28 raek: babilen: see \p in http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html

9:29 michaelr525: and what about an integrated "shell" when working with emacs on windows?

9:29 mprentice: michaelr525: i have magit-status as "C-c g"

9:30 michaelr525: mprentice: hmm?

9:30 mprentice: michaelr525: that was in reference to magit, not your shell question

9:31 babilen: raek: Anything in particular you are thinking about? \p{Digit} is (as stated) us-ascii only

9:31 mprentice: michaelr525: on mine, M-x shell brings up an interface to Windows Powershell, but i don't use it that way so i can't help you much

9:31 raek: babilen: sorry, I was thinking about the unicode category feature (which also uses \p)

9:32 babilen: raek: No problem. :)

9:32 michaelr525: mprentice: ok thanks. why did you map C-c g to magit-status?

9:33 mprentice: michaelr525: magit works in a buffer brought up with magit-status. it's not an interface to the emacs version stuff.

9:33 michaelr525: ah, I see!

9:33 will have to try that

9:34 mprentice: michaelr525: when i tried it git-vcs or whatever it was called didn't work out of the box, and i didn't have the patience to set it up :P

9:35 raek: babilen: it looks like 二 has the unicode category "OTHER_LETTER" and is not considered a digit...

9:37 I was expecting that the Nd (decimal digit number) category would work for CJK numerals too

9:39 babilen: see the last table: http://www.fileformat.info/info/unicode/char/4e8c/index.htm

9:41 ,(re-find #"\p{Nd}+" "123١٢٣一二三")

9:41 clojurebot: "123١٢٣"

9:41 babilen: raek: I have to confess that I am mildly surprised

9:42 raek: I know that this is far from being a Clojure issue and thank you for giving an example with other scripts, but seriously: wtf! :)

9:43 pjstadig: the goal of Unicode is to have a way of encoding glyphs, it's goals do not include encoding semantic meaning

9:43 except where it's necessary for backwards compatibility with existing encodings

9:45 babilen: pjstadig: Yes - but that means that if you want to find all numbers in a text you *have* to hardcode all characters that denote numerals for every single script.

9:47 michaelr525: mprentice: i've staged some files but hitting c in the staging buffer asks me Nothing changed. Commit all unstaged changes?

9:47 wtf?

9:49 raek: also, different cultures have different rules for what a letter is. maybe there isn't much disagreement on what is a numeral, but in that case this would be one of few things in unicode whose rules everyone agree upon

9:51 michaelr525: mprentice: Sorry, it says: Nothing staged. Commit all unstaged changes?

9:52 but i have 4 staged files right here in the buffer

10:00 mprentice: michaelr525: strange. i'm not familiar enough to know why it would do that :/

10:03 babilen: raek, pjstadig: Well, I have to dive deeper into this -- Seems to be either a bug in the unihan database or java's regex implementation. (IMHO "(?u)\d" *should* match "三") -- I'll take it to #unicode and #java. Thanks so far :)

10:05 cemerick: babilen: \d is equivalent to [0-9], and the 'u' flag only impacts case-insensitivity. Not sure why \d would match cn characters in any case.

10:08 babilen: cemerick: Forgive me -- I am from a Python background and (?u) behaves differently there -- All I meant was "There should be a character class (i.e. Digit) that matches 三

10:08 "

10:10 cemerick: babilen: Except that there isn't. :-)

10:11 There are multiple "number systems" in CJK AFAIK. There's 一, but there's also…

10:11 壹 (had to hit wikipedia for that one)

10:12 babilen: Why not just use your own character class? [一二三…]

10:12 babilen: Yes, I know -- but all of them have kPrimaryNumeric set -- It seems to be specific to unihan -- Note http://www.unicode.org/reports/tr44/#Numeric_Value and http://www.unicode.org/reports/tr44/#Numeric_Type_Han

10:13 cemerick: I was hoping to find a solution for *all* scripts as hardcoding these will mean a lot of work for me.

10:14 raek: babilen: maybe ICU4J is useful for you: http://site.icu-project.org/

10:14 chouser: babilen: you only want to match numbers, or also get their values?

10:14 raek: (in case Java misses some features)

10:15 babilen: chouser: Right now I only want to match them, converting them to their kPrimaryValue would be nice to have, but is not necessary right now.

10:15 raek: I'll take a look.

10:15 I'm working in cross-lingual natural language processing and *have* to deal with different scripts/languages

10:25 michaelr525: heya!

11:06 Netpilgrim: Hi. Could someone be so kind to critique my code at https://gist.github.com/1165353? It's working, am just wondering if it could be made more idiomatic.

11:09 Also coming from Java I'm still not too comfortable without types. Is there a way to at least make sure that a function parameter is e.g. a two-dimensional array/seq?

11:09 raek: Netpilgrim: use hyphens instead of underscores in names. #(length-counts %) --> length-counts. (map (fn [x] ...) coll) --> (for [x coll] ...)

11:10 don't use ==, use =

11:10 Netpilgrim: OK. Thanks.

11:11 raek: I thought == would be more effizient with numbers.

11:11 s/effizient/efficient/

11:11 lazybot: <Netpilgrim> raek: I thought == would be more efficient with numbers.

11:12 raek: Netpilgrim: also, find-paths can probably be implemented by passing the "state" (paths) as a parameter instead of mutating the atom

11:12 it's not very ideomatic to use mutation for computations in clojure

11:13 arohner: Netpilgrim: == is more efficient for numbers. it should be used when you know you're dealing with numbers, and performance is important. (I have no idea whether that applies to your case)

11:13 Netpilgrim: raek: OK, this is probably a big one. I'll try to rewrite the function.

11:14 raek: Can for always be used instead of map? What are the advantages?

11:15 raek: you cannot use for if you want to take from multiple collections in lock step

11:15 for just one coll, you can always use 'for'

11:16 I prefer it since it indents much prettier with bigger expressions

11:17 Netpilgrim: raek: I wasn't too sure about for, map just seemed made for this purpose.

11:19 Is ((set xs) x) the correct way to test if an element part of a seq?

11:19 raek: yes. if you are going to test many times, store (set xs) instead of xs

11:20 Netpilgrim: raek: Ok

11:21 raek: Netpilgrim: yeah, 'map' is the more simple form, and 'for' is syntactic sugar for certain common tasks

11:22 Netpilgrim: But I should be OK if I always use for except when working on multiple collections in parallel?

11:23 raek: yes. but 'map' is probably shorter if you have an existing function instead of an anonymous function

11:24 Netpilgrim: Hm, so it just comes back to “it depends”. :)

11:24 raek: yeah :)

11:24 if you need to write the map expression on more than one line, maybe for looks better

11:26 Netpilgrim: raek: I've just rewritten am_to_al with for and it looks better. I think the fact that the name of the collection comes to the front of the expression improves the readability.

11:28 raek: Hyphens in symbol names look really odd to me but I guess I better keep to the established style.

11:29 raek: Netpilgrim: you could probably implement the adjacency lists as a set of [from to] pairs

11:30 dnolen: refining the pattern match api for arrays and bits, Object Oriented Macros, http://dosync.posterous.com/object-oriented-macros, upvote on HN por favor

11:31 Netpilgrim: raek: But then I couldn't get all children with (adj-lists parent).

11:35 raek: To come back to == and =. What exactly is the difference? == Seems to be only defined for numbers, so I thought it might be more efficient there.

11:37 ambrosebs: I'm having some trouble combining dynamic binding with macros. I don't understand why the last form returns false https://gist.github.com/1165470

11:40 Chousuke: ambrosebs: macro expansion is done at compile time, while the binding happens at runtime

11:41 ambrosebs: Chousuke: cheers, that makes sense.

11:42 Chousuke: if the macro returned the symbol *test1* instead then that would work

11:44 khaliG: hm, using set! i'm getting the error "Can't change/establish root binding of: *foo* with set"

11:45 ambrosebs: Chousuke: the problem I'm trying to solve is wrapping a macro in a `binding` form, which triggers behaviour during macro expansion

11:45 impossible?

11:47 Chousuke: ambrosebs: yeah, that's not really possible

11:48 you could use eval to make something that "works" but I think then you have more problems than you solve :P

11:48 ambrosebs: :)

11:48 I can work around it, but did cause some headaches

11:49 Chousuke: you can use a global bindable variable and set! it though

11:49 ambrosebs: looks like that's the best way

11:49 Chousuke: compilation and execution happens sequentially so if you set! something in a global it will affect macroexpansions later in the code. It's still somewhat hackish though :P

11:50 ambrosebs: the variable activates trace printing and debugging, so it's not that crucial to be fine grained

11:51 although it was a nice-to-have

11:51 possibly :)

11:51 Netpilgrim: raek: I have to leave now. Thanks for your help.

11:52 Chousuke: ambrosebs: yeah, that sounds like something you can just have as a global variable

11:56 raek: Netpilgrim: https://gist.github.com/1165579

11:56 (find-paths without mutation)

11:58 Netpilgrim: yes the adj.list suggestion was not a very good idea :)

11:59 khaliG: am i missing something in using set!? :/

11:59 babilen: And for example: (Python) re.findall(r'(?u)\d+', "123xyz١٢٣二四五") → ['123', '١٢٣'] (Clojure/java) (re-find #"\p{Nd}+" "123١٢٣一二三") → "123١٢٣"

11:59 And for example: (Python) re.findall(r'(?u)\d+', "123xyz١٢٣二四五") → ['123', '١٢٣'] (Clojure/java) (re-find #"\p{Nd}+" "123١٢٣一二三") → "123١٢٣"

11:59 (disregard that ECHAN, sorry)

12:01 raek: Netpilgrim: honestly, I don't really know. = works for everything and I haven't used == myself yet. perhaps it works as java's ==, but only for numbers.

12:01 babilen: so does python have the same problem?

12:02 (also, the clojure version of re.findall would be re-seq)

12:03 Netpilgrim: raek: Thanks for the code. Honestly I don't know why I thought I'd need the atom.

12:04 babilen: raek: hehe, thanks -- Python's "二".isnumeric() → True -- Haven't found a good aequivalent in Java/Clojure yet -- Also Python's regex module is supposed to work better. Am still investigating -- I'll let you know when I'm done.

12:07 pjstadig: babilen: wouldn't something like Character/isDigit be the Java equivalent?

12:07 assuming it wasn't brojen

12:07 er broken

12:08 raek: ,(Character/isDigit \二)

12:08 clojurebot: false

12:08 pjstadig: or you're looking for a way to take a string and say "is this a number (assuming I parsed it")

12:08 babilen: yes ^^^ that is exactly the problem

12:08 pjstadig: That is what I am looking for

12:09 pjstadig: i've never really liked Java for string processing

12:09 raek: at least string are sequences of characters and not bytes :-)

12:09 pjstadig: hehe

12:10 i was going to say python and ruby are better for that, but ruby...hmm

12:10 babilen: So, this is a bug in Java?

12:10 raek: babilen: I think the isDigit property is specified in the unicode standard

12:10 babilen: Well, it looks as if I have to use Python or Perl in that case

12:10 raek: python 3, I hope...

12:10 babilen: sure

12:14 well, isdigit and isnumeric are different .. http://www.unicode.org/reports/tr44/#Numeric_Value and indeed in Python: "二".isdigit() → False -- I am looking for a isnumeric function/method which seems to be missing in Java -- Recipes include Integer.parseInt + catching an exception.

12:15 cemerick: Looks like this Numeric_Value stuff came out in Unicode 5.2.0. (circa 9/2009). Wouldn't say that lack of support for it is a bug.

12:16 raek: babilen: maybe ICU4J provides it

12:16 it is built for these kind of things

12:17 http://www.unicode.org/Public/UNIDATA/UnicodeData.txt the unicode spec says 二 is of type "So", Other Symbol

12:17 (entry for 4E8C)

12:18 babilen: raek: Yes, I still try to understand why 二 is not considered to be a number or Nl (Number/Letter) or whatever ...

12:21 cemerick: babilen: Surely python's .isnumeric isn't what you want. It apparently returns true for 2155 (⅕).

12:23 eyeris: cemerick: why do you consider 1/5 non-numeric?

12:24 babilen: cemerick: I know that I don't understand this as good as I should. But 2155 (⅕) most likely has Numeric_Type=Numeric in http://unicode.org/Public/UNIDATA/UnicodeData.txt with a value of 1/5 and in Python you get "unicodedata.numeric('⅕')" → 0.2

12:24 cemerick: eyeris: babilen was talking about finding digits and integers within strings. I wouldn't think that that would include glyphs that represent one-fifth.

12:25 diogo: Hi. I want to develop in lisp/clojure using vim. I heard about slimv, but I'm unable to install it in my debian.

12:25 babilen: cemerick: I would settle for that -- It just means that I need additional tests (i.e. kPrimaryNumeric is an integer or so)

12:25 diogo: Anyone has an how-to install slimv on debian/linux

12:25 or any kind of troubleshooting for slimv?

12:26 eyeris: diogo: I don't know anything about slimv, but there is a VimClojure plugin on vim.sf.net

12:27 sjl: diogo: Slimv seems to work great with Pathogen on OS X -- there shouldn't be any problems on Debian.

12:28 babilen: diogo: I would recommend vimclojure -- I use slimv only for paredit -- you can see my vimrc on https://github.com/babilen/dotfiles/blob/master/vim/vimrc -- I can walk you through the installation later, but you will most likely want to use http://clojars.org/org.clojars.oskarkv/lein-vimclojure (leiningen plugin) to start the server. See https://bitbucket.org/kotarak/vimclojure for further information on vimclojure

12:28 cemerick: babilen: It seems like you really need to determine *what you want*, instead of looking/hoping for someone else's categorization to suit your requirements. In the end, you may just find it easier to slurp UnicodeData.txt, do a rough filter on it based on some coarse-grained criteria, and then curate that to yield the set that you want to define as numeric.

12:29 sjl: diogo: babilen: I actually do the opposite -- I use Slimv with two files from VimClojure :)

12:29 babilen: diogo: If you are on Debian you can easily install leiningen and clojure from the Debian packages. Give me 30 minutes and I walk you through this, OK?

12:29 sjl: I would love to learn about your setup :)

12:30 cemerick: Yes, that is very true. I want to find all digits in a text and am surprised that 二 is not considered a digit in Unicode.

12:30 sjl: babilen: It's basically Slimv with VC's indent and syntax files. I like Slimv's repl and keybindings (especially since they're the same when I do lisp or clojure) but VC's indentation and syntax are way better

12:31 babilen: I made a fork of Slimv where I replaced the files, and I try to keep it updated: https://bitbucket.org/sjl/slimv

12:31 babilen: sjl: thanks -- I'll take a look

12:32 diogo: Which branch of Debian are you tracking?

12:32 sjl: Oh awesome, Slimv fixed the cw/whitespace problem. https://bitbucket.org/kovisoft/slimv/changeset/75c81a22a1a6

12:38 babilen: diogo: Install leiningen + clojure according to http://groups.google.com/group/clojure/browse_thread/thread/686569edb1c76df1 -- then configure vim to use vimclojure+slimv -- you also have to install the nailgun client and the leiningen plugin. The former is explained on https://bitbucket.org/kotarak/vimclojure and the latter is done with 'lein plugin install org.clojars.oskarkv/lein-vimclojure "1.0.0-SNAPSHOT"'

12:38 (this should be easier)

12:51 chewbranca: diogo: I got slimv working with pathogen and https://github.com/vim-scripts/slimv.vim, and just installing the swank clojure plugin: https://github.com/technomancy/swank-clojure

12:51 diogo: working config here: https://github.com/chewbranca/rc_files/tree/master/vim

12:54 babilen: diogo: I recommend vundle instead of pathogen though

13:00 chewbranca: babilen: vundle seems overly complicated, I like that pathogen keeps the logic and process of fetching git repos in the hands of git

13:01 babilen: just two different approaches to the same problem though, either way is much much better than just dumping everything manually into ~/.vim

13:01 babilen: chewbranca: As does vundle -- you don't have to use its ":BundleInstall" but it makes it easier. (OT though → #vim)

13:03 srid: icey: speaking of refactoring clojure code, checkout http://blog.darevay.com/2011/08/briefly-the-arity-reduce-pattern-in-clojure/

13:04 icey: srid: cool, thanks man - i'm actually doing all the refactoring we talked about last night right now :)

13:04 srid: icey: in an oss project on github? (just wondering if i can take a look at the commits)

13:05 icey: srid: just using gists at the moment https://gist.github.com/1164329

13:07 * srid is dreaming of a webapp where refactoring-based commits (from all clojure projects in github) are accumulated for easy browsing

13:09 icey: srid: i got more feedback on this other file, but i'm still working on it... it's in a proper git repo though: https://github.com/pmn/peeranoia/blob/master/src/peeranoia/core.clj

13:11 diogo: thank you

13:16 Scorchin: If I have a sequences of strings (words), how do I track the frequencies? Do I need to create keys for each word in a new map?

13:30 srid: Scorchin: yes, why not? recur on (assoc freq word (inc (or (freq word) 0)))?

13:31 Scorchin: srid: Thanks, I figured it out. Needed to convert the strings into keys :)

13:38 scottj: srid: another way to write that fyi: (update-in freq [word] (fnil inc 0))

13:41 srid: scottj: good to know, thx!

13:42 Scorchin: Is there a limit on the size of a data structure that slime/swank can handle? Is there any way to increase this?

13:42 amalloy: &(doc frequencies)

13:42 lazybot: ⇒ "([coll]); Returns a map from distinct items in coll to the number of times they appear."

13:42 amalloy: Scorchin: if your data is strings, converting them to keywords is generally pointless

13:45 Scorchin: amalloy: mapping them to lowercase strings and then running "frequencies" against on the produced lazy list seemed to do the job

13:53 I think I might be loading too much data for clojure/emacs to handle :/

13:53 "variable binding depth exceeds max-specpdl-size"

13:54 the odd thing is that it's only a 2mb json file that I'm playing with

13:54 * srid finally left appengine for compojure+lein on heroku to avoid the painful compile+run dev cycle of appengine-magic (and other appengine specific oddities).

13:58 srid: 4clojure throws java.util.concurrent.RejectedExecutionException despite having a ~/.java.policy file as described; any clues? the exception doesn't tell which point in the 4clojure source it arises.

14:01 amalloy: srid: sounds more like a lein problem

14:02 there were a couple versions of lein released that did this for any app that spins up agents or futures (and we use an agent)

14:45 AWizzArd: Anyone here who knows Nexus, Archiva, Artifactory or any such tool? What I want is a server that can serve me jars in my internal network. The jars I want to put in there manually, and it can not access clojars or any maven repo. But for Leiningen I want it to look like a valid source.

14:46 hiredman: AWizzArd: you just need a webserver that understands put / get

14:47 the smarts are all actually in mvn, not in the repo

14:49 cemerick: AWizzArd: What hiredman said; though I happen to use Nexus. It works, and has a lot of nice extras.

14:50 I've also started using S3 as a public maven repo, which is really nice for separate public-facing stuff.

14:50 Somelauw: Emacs keeps changing fn into a curly f. And I can't figure out why.

14:50 AWizzArd: cemerick: so, Nexus could be installed on a local machine, and then I can dump some jars in some dir and have maven/leiningen/cake use the Repo it provides?

14:50 danlarkin: chas has an inexplicable affinity for software labeled "enterprise"

14:51 * hiredman also has a maven repo on s3

14:51 cemerick: AWizzArd: Yes, though if you're doing something that simple, just use apache or nginx or whatever.

14:51 amalloy: Somelauw: someone clever included that in some starter package

14:51 cemerick: I'm pretty sure I've never used anything labelled "enterprise".

14:52 AWizzArd: ah oki

14:52 cemerick: Shibboleths, they come and go.

14:52 amalloy: i think it also changes #(...) into λ(...)

14:52 Somelauw: amalloy: It seems confusing to me, but after some tests I figured out it was treated as fn.

14:53 amalloy: Somelauw: yes, i don't think i'd like it, but it's just a visual change

14:53 Somelauw: amalloy: It doesn't do that lambda trick but my version might be old.

14:53 cemerick: danlarkin: I thought the knock on me was that I've never met an XML element I didn't like, etc? :-P

14:54 danlarkin: well that too

14:54 but maven's got it all

14:55 * cemerick types `mvn`, and shudders at the ecstasy of it all

14:55 hiredman: all that ecosystem

14:56 pjstadig: but...but...you can specify the developers who are involved, and what their roles are

14:58 cemerick: Reminds me of Annie Hall, where Alvy recalls the Marx quote… "wouldn't want to be in any club that would have someone like me as a member"

14:58 AWizzArd: That seems to be a funny and *very* lightweight server *lol* http://www.jibble.org/miniwebserver/

14:58 amalloy: Somelauw: looks like it's in emacs starter kit: https://github.com/technomancy/emacs-starter-kit/blob/master/starter-kit-lisp.el#L59

15:01 so if you don't like it, that's where you'd turn it off

15:01 Somelauw: I still need to watch Annie Hall.

15:02 arohner: Somelauw: yes. though don't do it if you're getting over a sad/bitter break-up

15:03 does 'case' not work with constant expressions?

15:03 (int \newline) is failing me

15:04 but 10 works

15:04 amalloy: arohner: no, it doesn't do that

15:04 arohner: :-(

15:04 amalloy: (int \newline) will succeed if you pass in '(int \newline)

15:05 just use condp =?

15:05 arohner: I'm trying to build a fast parser

15:05 '(int \newline) isn't matching for me

15:05 amalloy: arohner: no, i mean, if your case clause is (int \newline), and the data you test it against is '(int \newline)

15:06 arohner: amalloy: ah, I get it. thanks

15:06 amalloy: though that might not be true. seems like it should be

15:07 arohner: I'm reading a char out of a reader, so I need to handle -1, plus a few chars like \newline. I can't put \newline in the case, because .read returns an int.

15:07 and (char -1) fails

15:11 danlarkin: arohner: (char -1) fails because now casts check validate their inputs

15:11 arohner: danlarkin: that's fine. I'd be happy if case accepted constant expressions to match against. i.e. (int \newline)

15:12 aaelony: hi, with-query-results from clojure.contrib.sql will give me a vector of maps. Has someone written a function via Hiccup to mark this up into an HTML table ?

15:12 danlarkin: how do you determine what's constant and what's not?

15:12 amalloy: arohner: you can write a macro that expands to 10 instead of (int \newline), or you can hardcode 10 and put in a comment

15:12 arohner: danlarkin: assume intelligence on part of the developer. "whatever you return the first time we call expr is what we match against"

15:13 amalloy: yeah, I'll probably do that

15:13 hiredman: or you can (case (char c) \newline ...)

15:13 amalloy: hiredman: but that fails for -1, which i think was his point

15:14 hiredman: amalloy: which is why you put an if (pos? ...) around it

15:14 arohner: not possible in the compiler

15:14 arohner: hiredman: yeah, but that's ugly because you split up your cond. I'll make a macro

15:15 hiredman: case has to know the hashcodes of the values at compile time

15:15 arohner: hiredman: yeah? a macro can do the job, so the compiler should be able to

15:15 amalloy: hiredman: i thought i understood (case), but (case '(a) (a) 1) fails, while (case 'a a 1) succeeds. what am i missing?

15:16 cemerick: amalloy: Lists are for grouping multiple test expressions. (case '(a) ((a)) 1) works.

15:16 amalloy: oh

15:17 hiredman: ,(case '(a) [a] 1)

15:17 clojurebot: 1

15:17 hiredman: ,(case 'a (a b) 1)

15:17 clojurebot: 1

15:17 hiredman: ,(case 'b (a b) 1)

15:17 clojurebot: 1

15:17 amalloy: okay. the world is back to sanity; thanks guys

15:17 hiredman: wild

15:17 amalloy: i didn't even know that was a feature that existed

15:19 * hiredman didn't either

15:20 amalloy: &(doc case)

15:20 lazybot: ⇒ "Macro ([e & clauses]); Takes an expression, and a set of clauses. Each clause can take the form of either: test-constant result-expr (test-constant1 ... test-constantN) result-expr The test-constants are not evaluated. They must be compile-time literals, and need n... http://gist.github.com/1166207

15:22 cemerick: case has some easter eggs in it. Like, falling back to equality upon hash collisions (thanks to ataggart).

15:22 amalloy: yeah, i remember that one

15:25 hiredman: isn't equality the 4th hard thing in computer science?

15:29 cemerick: hiredman: what's #3?

15:29 joly: naming, caching, ______, and equality?

15:29 * cemerick assume naming and caching

15:29 manutter: #3 is "coding in the absence of caffeine"

15:29 dpritchett: Does MVC exist in clojureland? I've been trying to figure out the point behind the Railsy "Fat Controllers, Skinny Models" mantra and how it might apply to my Django project. I haven't really figured it out yet but it occurred to me that some #clojure minds might have more experience than I do.

15:30 Somelauw: Hi, I have the feeling that reduce is often a bit unreadable or is it just me?

15:30 danlarkin: it's you

15:30 cemerick: dpritchett: Not a lot, no…unless you consider simple functions to be controllers.

15:30 dEPy: Fat controllers and skinny models?

15:30 arohner: cemerick: you forgot off-by-one errors

15:30 dEPy: Isn't it the way around...

15:30 ?

15:30 arohner: the two hardest things in CS are naming, cache-invalidation and off-by-one errors

15:30 amalloy: well, maybe you'll get lucky and never have to write code that knows about more than one element of a seq at a time, Somelauw

15:31 mabes: Somelauw: once you have used the concept/pattern a lot reduce looks quite natural. if you've never used a function like that in another language it may be confusing at first

15:32 Somelauw: amalloy, mabes: Here is some code that I think looks complicated http://ideone.com/FS3RI

15:32 hiredman: cemerick: off by one errors

15:32 dpritchett: you're right dEPy the models are supposed to be fat

15:32 Somelauw: And case is a valid macro nowadays. ideone is just old.

15:32 dpritchett: My current django project has 3.5x more LoC in the controller than the models, I was wondering if I am doing this wrong ;)

15:33 Somelauw: Code should work.

15:33 amalloy: Somelauw: reduce with destructuring over the accumulator can look confusing if you're not used to it

15:34 mabes: Somelauw: FWIW, that doesn't seem confusing to me

15:34 amalloy: reduce takes only one accumulator, so he's reducing over a vector of [mapping, stack] pairs, and each iteration he's pulling it apart and reconstituting it

15:35 Somelauw: If I didn't write it myself, I probably wouldn't be able to guess what it does.

15:35 amalloy: oh, you wrote it yourself? then the fact that i was able to explain it to you should reassure you that it's not confusing

15:36 Somelauw: Yes. I was just wondering if anybody except me would understand it.

15:37 amalloy: Somelauw: fwiw, i'd use count instead of .length; probably (let) the result of (peek stack); and maybe use assoc instead of conj

15:40 Somelauw: Still your explanation of the codeis not really complete.

15:40 amalloy: I agree on those points.

15:41 You didn't describe what it does return.

15:44 This might spoiler it, but it returns a map with the positions of brackets associated to the matching bracket.

15:44 amalloy: Somelauw: well, the most-recent positions of brackets, right? you're conjing onto a map, not a seq

15:45 gregh: joly: there are two things: naming, caching, and off-by-one errors.

15:45 amalloy: &(conj {} {\[ 2, 2 \[}, {\[ 5, 5 \[})

15:45 lazybot: ⇒ {5 \[, 2 \[, \[ 5}

15:45 amalloy: note that [ maps only to 5; you've lost the 2, if you intended to keep it

15:47 joly: just passed that one around the office :)

15:48 manutter: joly (and arohner): that is a good one.

15:55 Somelauw: amalloy: Nothing should get overwritten in the map.

15:56 amalloy: Somelauw: oh right, x is the index, not the character

15:56 Somelauw: amalloy: Right.

15:56 amalloy: that's the part i found hardest to keep in my head :P

15:56 Somelauw: The alternative is to make the reduce iterate through 3 lists because I need the positions.

15:57 amalloy: Somelauw: code is what, a vector?

15:58 Somelauw: A string containing [ and ] and other chars.

15:59 Although a vector of chars and a string are almost the same.

15:59 amalloy: you can reduce over a list of pairs, which seems more self-documenting to me: (reduce (fn [[mapping stack] [c idx]] ...) [{} ()] (map (juxt identity #(get code %)) (range (count code))))

15:59 or at least use a name that implies an integer count, like i or n; x is very confusing there

16:00 (and i guess that should be [idx c], if it's going to match up with my juxt)

16:00 jkkramer: ,(map-indexed vector "abc")

16:00 clojurebot: ([0 \a] [1 \b] [2 \c])

16:05 amalloy: ah, that's nicer, of course

16:14 Somelauw: I think it is getting readable.

16:15 http://ideone.com/mFEtf

16:16 Sorry, I pasted the old one again

16:16 ldh: I'm calling 'map' on a collection, but ultimately i want the results put into a set instead of a lazy-seq. is there a better way than (apply hash-set (map f coll))?

16:17 Somelauw: This is what it looks now: http://ideone.com/YENwp

16:19 hiredman: ,(doc set)

16:19 clojurebot: "([coll]); Returns a set of the distinct elements of coll."

16:19 Somelauw: Thanks guys.

16:21 ldh: hiredman: ah, of course. (set (map f coll)). That's better.

16:26 arohner: dnolen: (match foo [foo & rest :foo]) just made my day!

16:27 dnolen: arohner: nice! :)

16:27 someone's trying to red-black trees, but that needs to wait for vectors patterns.

16:27 arohner: dnolen: one of those "I wonder if this will work..." moments, where it goes your way :-)

16:28 dnolen: arohner: it had better work! there are tests in there man!

17:52 patchwork: hey all, trying to use swank-clojure with emacs https://github.com/technomancy/swank-clojure

17:52 I keep getting a connection refused error when running M-x clojure-jack-in

17:52 any clues where to start here?

17:53 emacs 23 on macosx

17:53 clojure-mode works fine otherwise

17:54 chewbranca: patchwork: you did the lein plugin install swank-clojure I take it?

17:54 patchwork: chewbranca: yep

17:55 chewbranca: patchwork: hrmm... maybe try jumping into your project with the command line and run lein swank to see if there is any errors; other than that, not sure

17:55 patchwork: the actual error: "error in process filter: make client process failed: connection refused, :name, SLIME Lisp, :buffer, nil, :host, localhost, :service, 63232"

17:55 lein swank works fine

17:56 "Connection opened on port 4005"

17:56 while that is running if I do slime-connect I get the same error

17:57 hiredman: can you ping localhost?

17:58 patchwork: is it an issue with emacs then?

17:58 Yeah, pinging localhost works fine

17:58 hiredman: can you telnet to localhost 4005 ?

17:59 chewbranca: that error message looks like its trying to connect on port 63232, rather than 4005, I'm not familiar with the emacs side of things, but could that be the issue?

17:59 patchwork: When I do slime-connect it tries 4005

18:00 clojure-jack-in starts its own process, so I assume that is where it gets the port from

18:00 hiredman: clojure-jack-in uses a a random port

18:00 patchwork: telnet localhost 4005 fails

18:00 connection refused?

18:00 hiredman: maybe a firewall issue

18:00 patchwork: weird

18:01 firewall, between me and my own computer?

18:01 how did that happen?

18:01 amalloy: patchwork: windows does that

18:01 hiredman: dunno

18:01 patchwork: I'm on macosx

18:01 strange

18:02 any idea how to troubleshoot? I guess this is beyond the scope of #clojure now

18:02 hiredman: osx will sometimes popup a window asking if I want to let java connect to the internet

18:03 patchwork: not too familiar with local network settings

18:15 kencausey: I'm finally getting around to dnolen's NYC meetup talk (good stuff!) and I'm wondering if the slides have been posted somewhere yet.

18:15 amalloy: kencausey: on scribd, i think

18:16 dnolen: direct download from github here, https://github.com/downloads/swannodette/match/patterns.zip

18:16 AWizzArd: A friend yesterday told me how easy it was for him to use Match to optimize terms (:

18:17 dnolen: AWizzArd: cool!

18:17 kencausey: dnolen: thanks, I think I just found it on scribd, but that's probably better

18:19 Raynes: Offtopic: I've got Spotify invites. If anybody in the USA wants one, PM me an email address.

18:22 patchwork: interesting, here is my netcat line for lein swank:

18:22 tcp4 0 0 *.* LISTEN

18:22 and I can telnet 4005

18:22 just not telnet 4005?

18:22 ( is my local network ip)

18:22 how is that possible?

18:22 *netstat

18:25 amalloy: patchwork: if it's only listening on the remote interface, then telnetting over the remote interface won't work

18:26 patchwork: Yeah, all I did was type "lein swank"

18:26 it set up the port etc

18:26 not sure how to tell it to listen on localhost rather than my local ip?

18:26 amalloy: *shrug* i'm just pointing out that it's entirely possible from the netstat point of view

18:27 patchwork: Yeah so it is expecting a remote connection then?

18:27 gtrak: how would I say... test a function just by defining a bunch of inputs and the corresponding outputs?

18:28 patchwork: is it some kind of lein setting I need to put somewhere?

18:28 amalloy: gtrak: in clojure.test? you probably want to use (are...)

18:29 gtrak: amalloy, I can't really define them outside the macro and pull it in, right? I'd need like a compile-time apply for that

18:30 ah, I see there is apply-macro

18:30 amalloy: gtrak: god no. don't use that

18:30 gtrak: haha, ok

18:30 amalloy: you haven't made clear why you want to define them outside of the are clause

18:31 gtrak: I guess it doesn't really matter, it just seems like I should be able to do that

18:34 tomoj: define what?

18:34 gtrak: test-data outside of an is macro... then do something like... for the corresponding inputs and outputs, run this function on them

18:35 do a proper error when something fails

18:37 makes sense for say, the mathematical definition of a function, something that maps from inputs to outputs

18:47 Netpilgrim: gtrak: I'm a noob around Clojure, and perhaps I don't understand you correctly. But why don't you just put your test input and output in a map and do something like (doseq [input (keys testdata)] (assert (= (f input) (testdata input))))?

18:48 gtrak: yea, that's exactly what I'm about to do

18:49 assert-predicate looks like the right thing to use

18:51 patchwork: I figured it out

18:51 lein swank 4005

18:51 it was defaulting to the wrong interface

18:51 is that a lein swank bug?

18:52 hiredman: is every interface, which is a security risk, so lein defaults to I believe

18:52 patchwork: Except that in my case it defaults to

18:53 hiredman: that may be a bug in the way it figures out the ip for lo

18:53 patchwork: That is what I am wondering

18:55 hiredman: does localhost actually resolve to for you?

18:56 swank-clojure uses (InetAddress/getByName host) and host defaults to "localhost"

19:01 patchwork: localhost resolves to

19:02 PING localhost (

19:51 dnolen: chouser: what are quoting in your tweet?

21:26 hiredman: huh

21:26 the release notes for 1.3 isssue in jira has been closed

21:26 http://dev.clojure.org/jira/browse/CLJ-777

21:39 jli: if I have a bunch of tiny web apps, is there a nice way to host them all in one place? say, have root.com/app1/whatever do the same thing as app1site.com/whatever ?

21:40 I guess if each project exposed their handler, you could have a router site that used the first bit of the URI to route to the right sub-app, and strip the first part off in the process?

21:41 amalloy: jli: i use nginx to do that

21:42 jli: amalloy: cool, I'll look into it. thanks

21:43 amalloy: and i think that's basically jetty's default behavior, if you can figure out how to use it; i cna't

21:47 fwiw, jli, subdomains are a "safer" way to do this than url prefixes. app1.root.com/whatever will work better, because app1 may include hrefs like /foo

21:49 hiredman: huh, there is a whole "clojure 1.3" dashboard in jira

21:54 jli: amalloy: yeah, that sounds nicer

21:56 and I guess with wildcards in DNS, there's no extra administrative stuff to do, right?

21:57 amalloy: heh, i dunno. i'm not much of a server admin

21:57 jli: okay. I think it'd work :)

22:13 sleepynate: ok darevay, i know you're around here somewhere

23:14 ivan__: hi all, im trying to add a plugin written in clojure to an existing java project, but am having problems with either the classpath or how im using clojure. I'm extending a class which works fine, but then if i try and call outside clj code, the clj compiler gives me erorrs. Am I missing somthing? (more details to follow)

23:15 ant output https://gist.github.com/b66ff83787d58ddf81c3

23:15 my plugin https://github.com/hadashi/play-clojure/blob/master/src/play/modules/clojure/clojureplugin.clj, and the code it tries to call https://github.com/hadashi/play-clojure/blob/master/src/play/modules/clojure/util.clj

23:43 jjddb: hello

23:43 might anyone be familiar with http.async.client?

23:44 I am trying to figure out how to download a non-string file, like an mpr

23:44 mp3

23:46 The closest I've gotten is this:

23:47 (spit "ex.mp3" (with-open [cl (c/create-client)] (-> (c/GET cl "http://www.example.com/ex.mp3") (c/await) (c/string))))

23:48 amalloy: jjddb: since you apparently don't care about asynchronicity, why not just use slurp?

23:48 jjddb: amalloy: hmm... let me try that

23:49 yea, all I want is a simple get

23:49 amalloy: slurp might have a binary/text toggle, you'll want to check the docs

23:59 srid: i don't think so

23:59 i had to use java.net.URL

23:59 and then slurp the resulting stream

Logging service provided by n01se.net