#clojure log - Sep 22 2011

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

0:07 devn: Anyone here familiar with bricolage programming?

0:09 symbole: Only what Google shows.

0:09 devn: http://yaxu.org/writing/ppig.pdf

0:10 napping: is there no clojure-contrib 1.2.1?

0:10 devn: napping: correct.

0:10 napping: If you're on 1.2.1, use clojure-contrib 1.2.0

0:11 symbole: devn: Sounds like an interesting concept.

0:11 devn: (That's probably confusing and could be fixed.)

0:11 symbole: I think it relates back to what Rich was talking about in his talk the other night.

0:11 napping: I was working of something that mentioned clojure-core 1.2.0 and clojure-contrib-1.2.0, so I thought maybe they should match

0:11 symbole: devn: I'm not familiar with Rich's talk.

0:11 devn: napping: That seems totally natural.

0:15 devth: Trying to write a macro that `let`s a few symbols for use inside the ~@body, but clojure makes me put a # at the end of the identifier to avoid capture. Can I explicitly capture them?

0:15 napping: Is it just coincidental that both were at 1.2.0 for a while?

0:15 symbole: devth: ~'x would capture x.

0:16 jli: aaa//a

0:16 er, apologies for the line noise

0:17 devth: symbole: thanks

0:20 devn: napping: You can still get clojure 1.2.0. I can understand the confusion.

0:20 One does not expect contrib to be off by a point release.

0:21 Perhaps an alias or something would prevent confusion like this in the future.

0:21 symbole: devn: Is there a recent talk Rich gave? Any recording of it?

0:21 devn: symbole: No recording yet, but you will want to see it. :) It was a really fantastic talk. Sussman gave him a standing ovation.

0:22 symbole: Was this at a local user group?

0:22 devn: No, Stange Loop.

0:22 symbole: Oh, nice. Seems like a really fun conference.

0:23 devn: symbole: Yeah it was a lot of fun.

0:24 It was the precursor to Clojure conj. Lots and lots of Clojure talks. Lots of people from the communit there, etc.

0:24 community*

0:24 symbole: Makes me want to go to Clojure Conj.

0:25 napping: devn: if anything, fixing the README in the git head for seesaw might have helped, and that's not the sort of thing you should worry about just based on me jumping into things - but I should send a patch

0:26 devn: napping: Regardless I feel like if there's no release for contrib that will ever occupy 1.2.1, then someone might as well make it possible to use "1.2.1" to grab "1.2.0", but maybe that's crazy talk-- I'm going to ask the list and see what people think.

0:31 napping: It's pretty clearly listed here http://clojure.org/downloads

0:32 ah, this http://richhickey.github.com/clojure-contrib/index.html is for the development verison

0:38 Probably no point, if 1.3 is coming out soon, and contrib is splitting

0:41 tomoj: overtone's "may this be the start" inversion is delightful :)

0:50 quotemstr: So is push-thread-bindings like progv?

0:56 thearthur: im switching a project to clojure 1.3.0-RC0: is this the latest 1.3. what do i put for X.Y.Z in :dev-dependencies [[swank-clojure "1.2.1"]]

0:56 errr[org.clojure.contrib/shell-out "1.3."]]

0:57 sorry cut-and-paste fail. im asking about clojure-contrib shell out as a leiningen dependency

0:58 quotemstr: It'd be nice if Firefox actually scrolled to the appropriate anchor in Clojure documentation pages.

1:00 thearthur: where can i find a list of the various contrib projects, are they on github?

1:06 quotemstr: Is there a way to make reflection warnings fatal

1:06 ?

1:06 thearthur: does contrib.shell-out exist in the new contrib?

1:09 quotemstr: not that I know of

1:11 are all the contrib projects listed at https://github.com/clojure or are they scattered around github?

1:18 adam_: is there a clojure debian package with all the contrib libraries?

1:24 hiredman: adam_: don't use apt packages for clojure http://technomancy.us/151

1:27 quotemstr: (let [sslfactory (.getSocketFactory ctx) sslsock (.createSocket sslfactory "example.com" 443) session (.getSession #^SSLSocket sslsock)] ...)

1:27 Why can the compiler infer the type of ctx for getSocketFactory, and the type of sslfactory for CreateSocket, but not the type of sslsock for getSession?

1:28 (Omitting the #^SSLSocket hint generates a reflection warning.)

1:28 napping: http://download.oracle.com/javase/1.4.2/docs/api/javax/net/ssl/SSLSocketFactory.html

1:28 hiredman: lose the '#'

1:28 what version of clojure are you using?

1:28 quotemstr: hiredman: But all the examples I've seen use it.

1:28 adam_: @hiredman, for my research, I don't use packages for that exact reason

1:28 i have a couple installed

1:28 1.2.0 with counterclock wise

1:28 1.0.0 from the deb package

1:28 napping: createSocket just claims to return a plain Socket

1:28 hiredman: quotemstr: look at newer examples

1:29 quotemstr: hiredman: 1.2.1

1:29 adam_: and 1.1.0 alpha

1:29 hiredman: #^ is depricated, just use ^

1:29 quotemstr: hiredman: Thanks. Switched.

1:29 napping: So what's wrong with that?

1:30 Oh.

1:30 Right. Thanks.

1:33 napping: I don't know why it is that way, it should have been legal to say SSLSocket createSocket(Socket s, String host, int port, boolean autoClose)

1:33 quotemstr: napping: Does Java have what C++ calls "covariant return types"?

1:34 hiredman: I believe it does

1:34 but it may have been a late addition

1:35 adam_: it does for 5.0 and later

1:35 hiredman: "Covariant return types have been (partially) allowed in the Java language since the release of JDK5.0"

1:35 and the ssl stuff predates that

1:35 napping: ah, I guess that's it

1:37 quotemstr: Ah, I see.

1:37 Is it possible to pare down the default clojure.jar so that applets start faster?

1:38 hiredman: is there a supported way? no, but you can certainly try it, fork clojure and rip out bits

1:38 are you aot compiling everything?

1:39 that can speed up launch time a little

1:39 quotemstr: Does invoking clojure.lang.Compile do AOT compilation?

1:39 hiredman: depends

1:40 quotemstr: I have a simple makefile that runs that, then creates a jar out of all the generated class files.

1:40 hiredman: ~aot

1:40 quotemstr: I suppose I can do better.

1:40 clojurebot: AOT genclass is http://paste.lisp.org/display/70665 and http://clojure-log.n01se.net/date/2008-11-18.html#14:19

1:40 hiredman: wow thats old

1:40 http://clojure.org/compilation

1:41 quotemstr: Yep, I'm using AOT compilation then.

1:47 thearthur: how do i find version numbers for the new contrib projects? ie: :dependencies [[org.clojure.contrib/shell-out "X.Y.Z"]]

1:47 (does shell-out exist in the new contrib stuff?

1:47 hiredman: no

1:48 thearthur: that would explain the trouble finding it

1:48 hiredman: clojure.java.shell

1:48 it is in core now

1:49 thearthur: yay :)

2:00 justin`: anyone have experience setting up clojure with mod_proxy? Everything seems to be working, except all my html is escaped

2:01 (using noir + enlive, the problem might also stem from that combination)

3:13 rqcursq: Have a good day

3:26 _harsh-1: joi #haskell

3:31 Blkt: good morning everyone

3:32 robermann: hi

3:33 Blkt: hi

4:16 patchwork: hey all, quick question: I have a java file with a single class and I want to include it in my lein project. Where do I put it and how do I import it? (I tried putting it in the src directory under the package path but it tells me ClassNotFound)

4:17 So the java file has this package declaration:

4:17 package com.thebuzzmedia.imgscalr;

4:18 and has this class:

4:18 public class Scalr {

4:18 I put it in ~/src/com/thebuzzmedia/imgscalr/Scalr.java

4:19 and tried to import it from the repl thusly:

4:19 (import '(com.thebuzzmedia.imgscalr Scalr))

4:19 And I get this:

4:19 com.thebuzzmedia.imgscalr.Scalr

4:19 [Thrown class java.lang.ClassNotFoundException]

4:19 what am I missing?

4:21 robermann: I'm not an expert: In my opinion an src lein's project folder should contain only .clj files.

4:21 patchwork: robermann: Aha, so where do I put the .java files?

4:22 robermann: I think you first should compile your class and put it into lib

4:22 (inside a jar)

4:23 wait a second

4:23 patchwork: Aha… hmm

4:25 robermann: put your .class inside the "classes" folder

4:25 (honoring the package declaration)

4:30 patchwork: cool thanks! I am kind of new to java, I just did javac but I notice there is a build.xml in the main folder. Is there a customary java tool that builds with a build.xml?

4:31 Also, when I used javac it made a bunch of files like Scalr$1.class and Scalr$Method.class. is this normal?

4:32 nevermind, found ant

4:32 way better than javac

4:48 robermann: *$*.class files are generated by javac when you define inner classes in your source Java file

4:51 patchwork: okay, good to know

4:52 Hmm, it finds the class, but does not seem to have the resize method, though it is in the source. How do I see what methods a java class has from clojure?

4:52 > Scalr

4:52 hsbot: Not in scope: data constructor `Scalr'

4:52 patchwork: com.thebuzzmedia.imgscalr.Scalr

4:53 ah, I triggered hsbot

4:53 robermann: does your methods/constructors are public?

4:54 patchwork: Yeah,

4:54 public static BufferedImage resize(BufferedImage src, int targetSize,

4:54 BufferedImageOp... ops) throws IllegalArgumentException {

4:54 return resize(src, Method.AUTOMATIC, Mode.AUTOMATIC, Rotation.NONE,

4:54 targetSize, targetSize, ops);

4:54 }

4:54 So I should be able to say

4:54 (Scalr/resize img 180)

4:54 but I get a

4:54 No matching method: resize

4:54 [Thrown class java.lang.IllegalArgumentException]

4:55 I got img by doing a

4:55 (javax.imageio.ImageIO/read (as-file "/Users/rspangler/Desktop/Spomenik_03.jpg"))

4:56 which shows it is an BufferedImage object

4:58 robermann: I think you should pass the third parameter too

5:04 patchwork: that was it, thanks!

5:10 robermann: BTW, if you want to inspect the methods of a class (String, for excample), try: (for [method (seq (.getMethods java.lang.String)) :let [method-name (.getName method)]] method-name)

5:10 patchwork: That is what I was looking for

5:10 so .getMethods is the magic

5:10 How do I access a java enum from clojure?

5:11 this scalr class has options that are enums

5:11 Scalr/Method fails

5:11 public static enum Method {

5:11 inside the class def

5:12 Once I have a reference to the enum I can say (Method/valueOf :QUALITY)

5:12 or something

5:12 but I can't get at the enum, even though it is public and static

5:19 Found it

5:19 Scalr$Method/QUALITY

5:19 odd syntax

5:20 robermann: yes (javax.tools.JavaFileObject$Kind/HTML)

5:20 not so intuitive :D

5:25 patchwork: definitely expanding my java interop skills tonight

5:34 Hmm… how do I call a java function that has … ?

5:35 The last argument is

5:35 I was trying to be clojure flexible with BufferedImageOps…

5:35 (with ellipses)

5:35 If I pass in an argument I get the "No matching method found: resize" exception

5:35 ivan__: patchwork: isnt ... just an Object[] ... so i guess you could pass in a Object[] ?

5:36 (disclaimer, im not a clojure user :))

5:36 patchwork: Ah, so how do I create an Object[] in clojure?

5:36 funny, I am used to just clojure and all of this java stuff is throwing me off

5:37 ivan__: patchwork: http://clojure.org/java_interop#Java%20Interop-Arrays ?

5:38 raek: patchwork: (into-array collection)

5:38 or maybe object-array is better here

5:39 ivan__: patchwork: https://github.com/nickmbailey/java.jmx/commit/2a1e991c49718dc34c584fcebb989338ec8a13bc

5:39 i think this is being called heh

5:39 patchwork: That works!

5:40 thanks all

5:40 so I need to use java arrays for interop, makes sense now

5:40 for some reason I thought clojure collections would just be translated into java arrays

5:40 ivan__: patchwork: http://stackoverflow.com/questions/5638541/problems-calling-a-variadic-java-function-from-clojure

5:40 ah cool

5:40 raek: the java interop is perhaps more accurately described as JVM interop...

5:41 it doesn't have much syntactic sugar for Java inventions (eg. nested classes, varargs)

5:41 ivan__: you just have to match it to how its represented in bytecode/on jvm

5:42 in scala object a{def blah} gets mapped to equivlent of class a{public static void blah} in java

6:17 shtutgart: any advice on articles about building gui with clojurescript? (except "Most Basic ClojureScript GUI")

6:28 is it (clojurescript) even ready for use in production? maybe i should pick some java framework like vaadin?

6:35 bsteuber: shtutgart: I'd recommend reading "Closure: The definite guide"

6:36 of course it's for js, so you have to translate the OO-patterns to functional stuff for yourself

6:37 but it explains the API well

6:38 shtutgart: bsteuber: ok, thanks

6:52 kjeldahl: As much as I hate it, I need to make some jetty stuff (using the noir framework) run under Windows. After I quit the server (from a "lein.bat run"), the java process keeps running. Any simple workarounds (other than manually killing every time; cygwin kill doesn't seem to do the job properly)?

6:54 FWIW, built-in kill in cygwin bash does not work, but /bin/kill -f PID does.

8:57 Blkt: how do I get a seq or a list from a Double[]?

8:58 kzar: Any ideas what I'm doing wrong here? http://paste.lisp.org/display/124777 I'm somehow messing up a really really simple XOM query

8:59 fdaoud: Blkt: (seq dblarray)

8:59 kzar: Blkt: (seq (double-array [1 2 3 4 5]))

9:00 Blkt: thanks

9:00 thanks a lot guys

9:00 fdaoud: welcome

9:33 Blkt: how do I return multiple values?

9:34 Fossi: in a vector

9:34 for example

9:35 Blkt: isn't there a "values" construct?

9:36 joegallo: yes, it's called vector :)

9:37 Blkt: doesen't sound like Common Lisp's values, but that'll do the trick

9:40 joegallo: i'm not very familiar with values, but a very very quick read makes me think that you'll like this

9:40 if i have a (point) function that returns a vector of an x and y coordinate, which is very idiomatic, then i could use it like this:

9:40 (let [p (point)] (print (first p) (second p)) ;; but that's pretty lame

9:41 however, i can combine that with clojure's destructuring, and get something much nicer:

9:41 (let [[x y] (point)] (print x y))

9:41 so, as long as you're in a let context, it feels more like the vector is multiple value return, and less like a vector

9:50 jli: Blkt: clojure uses jvm calling convenions, so no multiple value return

9:50 people just use one of the nice general data structures :)

10:07 Blkt: jli: I supposed id, thanks for the explenation

10:23 kzar: I'm parsing a big XML file with XOM, I want to check the xmlns beforehand though any ideas? (I thought of reading the first 5 lines and finding it myself but it seems like the wrong approach.)

10:26 (I have to set up a context object with the xmlns so that I can query for things later. I want to set it dynamically so it always works.)

10:34 lnostdal: where's clojure.contrib.math gone in 1.3? i'm looking for round .. (java's Math/round isn't as good; it doesn't accept ints)

10:36 ok, no one knows .. i'll copy paste from the old clojure-contrib github then .....

10:36 clojurebot: () invokes the form inside, but there is an implied str call. The semantics are different inside the interpolated string, necessarily so.

10:40 lnostdal: and add a java.lang.Long method for it... sigh ..

11:01 TimMc: lnostdal: It's probably in core somewhere.

11:14 chrido: hi, i'm in general new to the whole java ecosystem. my application will do the whole day processing some messages and serving a status html page.

11:14 how would you deploy such an application on a windows box?

11:15 wrap it as a windows service? put it into tomcat?

11:15 joegallo: is it already running in an application server or servlet container like jboss, tomcat, jetty or the like?

11:15 or is it a standalone java/clojure application?

11:16 chrido: no, i'm just beginning with the application, greenfield

11:18 joegallo: okay, here's my $.02. since you are talking about serving up an html status page, you're probably going to be deploying something that ends up either running inside tomcat as a war file, in which case you should look at installing tomcat as a windows service (their windows installer handles this for you, iirc)

11:18 OR, you'll embed jetty into your application, such that when you start your application as a normal java app, you'll also be starting jetty, and your app will use jetty to serve the html

11:18 in which case you'll want to look at the java service wrappers for windows that exist

11:19 chrido: does tomcat start the application after deployment automatically?

11:19 joegallo: google and here are some thing for that list of service wrappers: http://stackoverflow.com/questions/68113/how-to-create-a-windows-service-from-java-app

11:19 chrido: ah, thanks!

11:20 joegallo: if you deploy your application as a war file, and you have that war file in the right tomcat directory, then, yes, tomcat will automatically load up your application upon start. and you'll be ready to start serving html.

11:21 in order to kick off some non-html-serving aspect of your application, though, you'll need to hook into something like the ServletContextListener, which is a hook that tomcat can call into your code to let you know that "hey, your app just started", and from there you could kick off a thread that will do the message processing or whatever.

11:22 based on nothing, i would argue that the embed jetty approach will make you happier, if what you're looking to do is write clojure code

11:22 but that's based on nothing

11:22 (besides my own prejudice, i suppose)

11:23 chrido: joegallo: ok, thanks a lot, just found a jetty windows service wrapper, seems to be also usable by our administrator, i think i will go with jetty

11:24 joegallo: okay, best of luck, have fun

11:31 cemerick: We're raised almost half of what we need to get Ambrose to the Conj. If you can, please donate — or share the post's link so that others can hear about the 'scholarship' fundraiser: http://wp.me/p10OJi-aX

11:32 Of course, thanks to everyone that's already donated; every cent is greatly appreciated. :-D

11:32 joegallo: cemerick: what are we looking at for top donations? i mean, if i'm going to donate, i want to win the autographed books. :)

11:33 cemerick: joegallo: I guess I don't really want to say precisely, as I'd be giving away what the eventual top donors had pitched in (which I guess they might not appreciate).

11:33 joegallo: blast

11:33 cemerick: > $100, certainly

11:33 joegallo: but good point

11:33 hsbot: <hint>:1:1: parse error on input `$'

11:34 joegallo: i guess the only way to be sure is to give $3000 - current account balance

11:34 :)

11:34 cemerick: hah

11:35 fdaoud: cemerick: that's a nice incentive. just curious: what happens to the donated amount if it's not enough?

11:35 cemerick: fdaoud: I don't plan on falling short. :-)

11:35 fdaoud: cemerick: of course not.! but what if?

11:35 cemerick: People will end up donating, just to get me to shut up.

11:36 fdaoud: I've never contemplated the possibility, honestly.

11:36 joegallo: it won't happen

11:37 i mean, he'll harass everyone until he gets there.

11:37 cemerick: Exactly right.

11:37 fdaoud: *<8-)

11:37 * cemerick needs an *evil grin* emoticon

11:37 fdaoud: I like your incentive. I'd do anything for a free computer book ;)

11:38 cemerick: Seemed like an easy, reasonable, fun extra.

11:38 michaelr525: >

11:38 err

11:38 so what

11:38 what

11:38 where is rich hickeys slides from strange loop?

11:40 cemerick: michaelr525: not up yet; will be here when they are: https://github.com/strangeloop/2011-slides

11:41 michaelr525: yeah, i'm polling on this page all day :)

11:42 really great stuff in there

11:42 wish I could be there too to hear all that

11:42 khaliG: yes paredit, but is there is a clever way to avoid having to hit shift+9 and shift+0 all the time?

11:43 cemerick: Thanks all; now we are *actually* halfway to the fundraising goal. Go #clojure :-)

11:43 michaelr525: how many people donated so far?

11:44 cemerick: ~35 or so?

11:44 clojurebot: excusez-moi

11:44 michaelr525: oh

11:44 ,(div 1500 35)

11:44 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: div in this context, compiling:(NO_SOURCE_PATH:0)>

11:45 cemerick: ~$42 / person

11:45 clojurebot: Huh?

11:45 michaelr525: yes, very generous people

11:45 imho

11:46 cemerick: Well, that's just a mean. :-)

11:46 Gotta run for a while. Keep spreading the world, everyone. Thanks again :-D

11:47 * michaelr525 is spreading the world

11:53 dnolen: please retweet if you have a free moment, https://twitter.com/swannodette/status/116899593119219712

11:59 Blkt: good evening everyone

12:07 dnolen: wow Shen released, http://www.lambdassociates.org/Download/download.htm

12:08 oops spoke too soon 12AM GMT tomorrow

12:09 technomancy: didn't see that coming

12:12 khaliG: dnolen, sweet

12:37 chewbranca: anyone have any recommendations for a database migration library? been checking out lobos and drift, curious to see if anyone has any thoughts

12:58 devn: technomancy: I'm asking this question without having done much homework, but I figured asking you might save me some time. I'm playing around with using ruby from clojure and what I'm doing is grabbing the gem source and placing it in src/foogem. The issue is that src/foogem/lib needs to be renamed to something else otherwise it will be blow away.

12:59 technomancy: I'm trying to figure out if there's a way to stop that from happening. According to Yoko Harada this didn't happen to her locally but happened on deploy to Heroku. Do you suspect Heroku, or could it be lein?

13:06 technomancy: devn: nothing comes to mind off the top of my head. only lib/ in the top-level of the project should be affected

13:21 michael_campbell: Anyone here going to clojure/conv?

13:21 dnolen: michael_campbell: lots.

13:21 michael_campbell: I registered yesterday, so will be there also,although I feel I'm woefully under-brained for it still =)

13:26 zerokarmaleft: michael_campbell: kind of in the same boat...we can get some jackets made

13:27 michael_campbell: zerokarmaleft: *chuckle* indeed. I'll be identifiable as the drooling idiot in the back ;-)

13:28 Not that that is out of the ordinary for me most of the time as it is...

13:28 manutter: I've been drooling since the schedule was posted...

13:46 justin`: Anyone know why my ouput might be coming out completey escaped when using enlive+noir?

13:52 icey: justin`: I think enlive escapes everything by default

13:57 jli: lnostdal: did you see this page? http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

14:02 elderling: jli: Link appreciated.

14:05 justin`: icey: any idea how to unescape it? I'm basiclly just trying to define a single html page as a teplate in enlive and as a page in noir, and I'm getting fully escaped html

14:06 when using the code from the new tutorial now on the enlive github, the same thing happens, oddly, but when spitting out hiccup code, everything's fine

14:07 lnostdal: jli, it leads to some log site

14:07 "latest build status"

14:08 but googling https://github.com/clojure/math.numeric-tower

14:10 icey: justin`: yeah, i think it's enlive that's doing the escaping, not noir. I think there is something you can call in enlive to mark the string as already escaped. give me a second, i'll see if I can find it

14:11 justin`: yeah I've been looking around in the source but can't seem to find anything, but maybe I'm just looking for the wrong thing

14:12 icey: justin`: I think you're looking for html/escaped

14:12 justin`: http://www.mail-archive.com/clojure@googlegroups.com/msg08293.html

14:14 justin`: k thanks I'll check that out! I think that function was removed from the current version

14:14 icey: justin`: oh shoot, that's not going to be helpful then lol

14:15 justin`: have you tried using emit* ?

14:16 (I'm not really an enlive user, so I'm not sure if this is something that you would have already tried)

14:16 bsod1: clojure(and I think most lisps) doesn't have statements, right? everything is either expression(has a return value) or special form(like if, fn)

14:18 amalloy: bsod1: first half true, second half...sorta true

14:18 everything is an expression, full stop. some things are also special forms

14:18 justin`: icey: yeah I'm guessing I should just use it on the result of the template? When I do it just double escapes eveything, so it looks like that's causing the problem, gotta run out for now but thanks again

14:18 amalloy: &(let [x (+ 1 (if true 2 1000))] x) ;; used special form in "expression context"

14:19 bsod1: thanks. one more question, what are differences between a real tail-call and clojure's recur?

14:19 icey: justin`: when you come back it might be useful for you to post up some code

14:19 amalloy: ,(let [x (+ 1 (if true 2 1000))] x)

14:19 clojurebot: 3

14:19 amalloy: recur can only do self-recursion. tall calls can call other functions

14:24 bsod1: what is a good way to create a new vector from an old vector but without it's first and last elements?

14:26 kharrington: ,(doc subvec)

14:26 clojurebot: "([v start] [v start end]); Returns a persistent vector of the items in vector from start (inclusive) to end (exclusive). If end is not supplied, defaults to (count vector). This operation is O(1) and very fast, as the resulting vector shares structure with the original and no trimming is done."

14:52 bsod1: amalloy

14:52 amalloy: *ponder* what was that about?

14:53 thorstadt: hit and run

14:54 manutter: never define colon as a hotkey for "Quit"

15:00 fdaoud: do bcarper or cgrand ever hang out here?

15:02 amalloy: fdaoud: if they do those aren't their irc nicks

15:02 hiredman: 2010:Feb:15:05:45:33 cgrand : chouser: what was your latest use case?

15:04 fdaoud: amalloy: yeah I figured, however I figured people here would know what they use instead :)

15:04 they don't use anything special on github

15:06 hiredman: ok so cgrand hasn't been here a year and a half.. :/

15:21 symbole: Wizywig: Ping.

15:21 JochenR: is there anyone like me who is missing a function mmap that is like map but takes a map and produces a map processing just the values?

15:21 Wizywig: symbole: pong

15:24 symbole: JochenR: I think it just mind be you :)

15:25 might be*

15:26 JochenR: hmm, is there such a function in core? I have of course written it myself

15:26 topically I see (into {} (map …)) but I find this to be just noise

15:26 r0man: is there a recommended version of swank-clojure to use with clojure 1.3-RC0? i keep getting "No matching field found: getRoot for class clojure.lang.Var" errors when running my tests via emacs. lein test runs fine on the command line. any hints?

15:27 hiredman: r0man: the latest version will work fine

15:27 latest release or any snapshot

15:27 symbole: JochenR: You can always use (vals ..) to get all the values. Seems pretty easy to make, but I don't know if one is already in the core.

15:28 r0man: hiredman: hmm, that's what i tried :(

15:29 hiredman: JochenR: is it really a map then? not a list of tuples?

15:29 maps as datastructures are generally not for linear traversal

15:30 dnolen: JochenR: another alternative is to use reduce.

15:30 JochenR: just see a vector as a map with the keys being indexes

15:31 mmap is a function that treats maps in the same way as map treats vectors

15:31 hiredman: people have a tendency to use {:id1 :value1 :id2 :value2} instead of [{:id :id1 :value :value1} {:id :id2 :value :value2}]

15:31 dnolen: JochenR: map doesn't treat vectors, it works w/ sequences

15:31 and you get a lazy sequence as a result, not a vector

15:31 JochenR: yeah, sure, but still you rely n the same ordering when you have a


15:31 hiredman: but the second is better for a lot of cases and infact maps more closer to something like a sql table

15:32 JochenR: vector

15:32 hiredman: the first is more like a k/v store

15:32 JochenR: (mmap inc {:a 1 :b 2}) -> {:a 2 :b 3}

15:32 hiredman: we understand what it does

15:33 and why people ask about

15:33 JochenR: oh, I am not the first? ;*)

15:33 hiredman: just saying you may reconsider your choice of data representation

15:34 JochenR: i see but, hmm, I do not really agree

15:34 ipostelnik: hiredman, every clojure shop seems to maintain a set of map fn variants to work with maps

15:35 hiredman: ipostelnik: really? how many clojure shops have you surveyed?

15:35 ipostelnik: 2 :)

15:35 hiredman: (no one asked me)

15:36 ipostelnik: I would say the same to them, if you want to linearly traverse a map, you may be using the wrong structure

15:36 JochenR: not linearly, just make sure all values get processed (pmap is fine). Order plays no role here

15:36 ipostelnik: small maps as tagged data representation are very common

15:36 hiredman: the second representation is far more flexable and can be made lazy while the map cannot

15:37 JochenR: hiredman: good point, maybe this is why it is missing from core. It is not "simple"

15:38 hiredman: ipostelnik: I am not taking a poll, I don't care what is common

15:38 as I said "people have a tendency to ..." I think that tendency is very short sighted

15:38 amalloy: yes, while it's tempting to map a function over a map's values, dumping it back into a map at the end is expensive

15:38 hiredman: correct

15:39 amalloy: better to work lazily with a bunch of k/v pairs for as long as possible, and dump it into a map at the end if you really need to (often it turns out you don't)

15:39 arohner: JochenR: I call that fn map-values

15:39 amalloy: eg, clojure-useful contains map-vals, which has exactly the function you're asking about, but i never use it

15:39 JochenR: hmm, this smells a bit like implementation detail to me.

15:39 arohner: JochenR: I also have map-keys

15:40 amalloy: JochenR: it is *not* an implementation detail

15:40 maps are not lazy, and cannot be while preserving the guarantees they make about fast key lookup

15:40 hiredman: working with sql, hadoop, riak map/reduce, etc the second case is all you see

15:41 actually that is not entirely fair, you'd need a transform between mapping and reducing depending

15:42 JochenR: as I see it clojure has chosen sequence as its main abstraction, other languages do different and there the set of functions over collections is a bit different, with different performance characteristics

15:43 but in clojure you might be right, you have to think in sequences, not collections here

15:43 arohner: JochenR: clojure hasn't chosen seqs as its main abstraction. All of the seq and coll functions in clojure have complexity guarantees

15:44 JochenR: well, map filer etc. al produce just sees from any squabble input

15:45 amalloy: JochenR: in a mutable language, you can modify a map's values in-place cheaply. you can't really do that when the maps are immutable, i think

15:45 arohner: but you explicitly can't do contains? on a seq, and some has a big warning that it's O(n)

15:47 hiredman: you can do it with maps, sure, and plenty of people have, but you can choose to do better

15:48 (heck I have)

15:49 JochenR: in smalltalk e.g collection is the base abstraction. aMap.collect fn yields a map, aVector.collect fn yields an ordered collection etc. You get something from the same "species" (roughly like equality paritions in clojure) In clojure you end up with a seq. aMap.collect is mmap. No mutation,new items are returned.

15:49 hiredman: (done it with maps, and argued with coworkers that the second way is better and just given up and let them do stuff)

15:49 JochenR: this is not smalltalk

15:50 amalloy: JochenR: i don't think it can both (a) do it in O(n) time without mutation, and (b) provide constant-time lookup after creating the new one

15:50 if it can i would be interested to hear how

15:50 hiredman: even though smalltalk makes that method available, I would still argue that if you find yourself using it, you may want to pause and think about it

15:50 TimMc: I like "seqable" -> "squabble".

15:50 hiredman: "is this the correct representation of my data?"

15:52 JochenR: Don't get so defensive :-). I am not saying that one should always use mmap, but in case you need a map over the values of a map (map is somehow bound twice here) it would be a useful function. I nfor sure need it sometimes..

15:52 hiredman: defensive?

15:53 ipostelnik: you don't always get to choose the representation - for instance ring gives you parameters as a map not a sequence

15:53 hiredman: useful, but often a poor choice, similar to calling contains? on a seq. clojure tends to push away from bad choices

15:53 amalloy: ipostelnik: and if you find yourself wanting to use map-vals on a ring map, let me know

15:53 JochenR: feel a bit like that because i hear performance all the time, but i just want to have readable code. I optimize just when it gets slow. With my small maps I do normally not care.

15:53 hiredman: ipostelnik: which is fine, do you really often map over all of the different kinds of fields there?

15:54 ipostelnik: hiredman, not often, but in my last project I needed to convert the keys to int

15:54 eug_: hi all. suppose i have a java object in repl. is there a way to get a list of its methods?

15:54 ipostelnik: it was super convenient to use a mmap on it and very easy to read the resulting code

15:54 bhenry: ,(doc show)

15:54 hiredman: ipostelnik: all of them?

15:54 clojurebot: No entiendo

15:54 amalloy: eug_: clojure.repl/show

15:54 eug_: cool

15:54 ipostelnik: all the query parameters

15:54 JochenR: yep

15:55 eug_: that's awesome!

15:55 hiredman: ipostelnik: so now the more query parameters I pass in the, the longer your app will take running that loop

15:55 ipostelnik: hiredman, sure

15:56 hiredman: ipostelnik: I am not saying down with maps, my example had more maps!

15:57 eug_: does anyone bind () to other keys? they're so faaar away from home row

15:57 bhenry: ipostelnik: he never said it's never a good idea. he said if you find yourself using it you might want to reconsider. in that case, it makes sense to mmap, because you probably only have a handful of params. but in another instance, you might be considering, "hey, i don't want to do it this way"

15:57 amalloy: eug_: i bind then to 9 and 0 - not having to use shift is good enough for me

15:57 JochenR: I just today had a map with some keys and strings, all of the strings to be resolved into data structures under same keys. mmap was very handy.

15:57 hiredman: I tried lowercase parens once, too much of a pain, turns out I type a lot of numbers

15:57 amalloy: (in fact i swap all the numbers with symbols, which on the whole has been a net gain i think)

15:58 hiredman: i know! more than i thought i did too

15:58 eug_: mind blowing idea

15:59 amalloy: but as it turns out i'm more fond of shouting! (and parenthetical asides)

15:59 ipostelnik: bhenry, I'm not arguing that maps are always the right data representation - my original point was that I've seen a lot of mmap implementations

15:59 TimMc: eug_: Also, you only really need the left paren.

15:59 dnolen: JochenR: if you're constantly mapping over maps just to put them back into maps, I think you might have a representation problem. otherwise the occasional (into {}) doesn't really affect readability at all.

15:59 amalloy: TimMc: only true in emacs

15:59 TimMc: amalloy: Anywhere where paredit functionality is available.

15:59 amalloy: i guess i'm a sinner for not using erc, but it's handy to have ) available in irc

15:59 TimMc: hmm

16:00 You really shouldn't type unbalanced parens anywhere. :-P

16:00 or should I say

16:00 :-)

16:00 bhenry: TimMc: ) is handy to jump to the end of a form even when you have paredit.

16:00 eug_: TimMc: hm; but even in emacs/slime i don't get the autoclose

16:00 amalloy: bhenry: i use ]

16:00 i think

16:01 bhenry: amalloy: touche

16:01 TimMc: < and > are pretty rare

16:01 swap 'em with ( and ) maybe

16:01 eug_: that's very convenient

16:01 ah

16:01 JochenR: dnolen: haha, well, not constantly;-)

16:01 eug_: but not in cascalog

16:01 amalloy: TimMc: what, because <> are easier to reach? not at all

16:01 eug_: amalloy: much easier!

16:01 TimMc: foot pedal, that's the only solution.

16:01 eug_: i actually *do* have a usb pedal

16:01 TimMc: C, M, (, and )

16:01 * amalloy has one

16:02 eug_: http://www.gizmag.com/thanko-usb-foot-switch-computer-pedal/18737/picture/134895/

16:02 dnolen: JochenR: then it's just a minor convenience. Including mmap would mean including vmap, smap, lmap, etc.

16:02 TimMc: I might make one out of a cannibalized USB keyboard.

16:02 amalloy: i still only use it like 10% of the time, though - never really got used to using it

16:03 C, M, and S, in fact; that helps counter the problem of swapping numbers/symbols

16:04 JochenR: dnolen: no, maps are different, as their keys are not transparently handled by map (only here you get k v pairs) as with vectors sets etc.

16:04 it depends on how you see it.

16:06 amalloy: maps are only different because you want to treat them differently. sets and vectors are just as different, to someone with slightly different goals than whatever your current goal is

16:07 JochenR: No. See it from the side of the function you pass in. In map over maps you have to handle key value pairs, in all the other cases, just values.

16:07 (map inc {:a 1 :b 2}) -> {:a 2 :b 3}

16:07 (map inc [1 2]) -> (2 3)

16:08 (sorry, first should be mmap)

16:08 amalloy: JochenR: yes, i'm aware of the distinction you're asserting. but someone just like you would be equally reasonable asking for (map inc #{1 2 3}) to return a set

16:08 dnolen: JochenR: if you want map-map, then you want set-map

16:08 JochenR: sets are key oriented.

16:09 JochenR: (map inc #{1 2} -> #{3 2}) (e.g.). See it from the fn side

16:09 amalloy: but seriously, if you want mmap so badly, then write it once and put it in a utilities library, or use one of the many existing libraries that have it already

16:10 JochenR: this is I think why I sometimes missed mmap and wrote it.

16:10 amalloy: &(map inc #{1 2})

16:10 lazybot: ⇒ (2 3)

16:10 bhenry: JochenR: (map inc #{1 2}) does not return a set

16:10 JochenR: lazybot: of course you are right

16:10 dnolen: ,(set? (map inc #{1 2}))

16:10 clojurebot: false

16:10 JochenR: but doesn't change the point I wanted to make

16:10 amalloy: lazybot: does mapping inc over a set return a set??

16:10 lazybot: amalloy: What are you, crazy? Of course not!

16:11 * amalloy <3 bots

16:11 TimMc: I think that point has been made...

16:11 JochenR: TimM: yep, fortunately also way before :-)

16:12 TimMc: JochenR: What's a practical example where you've felt the need for mmap, anyway?

16:12 I'm having a hard time remembering where I've needed to do the same thing to all the values of a map, ignoring their keys.

16:13 amalloy: TimMc: converting web-request params from strings to ints is really the most common case i've seen

16:13 TimMc: Ah, I see.

16:13 amalloy: personally, i don't like to do it in middleware, but if you wanted to you'd have to keep it as a map

16:14 JochenR: Today, resolving names into data structures.

16:14 amalloy: for example, instead i use https://github.com/4clojure/4clojure/blob/develop/src/foreclojure/graphs.clj#L55 at the least-abstract level possible, so that i don't have to turn it back into a map

16:15 JochenR: another one was convering [x y w h} rectangles into awt rectangles

16:15 amalloy: (using with-adjustments from https://github.com/flatland/useful/blob/develop/src/useful/utils.clj#L89 )

16:16 dnolen: JochenR: I just ran a recursive grep on probably 10000-20000 lines of Clojure code, various libraries my own code. into {} appears 12 times

16:16 TimMc: So, type conversions, of sorts.

16:17 JochenR: not always, I have just found one where I dissoc'ed one key from all values (also maps)

16:17 maybe it is because I am doing o web development

16:19 dnolen: JochenR: this includes my own web stuff, I don't recall using into {} that much there either

16:21 JochenR: well, I also think I have at 100 times more map than mmap, but if I need to process just map values with map I miss it as I have to write into {} and adapt the fn arg as well..

16:22 dnolen: JochenR: so create a utility lib, upload to clojars and require in your projects, done :)

16:22 JochenR: (mmap inc {:a 1 :b 2}) <=> (into {} (map (fn [[k v]] [k (inc v)]) {:a 1 :b 2})

16:23 bhenry: in emacs/slime/swank how do i recall an error? i pressed q too soon and the process runs long. i am hoping to just view the error on the buffer i just quit.

16:23 JochenR: dnolen: smalles lib in clojars ;-)

16:23 arohner: bhenry: I don't know about that, but the last exception might be in *e in the repl

16:24 dnolen: JochenR: don't forget zipmap, (zipmap (keys m) (map inc (vals m)))

16:24 bhenry: arohner: haha crap! i typed e* on accident so now *e is unable to resolve symbol. d'oh!

16:25 amalloy: JochenR: put more in there than just mmap. put all the functions you want more than once. i have a whole blog post at http://amalloy.hubpages.com/hub/Build-your-own-Clojure-toolkit about how you should have your own personal library on clojars

16:25 JochenR: dnolen: sure, but still….

16:25 amalloy: JochenR: also, use for instead of map in that example

16:25 (into {} (for [[k v] m] [k (inc v)]))

16:25 JochenR: (zip map is a bit easier to read, though)

16:26 why for?

16:26 amalloy: (map (fn [x] (inc x)) foo)

16:26 (for [x foo] (inc x))

16:27 dnolen: JochenR: easier to read, once you get used to it.

16:27 amalloy: and way more flexible

16:27 JochenR: well, here I disagree completely. It is matter of taste I would say.

16:28 amalloy: (for [xs foo, x xs] (+ 2 x))

16:28 (mapcat (fn [xs] (map (fn [x] (+ 2 x)) xs)) foo)

16:28 TimMc: Why (fn [x] (inc x)) instead of inc?

16:28 amalloy: TimMc: yes, for actual literals like inc, map is nicer; that's why i changed my second example to add two :P

16:28 dnolen: JochenR: familiarity as well.

16:28 TimMc: k

16:29 JochenR: dnolen: depends from where you come :-)

16:29 amalloy: JochenR: map is fine for what it's good at

16:29 dnolen: JochenR: in general in Lisp readability is about structure. Does the structure of your code reflect the operation.

16:30 JochenR: amalloy: yes, I agree

16:30 dnolen: JochenR: I find zipmap more reflective structurally of the operation being done.

16:30 amalloy: and `for` is more flexible for all but the simplest of mapping operations

16:30 JochenR: amalloy: yes, but I need just simple

16:30 (here)

16:30 amalloy: no you don't, i just saw you write (map (fn [[k v]] ...))

16:31 as soon as you have to declare a function literal inline, you're just using map to write a longer version of for

16:31 JochenR: and what was the alternative?

16:32 amalloy: (map (fn [[k v]] foo) bar)

16:32 (for [[k v] bar] foo)

16:34 JochenR: I just see fn missing and the order is reversed. I like the map order better (mmap foo bar)

16:35 but I think this is in a loop now.

16:36 Thanks for the nice discussion!

16:37 kharrington: ,(let [m (zipmap (range 1000) (range 1000))

16:37 mr (time (doall (map (fn [[k v]] v) m)))

16:37 fr (time (doall (for [[k v] m] v)))])

16:37 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

16:37 kharrington: ,(let [m (zipmap (range 1000) (range 1000)) mr (time (doall (map (fn [[k v\

16:37 ]] v) m))) fr (time (doall (for [[k v] m] v)))])

16:37 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading character>

16:37 kharrington: arg

16:38 (let [m (zipmap (range 1000) (range 1000)) mr (time (doall (map (fn [[k v]] v) m))) fr (time (doall (for [[k v] m] v)))])

16:38 ,(let [m (zipmap (range 1000) (range 1000)) mr (time (doall (map (fn [[k v]] v) m))) fr (time (doall (for [[k v] m] v)))])

16:38 clojurebot: "Elapsed time: 3.8 msecs"

16:38 "Elapsed time: 6.137 msecs"

16:38 kharrington: there... copy paste fail...

16:39 dnolen: JochenR: the takeaway is that lots of people want little small additions to the language (including myself) that don't add much expressive power. and these requests are not infrequent.

16:39 bhenry: kharrington: if you're map is that big you're almost definitely using the wrong data structure.

16:40 JochenR: dnolen: sure true

16:40 TimMc: Why?

16:40 clojurebot: http://clojure.org/rationale

16:40 TimMc: ~antibotsnack

16:40 clojurebot: Pardon?

16:41 amalloy: ~botsmack

16:41 clojurebot: Owww!

16:41 TimMc: ha

16:41 kharrington: bhenry: the ratio of performance is just as bad for a map of 20 entries

16:41 bhenry: ah

16:41 TimMc: ,(let [m (zipmap (range 100000) (range 100000)) mr (time (doall (map (fn [[k v]] v) m))) fr (time (doall (for [[k v] m] v)))])

16:42 clojurebot: "Elapsed time: 188.032 msecs"

16:42 "Elapsed time: 207.119 msecs"

16:42 kharrington: ,(let [m (zipmap (range 20) (range 20)) mr (time (doall (map (fn [[k v]] v\

16:42 ) m))) fr (time (doall (for [[k v] m] v)))])

16:42 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading character>

16:42 kharrington: ,(let [m (zipmap (range 20) (range 20)) mr (time (doall (map (fn [[k v]] v) m))) fr (time (doall (for [[k v] m] v)))])

16:42 clojurebot: "Elapsed time: 0.417 msecs"

16:42 "Elapsed time: 1.397 msecs"

16:42 TimMc: kharrington: You need larger numbers to test performance.

16:42 Also, /query clojurebot

16:42 amalloy: TimMc: i think he's publicizing it on purpose though, so everyone can see the difference

16:42 TimMc: I usually PM clojurebot until I have the syntax correct.

16:43 kharrington: TimMc: well, then you get into bhenry's argument

16:43 i use a REPL on my own machine to test syntax, it was just a horrible serious of copy/paste fails

16:43 series... see... typing fail

16:44 bhenry: kharrington: i believed you before you did the second example

16:44 kharrington: bhenry: well, its kind of interesting that it balances out as you increase in the size of the map

16:45 TimMc: kharrington: I've been doing runs of 100000 on clojurebot and the time is pretty variable.

16:45 I should be using a separate JVM from the rest of you. :-P

16:45 * Raynes notes that clojurebot is probably not the best place to run benchmarks.

16:46 Raynes: The code is sandboxed/molested in either bot.

16:46 technomancy: clojurebot: are you a benchmarking platform?

16:46 clojurebot: excusez-moi

16:46 technomancy: hmm... he used to have a factoid to that effect

16:47 amalloy: lazybot: is clojurebot a benchmarking platform??

16:47 lazybot: amalloy: Definitely not.

16:47 Raynes: lazybot doesn't know he is sandboxed. I have a perception filter in place to make him feel free, but he isn't free.

16:47 amalloy: technomancy: see, this way is just easier

16:48 technomancy: true. clojurebot is a lot of things, but consistent is not one of them.

16:51 TimMc: Same with my home server, apparently.

16:52 Anyway, if we don't care about giant maps, why do we care about performance?

16:53 Repeated operations over many small maps?

16:55 kharrington: I think the second method always runs slower because of GC or something.

16:55 Reverse your tests and weep.

16:56 kharrington: ,(let [m (zipmap (range 20) (range 20)) fr (time (doall (for [[k v] m] v))) mr (time (doall (map (fn [[k v]] v) m)))])

16:56 clojurebot: "Elapsed time: 1.362 msecs"

16:56 "Elapsed time: 0.453 msecs"

17:12 TimMc: kharrington: You need *way* bigger numbers for benchmarking.

17:12 20 isn't going to cut through the jitter.

17:18 kharrington: TimMc: I do buy that there is a point at which they seem to more or less equal out (>>10k entries in the map), but up until that point the map call is pretty consistently faster (even with the hash-map def-ed, and with the order of the map/for swapped)

17:18 Netpilgrim: Is there a specific reason behind the parameter order of (nth coll index)? All other functions that take some number and a collection seem to have the order reversed.

17:19 amalloy: Netpilgrim: the best explanation i've come up with is to match other lisps; i think everyone gets confused by nth with the current ordering, so it "can't" be on purpose

17:19 TimMc: kharrington: Right, so if you want to test 20-item maps, you need to repeat that maybe 10000 times and average the times.

17:20 Netpilgrim: amalloy: Too bad, I had hoped for some clever design idea – something to do with function composition perhaps.

17:22 amalloy: The order might also be chosen to mirror ([…] index).

17:22 TimMc: Netpilgrim: With some functions it *is* hard to say which arguments people will most likely want to partially apply.

17:24 kharrington: TimMc: touche, when wrapped in a dotimes, for does seem to outperform map after a certain number of trials

17:25 but that being said, if the call isn't iterated a ton of times, would the jitter actually be a reasonable thing to consider for performance's sake?

17:26 in the context of the call being contained in a bunch of other code

17:27 TimMc: No, because you can't predict jitter, so why let it contaminate your results?

17:27 Ultimately, things like branch prediction become important in real-world code, so these toy loops don't even tell us much.

17:28 I.e., wait until you have slow code, *then* try replacing for with map. :-)

17:28 kharrington: mmm... but i'm curious now!

17:29 TimMc: I just don't think you can say "for is faster than map" (or vice versa) outside the context of a full program.

17:29 Everything is relative, there is no god, etc.

17:40 amalloy: TimMc: no, i think map is faster than for, without exception

17:40 it just doesn't *matter*

17:41 since for macroexpands into a big mess that has a map deep down inside

17:46 on further inspection, it doesn't contain any maps, it does the lazy-seq stuff manually. whatever

17:50 kharrington: amalloy: i'm not so sure anymore though. i have been running a loop that steps through various sized maps, trying both let [... map ... for] and [... for ... map], and it really seems to be more or less equaling out, generally favoring for if the hash map is large

17:50 far too much time spent on this at this point though

17:58 TimMc: They're both O(n), it's all good.

18:00 amalloy: TimMc: laziness makes even that a confusing thing to say

18:00 concat is O(n), except that it's also O(1)

18:01 TimMc: returns in O(1), computes in O(n)

18:01 kharrington: and hence the argument about usage in the context of a real program

18:10 tomoj: does (range) "return" in O(infinity) ?

18:11 hiredman: it is O(1) but walking the result is O(n) where n is too large

18:14 TimMc: ,(let [N (range)]) ; tomoj

18:14 clojurebot: nil

18:14 tomoj: er, "compute"

18:14 TimMc: yeah

18:15 * kharrington resists sending that command

18:15 TimMc: But it is O(n), where n is infinity,

18:15 tomoj: that doesn't make any sense

18:15 TimMc: kharrington: ##(let [N (range)] N) won't hurt

18:15 kharrington: doall

18:15 lazybot: Execution Timed Out!

18:15 tomoj: I guess "O(n)" hardly ever really means O(n)

18:15 TimMc: See?

18:16 tomoj: range is O(n). (range) uses an infinitely high n,

18:17 amalloy: i realized recently that intern (as in java's string interning) is just (memoize identity)

18:18 not really related to this O(n) discussion but i thought someone here would find it interesting all the same

18:18 TimMc: ,(doc memoize)

18:18 clojurebot: "([f]); Returns a memoized version of a referentially transparent function. The memoized version of the function keeps a cache of the mapping from arguments to results and, when calls with the same arguments are repeated often, has higher performance at the expense of higher memory use."

18:19 TimMc: Hmm, it doesn't say what is used for equality.

18:19 amalloy: =

18:19 TimMc: &source memoize

18:19 lazybot: java.lang.Exception: Unable to resolve symbol: source in this context

18:20 TimMc: $source memoize

18:20 lazybot: memoize is http://is.gd/se7JvF

18:20 amalloy: &(let [intern (memoize identity)] (identical? (intern "test") (intern (str "te" "st"))))

18:20 lazybot: java.lang.SecurityException: You tripped the alarm! intern is bad!

18:20 TimMc: hah

18:20 amalloy: &(let [int (memoize identity)] (identical? (int "test") (int (str "te" "st"))))

18:20 lazybot: ⇒ true

18:20 amalloy: &(identical? "test" (str "te" "st"))

18:20 lazybot: ⇒ false

18:21 amalloy: i mean, really i guess what's used for equality is hash-map/get

18:21 TimMc: So clojail bans by symbol, not var.

18:21 amalloy: TimMc: yes, clojail is remarkably stupid in many ways

18:21 but it's hard to do better

18:21 TimMc: Conservatively stupid, I would hope.

18:22 amalloy: mostly. there are areas where you can't really do that; sandboxing is a huge topic

18:22 (tune in at the conj for Raynes's talk about clojail, if you're interested)

18:23 TimMc: Huh, "find".

18:23 amalloy: find is sweet

18:23 hiredman: some day the clojure compiler will have the hooks

18:24 amalloy: hiredman: i would love that

18:24 TimMc: ,(let [eval 3])

18:24 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

18:24 TimMc: "SANBOX" :-P

18:25 reburg: hey #clojure... trying to construct a multipart HTTP POST... I have a File object, but I'm not sure where to go from there.

18:25 i'm using clj-http for now, but i'm not wedded to it in any way

18:25 hiredman: I sort of started fiddling with the compiler to expose hooks for it, but it rapidly degenerated into something rather distasteful

18:26 amalloy: TimMc: all the clojure sandboxing environments are woefully insufficient at the moment

18:27 naeu: hi there

18:27 amalloy: ,((resolve (symbol (str "ev" "al"))) '(inc 1)) ;; for example

18:27 clojurebot: 2

18:28 TimMc: yup

18:28 amalloy: clojail has its own issues, like the ability to spin up new threads that the sandbox can't kill off

18:28 TimMc: I recall some other neat tricks.

18:28 naeu: I was hoping someone could help me with a macro I'm trying to write

18:28 amalloy: (which problem is currently causing us headaches at 4clojure)

18:29 hiredman: clojurebots sandbox is actually running in a different classloader and with a different version of clojure than clojurebot now, which is kind of neat

18:29 naeu: (defmacro foo [& body] `(let [bar# (some-fn-which-returns-a-list)] (let [~@bar#] ~@body)))

18:29 amalloy: yeah, i like that feature

18:29 naeu: I'd like to do somethign like this

18:29 hiredman: impossible or very hard to get at clojurebot internals from the sandbox

18:29 amalloy: naeu: you can't

18:30 TimMc: amalloy: But Clojure needs to say yes! :-P

18:30 naeu: amalloy: is it totally impossible? :-(

18:30 amalloy: yes

18:30 TimMc: ...and with that I am headed home.

18:30 amalloy: TimMc: see, i said yes

18:30 naeu: i mean, you can do anything with eval

18:30 naeu: amalloy: sure

18:31 amalloy: but you need the let-bindings available at compile-time, and you want them to be computed at run-time

18:31 naeu: yup, that's the size of it

18:31 TimMc: naeu: macros are syntax transformers -- they turn your code into other code before any values are available

18:32 (really actually heading home now)

18:32 naeu: TimMc: thanks

18:32 i'll look for another approach then

18:36 simard: I have a list and I want to create a hash-map out of that list (the list's items are the keys, the initial value would be nil for all of them), is there a function for that ?

18:36 tomoj: sure you don't just want {}?

18:36 simard: ?

18:37 amalloy: &(zipmap [:a :b :c] (repeat nil))

18:37 lazybot: ⇒ {:c nil, :b nil, :a nil}

18:37 dakrone: reburg: right now I don't think there's a way to do multipart POSTS with clj-http

18:37 tomoj: oh, are you using it kind of like a set too?

18:37 dakrone: reburg: may be worth looking into though, I'll add it to the TODO

18:37 reburg: dakrone: any idea of what i should be using?

18:37 amalloy: &(into {} (for [k [:a :b :c]] [k nil]))

18:37 lazybot: ⇒ {:a nil, :b nil, :c nil}

18:37 tomoj: &(= (:foo {}) (:foo {:foo nil}))

18:37 lazybot: ⇒ true

18:38 amalloy: oh, i see what you're getting at, tomoj

18:38 dakrone: reburg: I don't know of any library that does it currently, sorry

18:38 simard: hehehe I don't

18:38 but zipmap and into are what I want

18:38 amalloy: simard: a map with no entries is indistinguishavle, in most contexts, from a map with keys that have nil values

18:38 tomoj: there is no reason to put those keys in there unless you do something like (get the-map a-key :not-found) or check keys or something

18:39 simard: tomoj: I intend to fill it later

18:39 amalloy: tomoj: or (= m1 m2)

18:39 reburg: dakrone: actually, it doesn't have to be multipart... how would i go about doing a post w/ the file contents in the body?

18:39 tomoj: just fill it later then :)

18:39 amalloy: simard: doesn't matter

18:39 simard: tomoj: well yes, I want to test the presence of a key, actually

18:39 tomoj: ah

18:39 simard: probably :)

18:40 tomoj: contains? would be a good reason too

18:40 amalloy: tomoj: i considered that to be enfolded by "or check keys or something"

18:41 tomoj: that was accidental, I meant keys the function :)

18:42 Netpilgrim: What is wrong with this reimplementation of map: https://gist.github.com/1236249 E.g., I get an NPE for (map- inc [1 2 3]).

18:42 amalloy: Netpilgrim: you forgot an end-condition

18:42 (take 3 (map- inc [1 2 3])) probably works fine

18:43 Netpilgrim: amalloy: Oh. That should have been obvious. Thanks.

18:43 jli: mbac: write more clojure

18:44 amalloy: jli: did i miss a message from mbac?

18:44 jli: amalloy: no, I just know him IRL :)

18:45 reburg: actually, i need to run. thanks for your help dakrone!

18:46 dakrone: reburg: sorry I couldn't help more, hit me up later

19:04 Netpilgrim: amalloy: Small bug in 4clojure: If you sort the problems by difficulty, the order is alphabetical (easy, elemantary, hard, medium).

19:06 naeu: how might I refer clojure into a namespace created by create-ns?

19:06 amalloy: Netpilgrim: yeah, if you're handy with javascript i'm sure the patch to configure data.tables to do that is minimal

19:06 and we'd be happy to take it

19:07 Netpilgrim: amalloy: I’ve actually managed to stay away from JavaScript.

19:08 jli: amalloy: not quite rewritten in clojurescript yet? :P

19:09 amalloy: jli: unlikely to ever happen

19:09 jli: hum, why's that?

19:11 amalloy: i'm not at all excited about adding a compilation step for the js, especially a compilation step that doesn't work on openjdk (last i checked)

19:11 jli: hm, yeah.

19:12 amalloy: and since we're using jquery and all that crap, we couldn't use the optimizing compiler; we'd just end up with really bloated js code

19:12 and everyone who wants to touch the frontend would have to learn cljs...there's just no compelling reason to switch

19:16 hiredman: https://thestrangeloop.com/sessions/post-pc-computing-is-not-a-vision <-- this was a pretty depressing talk

19:16 "js everywhere!!!"

19:16 rbranson: heh

19:16 hiredman: I think he meant it as something to be excited about

19:16 rbranson: the rant of a senile old man

19:16 technomancy: hiredman: http://twitter.com/#!/dibblego/status/116861441876824064

19:17 hiredman: at one point he had a slide with a js+html+dom stack super imposed on a washing machine

19:17 companion_cube: is there something to read on it on the web?

19:18 hiredman: his slides will be up at some point

19:18 not worth a read

19:18 rbranson: maybe he'll fix the rampant typos

19:18 hiredman: do-deca-dec worst talk at strangeloop

19:18 rbranson: by far

19:18 made richey look even more like a bawss

19:19 hickey, wow

19:19 jli: what did rich talk about?

19:19 amalloy: the perils of TDD, to judge from the twitterverse

19:19 hiredman: :D I went out to eat with rich and some relevence guys afterwards, it was sweet

19:19 jli: hm, interesting

19:20 rbranson: he made like one comment about TDD, but everyone got all caremad

19:20 companion_cube: many talks seem cool

19:20 rbranson: I don't think he's even against TDD, just the zealotry

19:20 hiredman: well, the middle D there

19:20 technomancy: hiredman: man, I got stuck at a scala dinner where they were commisserating the scala-bashing in the keynote

19:20 hiredman: hah

19:20 simard: I have this snippet here: http://pastebin.com/bHN00AZp , which I'd like to simplify or make more elegant, is there anything obviously wrong to it ?

19:21 technomancy: hiredman: actually it wasn't that bad

19:21 jli: technomancy: what was the keynote?

19:21 amalloy: (comp #{:a-type} :type)

19:21 rbranson: yeah it wasn't -- he pretty much pissed off everyone in one way or another

19:21 technomancy: except for the part where he was all "I still don't believe that anyone who actually understands the curry-howard isomorphisms could really be against having a type system."

19:21 rbranson: which is what made it so great

19:21 technomancy: jli: rich's simplicity keynote

19:21 couple thinly-veiled jabs at scala in there

19:22 jli: heh

19:22 technomancy: or at least that's how the scala guys took it

19:22 rbranson: he had jabs to go around :D

19:23 technomancy: http://twitter.com/#!/moonpolysoft/status/116269563389296640

19:23 (SFW)

19:23 rbranson: except for the dick background? ;)

19:24 technomancy: oops

19:24 SFW compared to the average moonpolysoft tweet

19:24 (it's just ascii; don't worry)

19:24 amalloy: sorta depends where you work

19:25 rbranson: where I work -- doesn't matter

19:25 mdeboard: Anyone know of any person/people/organization(s) doing any ML (or greater AI) work with Clojure?

19:25 amalloy: i'm really just trying to wedge in a joke about technomancy working at a porn studio, but i can't get it to make sense

19:27 rbranson: http://blog.markwshead.com/1069/simple-made-easy-rich-hickey/ <--- notes

19:27 technomancy: I'll defer to danlarkin

19:27 mdeboard: rbranson: Since you own Virgin International, you could come in to work wearing a suit made of dildos and no one would say a word.

19:27 rbranson: they would probably say lots of words, really

19:28 mdeboard: "Nice suit, Mr. Branson!"

19:28 THanks for the link, btw, was looking

19:29 rbranson: i'd wait for the video before looking at the slides -- will just be confusing

19:29 jli: man, I really don't understand how to follow discussion on twitter :(

19:30 rbranson: if anything, I think it most thoroughly bashes the NodeJS and MongoDB crowd the most

19:30 technomancy: rbranson: "This is UNIX^H^H^H^HJabbascript; I know this!"

19:31 danlarkin: confirmed, technomancy works at a porn studio

19:31 mdeboard: nice

19:31 jli: leiningen was a classic film - kudos

19:31 technomancy: danlarkin: just because you keep adding me as a clojuredongs committer...

19:32 mdeboard: lol.

19:32 jli: all those ants, superhot

19:32 mdeboard: rbranson: Do you have any idea when said video will surface @ InfoQ?

19:32 Just reading those notes have piqued my interest. We do everything the "easy" way at work.

19:32 rbranson: mdeboard: they are really slow

19:32 at least they were for 2010

19:33 mdeboard: THey pace them out to milk page views I'm sure

19:33 rbranson: mdeboard: it was pretty transformational in my thinking… sounds cliche but whatever

19:33 mdeboard: hoping Mssr. Hickey's is among the first

19:33 rbranson: You're the second person who's said that about that talk, of the two people I've talked to about it

19:34 hiredman: rich mentioned something about if/cond being "complected" (bad) which was interesting

19:34 technomancy: a lot of what he said was in Stuart H's conj talk if you just can't wait.

19:34 rbranson: i'm not even a clojure user really. have looked into the concepts because i find them interesting, and after his talk, i'm looking more into it just after all that

19:35 hiredman: no one really has said anything about that

19:35 he mentioned using a rules engine instead

19:35 technomancy: hiredman: and/or predicate dispatch

19:35 IIRC

19:36 but yeah, being dataflow-ish was a theme between him and sussman

19:36 hiredman: really? I don't recall him mentioning predicate dispatch there

19:37 pattern matching was mentioned separately from if/cond I believe

19:37 technomancy: perhaps that was a jump I made in my own head

19:38 closed/open -> match/pred-dispatch was mentioned by dnolen at least.

19:38 hiredman: right

19:38 technomancy: and cond basically only exists as a compilation target for match, right? =)

19:39 rbranson: told everyone to go fuck themselves and use prolog ;D

19:41 dnolen: I think Rich was advocating moving conditionals outside of fns - predicate dispatch / rules are both ways to get there.

19:42 rules/logic programming also good ways to emphasize what over how

19:44 mdeboard: dnolen: "outside of fns"?

19:45 What's fns stand for?

19:45 Oh

19:45 `fn`s

19:45 rbranson: like not using if-then-else statements basically

19:45 mdeboard: derp.

19:49 hiredman: which I don't really get, like if I replace (if (> 3 4) a b) with (query-expert-system (is (> 3 4)) (choices a b)) dunno how that is different

19:49 which is why I found it an interesting point

19:50 rbranson: <dnolen> rules/logic programming also good ways to emphasize what over how

19:50 that is basically it

19:51 it's hard to make a bunch of if-then-else spaghetti composable

19:51 hiredman: but it means the rule engine has to drive your code, you can't just query it

19:52 rbranson: i'm not expert, but i agree… just because the rule code i've written & seen has all been terrible

19:54 dnolen: hiredman: I don't think he's talking about simple conditionals. But once you start getting to more than 4-5 cases, probably a good target for pred dispatch / rules

19:55 rbranson: interdependent rule code also tends to get littered across the codebase

19:56 * companion_cube puts The_Doctor in his tardis

19:58 companion_cube: I find that in many cases, complicated if/then/else should be local only, and conditional otherwise should be replaced by something like an event system that uncouples parts of the application

19:59 mdeboard: rbranson: I found your personal website and am forced to dismiss your opinion

19:59 rbranson: On *everything*

19:59 rbranson: mdeboard: quit stalking me :)

19:59 mdeboard: I wish I could unsee it

20:00 also I wanted to make sure you weren't the famous richard branson

20:01 rbranson: thanks for reminding me to update it to something more relevant

20:03 mdeboard: I dunno, I think you could market it as an avant garde critique of modern web design

20:03 rbranson: it's much better now

20:05 mdeboard: rbranson: Wow

20:05 nailed it.

20:05 rbranson: they call me the oracle

20:06 dnolen: companion_cube: interesting opinion given that dispatch on type is one giant non-local conditional statement

20:08 companion_cube: dnolen: i wasn't thinking of type-based events

20:09 more something like FRP

20:09 let's say a system in which events are objets, not types

20:27 hiredman: dnolen: right the simple if is jsut an example

21:06 cemerick: dnolen: where did 'swannodette' come from, anyway?

21:08 rbranson: nytimes I believe

21:12 cemerick: rbranson: really?

21:13 * rbranson stabs himself in the face

21:17 * cemerick has strange effects on people sometimes :-P

21:31 amalloy: cemerick: you should wear a mask at the conj, for everyone else's safety

21:31 redinger: If he wears a mask how would we tell him and Fogus apart?

21:32 amalloy: we could ask which one has published a...damn!

21:33 dnolen: cemerick: marcel proust

21:33 cemerick: amalloy: don't jinx it! ;-)

21:35 * cemerick had to look Proust up on wikipedia #lame

21:36 amalloy: /join #lame

21:36 they wouldn't let me in. not sure if this is a good sign or bad

21:39 cemerick: "I never wanted to be part of any club that would have me as a member."?

21:51 ibdknox: dnolen: just sent out my post to clojure-dev, loops themselves are just incredibly slow

21:56 gtrak: do you have to do anything special to make cljsc compile multiple files?

21:57 ibdknox: gtrak: no

21:57 gtrak: it doesn't see the :require'd file

21:57 ibdknox: gtrak: http://github.com/ibdknox/cljs-watch might make your life easier

21:57 are you compiling a specific file? or a directory?

21:58 gtrak: a file, but I suppose it should be the directory?

21:59 ibdknox: yep

22:03 dnolen: ibdknox: it's not loop/recur that is slow, it's doseq - that'll wrap array in a ArraySeq

22:03 ibdknox: I would measure with raw loop/recur

22:05 ibdknox: dnolen: I'll add numbers for that in a few

22:13 dnolen: still 2 orders of magnitude off

22:13 dnolen: does drop it down to 3000 though instead of 4500

22:13 dnolen: ibdknox: what's the compiled JS look like?

22:14 ibdknox: and is this in advanced compiliation mode?

22:14 ibdknox: I'm pretty sure deep property lookup gets eliminated by the compiler, which is another big perf hit.

22:15 ibdknox: dnolen: collecting advanced numbers now

22:17 dnolen: gist updated with advanced mode output. Still 1700-2000ms

22:18 dnolen: ibdknox: what gist?

22:18 ibdknox: https://gist.github.com/1236554

22:21 dnolen: ibdknox: you're just measure seq performance, not loop performance. using range to control iteration is not going to be fast, instantiation per step

22:21 measuring

22:22 ibdknox: dnolen: good point. One sec

22:22 indeed.

22:23 dnolen: all the way down to 126!

22:23 dnolen: problem is seqs are how we interact with everything

22:23 dnolen: ibdknox: now you're paying for the fact that (inc i) should be inlined

22:23 ibdknox: yes

22:23 dnolen: ibdknox: no in hi-perf Clojure you don't use seqs

22:23 nor in ClojureScript

22:23 same rules apply

22:24 ibdknox: dnolen: the correct solution is an array?

22:24 dnolen: ibdknox: array ops + loop/recur with an integer counter

22:25 ibdknox: dnolen: why can't that just be an implementation detail?

22:25 dnolen: ibdknox: they should be but we haven't figured out what that is yet. That was idea behind Pods.

22:28 ibdknox: dnolen: maybe that's something we should try to get out of the conj. It seems very wrong to me that I have to explicitly not use one of the best parts of Clojure to be able to do something realistic.

22:30 dnolen: ibdknox: we'll have to pick rhickey's brain, he got started on it, but stalled because he couldn't solve something around access in multithreaded scenario, but maybe we don't need to care about that.

22:31 pcerrato: Rich's "sequences" talk appears to have shrunk to 8 seconds both on blip.tv and iTunes. Anyone know where I can find to full talk?

22:39 amalloy: pcerrato: rich can convey a lot of information in 8 seconds

22:40 pcerrato: this is true ...

22:40 symbole: Any StrangeLoop videos posted already?

23:09 livingston: I have a list that I am destructuring, it will have 3 or sometimes 4 items, the 4th is optional. a valid value for the fourth is nil, so what's the best way to detect the difference between a given nil and an unprovided nil?

23:10 srid: %g tools.match

23:10 $g tools.match

23:11 livingston: use multiple arity function and core.match?

23:12 livingston: it's not multiple arity, the input is one list e.g. [[a b c d]] where sometimes the function will be called (foo '(x y z))

23:13 brehaut: livingston: kind of hideous but ((fn [[a b c d :as l]] (if (= 4 (count l)) d :no-d)) [1 2 3])

23:14 livingston: right now I'm just doing [[a b c d :as x]] and then checkign the length of x

23:14 ha, that was what I was about to say. thanks.

23:19 brehaut: livingston: its much less horrible than ((fn f ([l] (apply f l)) ([a b c] :no-d) ([a b c d] d)) [1 2 3])

23:19 livingston: brehaut: what the heck is that?

23:20 brehaut: an abomination

23:20 ibdknox: it's probably cleaner to destructure in a let

23:20 and just take x as your param

23:21 brehaut: ibdknox: im just using fn because livingston said it was a function

23:21 livingston: ibdknox: I am. this is part of a bigger thing

23:21 ibdknox: livingston: good deal

23:22 livingston: brehaut: yeah it doesn't much matter, destructure here or there it's 6 one way, half dozen the other

23:22 i'm assuming the desctruring in the call signature is just syntactic sugar that macros away to something like that anyway

23:22 ibdknox: well

23:23 yes, but the way you would then write that code changes significantly

23:23 brehaut: livingstone, the macro just calls destructure

23:23 livingston: oh but duh if I have the parameter I don't need the :as bit

23:23 ibdknox: because you can use an if while destructuring

23:24 livingston: (fn [quad] (let [[a b c d] quad] (if (= 4 (count quad)) ...

23:27 srid: something like http://pow.cx/ but for clojure would be cool.

23:28 ibdknox: srid: what is missing from Noir for that to be true?

23:28 srid: livingston: you can also `apply` the fn over the list (create wrapper function that does that)

23:28 livingston: srid: yeah but that seems messy, destructure will do it.

23:29 srid: ibdknox: pow is framework agnostic. pow for clojure would be more like 'run any ring-based apps -- based on "lein run"' just by symlinking the code directory (with auto-restart, etc..)

23:29 ibdknox: srid: so kind of like lein ring server then? Except maybe a bit more robust

23:30 srid: ibdknox: yea, but not tied to single app. ln ~/code/myrubyapp ~/.pow is all that is required to have http://myrubyapp.dev refer to a running server

23:30 ibdknox: I see

23:30 srid: that's `ln` (symlink)

23:30 ibdknox: yep

23:31 seems like it wouldn't be hard to build

23:31 the only difficult part is the vhosts

23:32 amalloy: &(map (fn [[a b c & [d :as has-d]]] [a b c d has-d]) [[1 2 3 4] [5 6 7]])?

23:32 lazybot: ⇒ ([1 2 3 4 (4)] [5 6 7 nil nil])

23:32 amalloy: livingston, brehaut: ^

23:32 brehaut: amalloy: aha of course

23:34 ibdknox, srid: would multicast dns be a solution to that?

23:34 livingston: amalloy: interesting, I'm not really sure how that makes me feel, but it'd certainly work

23:34 it avoids the counting that I don't like

23:34 ibdknox: amalloy: I feel like we could get juxt in there somewhere ;)

23:34 amalloy: livingston: the counting is evil; it means you couldn't ever extend this pattern to work for infinite sequences, for example

23:35 livingston: someone better not be putting one of those here.

23:35 ibdknox: livingston: what does the function do? lol

23:36 it's kind of a weird pattern

23:36 livingston: I would hope that the compiler could optimize (= 4 (count ... )) to know that it can stop at 5 but maybe it can't

23:36 ibdknox: it doesn't

23:37 livingston: that's why some people recomend testing (rest (rest ...)) if you want to know if there is more than 2

23:37 amalloy: *cough* next, not rest

23:37 brehaut: nnext

23:37 ibdknox: nth!

23:38 amalloy: &(nthnext [1 2 3] 2)

23:38 lazybot: ⇒ (3)

23:38 amalloy: &(nthnext [1 2 3] 3)

23:38 lazybot: ⇒ nil

23:38 livingston: in common-lisp it was neither either nth-cdr or (cddr

23:38 brehaut: because common lisp is anti vowels?

23:38 ibdknox: lol

23:38 technomancy: brehaut: optimized for wheel of fortune!

23:39 * technomancy can't get over how `assoc' in elisp (and presumably CL) returns the whole cons

23:39 livingston: ibdknox: the function takes an rdf triple or optionally a quad if the graph is specified, if the graph isn't specified it goes to the default graph.

23:39 brehaut: technomancy: the APL edition of WoF would be quite hard

23:39 technomancy: hehe

23:39 amalloy: technomancy: i assume it's so you can replacd or replaca it?

23:39 livingston: technomancy: how else would you change the value?

23:40 technomancy: livingston: change? what's change?

23:40 livingston: brehaut: you could have some 'a's in there ... (caddr that's "third"

23:40 ibdknox: we don't need no stinkin' changes here

23:41 simard: I have a list of hash-maps ({:N 1 :string "stuff" :more "stuff"} {:N 2 :string "hello" :more "world"}) and I want to find the first hash that matches with a candidate hash that contains all keys but one, like {:string "stuff" :more "stuff"}. if there is a match, I want {:N 1 :string "stuff" :more "stuff"} to be returned, otherwise nil.

23:41 there's probably an easy way out, right ? :)

23:42 livingston: simard: is it one specific key you don't want?

23:42 simard: no, I want it

23:42 I just don't care if it matches or not

23:42 and yes, it's one specific key

23:42 say, :N

23:42 livingston: (some (fn [m] (not (:bad-key m))) maps)

23:43 that's not what your asking though right you want a set of keys to match?

23:43 amalloy: &(let [maps '({:N 1 :string "stuff" :more "stuff"} {:N 2 :string "hello" :more "world"}), test {:string "stuff" :more "stuff"}] (first (filter #(= test (dissoc % :N)) maps)))?

23:43 lazybot: ⇒ {:N 1, :string "stuff", :more "stuff"}

23:43 ibdknox: meh

23:43 you beat me to it

23:44 simard: meh indeed

23:44 ibdknox: simard: hm? amalloy's solution is a good one

23:44 amalloy: ibdknox: all of my code is correct on the first try so i just type it into irc without testing

23:45 ibdknox: lol

23:45 simard: yes I agree, I'm just impressed that anything I ask here is answered within the minute

23:45 lol

23:45 amalloy: simard: maybe a language issue? "meh" is an expression of...apathy or indifference

23:45 * ibdknox bows before alan's awesomeness

23:45 simard: amalloy: yes I guess that's it

23:45 should have been, "wow"

23:46 brehaut: the great thing about #clojure is that it acts like prolog. you ask a question and you get a stream of answers until hiredman says 'no'

23:46 ibdknox: hahaha

23:46 or 'incorrect'

23:46 amalloy: nice

23:47 i'm sure i've answered at least one question today with "no"

23:48 someone wanted to do something crazy with a macro that needed runtime information

23:48 technomancy: amalloy: steve yegge disapproves.

23:48 ibdknox: srsly

23:48 amalloy: technomancy: second one to make that joke about my answer already :)

23:48 ibdknox: Let's ostracize him.

23:49 technomancy: oh snap

23:49 amalloy: amalloy: naeu: you can't

23:49 TimMc: amalloy: But Clojure needs to say yes! :-P

23:51 ibdknox: I feel like I should write something ridiculous that lets me write awesome blog posts like this one: http://blog.whatsapp.com/index.php/2011/09/one-million/

23:52 amalloy: ibdknox: just make a bunch of money instead. then you can write: "I recently deployed my horizontally-scaled webapp, with an established TCP connection on each of my million machines"

23:52 ibdknox: hahaha

23:52 funny you should mention that...

23:53 One of our original plans for typewire was to essentially spin up 600 machines to handle a couple of very high traffic events

23:53 that's when I ditched node.js ;)

23:54 livingston: what's the business plan for that thing?

23:55 ibdknox: What do you mean exactly? Right now it's mostly just sitting there with a few folks using it

23:56 Got screwed over by the contracts of a couple competitors

23:56 livingston: I mean how do they plan on monitizing "i'm going to let you use a lot of my bandwidth for free"?

23:56 ibdknox: ah, totally misunderstood. For whatsapp? I have no idea. I can only imagine their magical 1 million connections are all dormant

23:57 livingston: yeah sorry I ment whatsapp

23:57 ibdknox: so in theory they're not really shelling out much money

23:57 but yeah, it's not clear how they intend to monitize

23:58 livingston: if they are going to start routing messages texts whatever that costs them something, so I was just wondering how they planed to even recoup that? unless the whatapp app has a high enough cost

23:59 ibdknox: $0.99 doesn't seem like enough to cover a user over the lifetime of use

Logging service provided by n01se.net