#clojure log - Aug 19 2011

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

0:01 talios: cemerick: want milk and cookies, and a story? :)

0:01 cemerick: talios: Yes, please.

0:01 Now talios has to deliver :-P

0:02 talios: There was once a developer called Chas who...... BED TIME!

0:10 sshack: hi, stupid question. But I saw a website for I think a literate clojure documentation package, but can't remember it now.

0:10 cemerick: marginalia

0:10 sshack: The website had documentation on the left, clojure code on the right, anyone remember what that was?

0:11 dnolen: alandipert: got an example of matching on a single expression?

0:14 alandipert: dnolen: http://alan.dipert.org/post/172774481/fizzbuzz-in-scala

0:15 up there with fib as a crucially important algorithm to our science, i know :-)

0:15 but porting of which is what caused me to feel like something was missing

0:19 dnolen: alandipert: so how would you improve over this? https://gist.github.com/1156032

0:20 just that you can use expressions where a & b are?

0:22 sshack: yah ha! marginalia

0:22 That's what it was.

0:23 alandipert: dnolen: https://gist.github.com/1156032#comments

0:24 dnolen: alandipert: yeah no need for a different macro.

0:24 alandipert: dnolen: i agree

0:25 kencausey: sshack: there's a google group for it now also, not terribly active as of yet

0:25 sshack: Cool.

0:27 alandipert: looking at old scala, i think that 'missing' feeling is from cases that in clojure would be multimethod

0:27 dnolen: thanks for indulging me though! having fun experimenting

0:28 dnolen: alandipert: cool! any other feedback so far?

0:30 akov: when i try to (eval (list my-fn (list 1 2 3))) i get an ExceptionInInitializerError exception, but using the function straight up (my-fn (list 1 2 3)) works fine, am i misunderstanding what eval does?

0:32 raek: akov: you need to quote the symbol too

0:32 (eval (list 'my-fn (list 1 2 3)))

0:32 amalloy: raek: that will fail too: 1 isn't a function

0:32 raek: of course... :)

0:33 amalloy: (eval `(my-fn (list 1 2 3)))

0:34 akov: both of those seem to work

0:35 raek: (1 2 3) is not a valid expression, since 1 isn't a function

0:36 alandipert: dnolen: not yet, need to use it more

0:39 dnolen: did you mean to have y and z rows in the 'or patterns' section of the readme? because there is a mismatch

0:40 amalloy: i wonder if the fact that IFn isn't a protocol, in either clj or cljs, is related to the fundamental-ness of lambda? like, you can build anything out of lambdas, and thus you shouldn't try to rebuild lambda in a hosted environment

0:40 dnolen: alandipert: oops

0:44 alandipert: i can't decide if it would be nice or confusing if you didn't need a vector for your pattern in the single-row case, precedent being condp

0:45 dnolen: but enough syntax bitching from me for tonight :-) see you later

0:46 dnolen: alandipert: thx for the feedback, good stuff

0:48 alandipert: exprs now supported.

0:49 alandipert: dnolen: neat! hopefully not at the expense of anything?

0:50 dnolen: alandipert: nope, match design is fairly clean, such extensions are not hard.

0:51 alandipert: https://github.com/swannodette/match/commit/28e0ee49a3a7737e07bb8799d966edaff1f1026e

0:52 10-15 lines or something

0:52 that diff looks big because of reformatting.

0:57 alandipert: single match support back in

0:58 alandipert: don't need to wrap in vector

0:59 alandipert: dnolen: you're a machine. so you don't think that makes it confusing?

0:59 tbatchelli: scottj: better now? (re: disclojure tweet links)

0:59 dnolen: alandipert: I don't think so. I don't think we'll hype that you can do it. But some people will like it.

1:00 alandipert: really I just transform back into vector wrapped form.

1:01 alandipert: dnolen: cool

1:04 scottj: tbatchelli: I'd say worse, I think links are harder than normal text to read so more is worse imo

1:05 tbatchelli: gotcha

1:05 scottj: tbatchelli: I guess one option would be only have one link in the body of the text, or maybe make the person's name the here link.

1:05 tbatchelli: I think that'd be confusing

1:05 but I hear you

1:08 scottj: yeah I agree the person's name would be confusing, but it would grant technomancy's original(?) wish of having unique names for the links

1:10 tbatchelli: scottj: I think I am going with adding an MD5 hash and making this the link then ;)

1:10 scottj: haha

1:10 tbatchelli: scottj: I could tone down the style on the links

1:10 i.e. not bold

1:11 scottj: the thing is, in conkeror to follow a link you can either type part of the name or a number that's over it, so really the here is not that hard to type

1:11 tbatchelli: oh I'm not seeing your css since I'm viewing in reader

1:11 actually on the page it looks better

1:11 it's underlined links that I think are harder to read when they're long

1:11 tbatchelli: oh, I didn't try it that way

1:11 scottj: it might just be me

1:12 tbatchelli: scottj: I see it now

1:13 checking planet clojure now… to see how it looks (planet clojure bungles my posts because it doesn't honor the unsorted list tag)

1:13 (it's not there yet)

1:13 well, I'll let it be there and see what other feedback I get...

1:14 scottj: yeah, just to be clear I'm fine with yesterday's behavior (descriptive links in tweet) combined with today's (single link per tweet, othe rlinks go in your comments)

1:17 kencausey: tbatchelli: don't forget the relevant comment at the bottom of today's entry

1:18 actually I guess it is still accurate, I forget how short tweets tend to be

1:19 tbatchelli: kencausey: ?

1:20 kencausey: tbatchelli: not relevant I guess, I thought for a moment that your comment about formatting in your most recent blog entry was now inaccurate due to further changes

1:21 tbatchelli: kencausey: gotcha. No, I left it as is, and I'll collect the hate mail during the next few days ;)

1:22 it's hard to find a system that works for everyone across browsers and RSS readers

1:22 I think I'll just write an iOS app for that ;)

1:40 bool_: anyone have any suggestions for https://github.com/bool-/clojure-dict/blob/master/src/anthony/dict/dictclient.clj

1:40 essentially i'd like to abstract some more of the parsing code

1:41 amalloy: bool_: you wrote the same code over and over a lot of times

1:41 bool_: yeah

1:41 i noticed that

1:41 working on it now

1:47 amalloy: bool_: i forked it with an example of how you can pull out the repetition in client/auth

1:48 you should be able to generalize that to define and match, probably by making action take a function that decides what other stuff to do

1:48 bool_: yeah

2:10 amalloy,

2:10 ffs

2:10 one sec clipboard is borked

2:10 https://github.com/bool-/clojure-dict/blob/master/src/anthony/dict/dictclient.clj

2:10 there

2:10 i changed it up a bit

2:10 can't think of how to do define

2:10 as it gets two lines as a response before the text block

2:10 instead of one

2:11 amalloy: ugh, all this (declare) shit is making me dizzy. is there a reason you're not just defining things in the order you use them?

2:12 bool_: i just prefer it at the end

2:12 i have no idea why

2:12 old habits

2:15 amalloy: i still think it's easier if you make (push-command) return a function instead of actually doing anything

2:16 bool_: why is that? =O

2:16 amalloy: also, instead of (let [text-responses [...]] (if (some #{code} text-responses))), it's faster and clearer to write (let [text-responses #{...}] (if (text-responses code)))

2:17 bool_: iirc you're used to functional programming, right? but in haskell or ml or something?

2:17 bool_: uhm, i wouldn't say used to it

2:18 i've done very little in haskell

2:18 i've been an imperative guy for pretty much the extent of my programming life

2:18 amalloy: i mean, mostly it's just an aesthetic opinion i have, and i'm sure people would disagree with me

2:18 bool_: i see

2:19 amalloy: but it has benefits. here for example, it means you could add an extra optional arg to the "function" version of push-command

2:19 and you don't have to keep repeading-and-passing conn-info all over the damn place

2:20 bool_: hmm i didn't think about

2:20 that

2:20 amalloy: (def define (push-command "DEFINE" (fn [& args] (...special post-processing for DEFINE here...))))

2:20 bool_: it doesn't need post-processing though =P

2:21 it needs it pretty much in the middle

2:21 amalloy: well it needs whatever. i dunno

2:21 bool_: basically you get two responses 150 and 151

2:21 then a text block

2:21 most are just response then text block

2:21 define is the only exception

2:21 amalloy: whereas all the others can be minimal: (def auth (push-command "AUTH")). no need to declare arglists, or mess with conn-info

2:22 bool_: the arguments manually prevents user-error though

2:22 amalloy: *nod*

2:22 bool_: that's the main reason i like that

2:22 amalloy: if you want to keep that, you can specify how many args to expect: (def auth (push-command "AUTH" 2))

2:22 bool_: expecting a number of args isn't the same as which args they are

2:23 amalloy: *shrug* okay

2:23 bool_: someone could still muck them up simply because they aren't labeled

2:36 Pupeno: Clojure is driving me crazy. Is there a way to get actual stack traces? I'm only getting errors such as "org.postgresql.util.PSQLException: FATAL: role "lobos" does not exist (config.clj:1)" and the line 1 of config.clj is the namespace declaration, so it doesn't say much.

2:49 kencausey: Pupeno: sounds like an authentication error

2:55 Pupeno: kencausey: I know… but that doesn't help.

2:56 kencausey: I need a stack trace… and I'm not talking about this specific error. For the past two or three days I been getting one liners, totally useless.

2:58 kencausey: all related to the same library or?

3:04 maacl: I am trying to using cake swank and Emacs for developing a compojure based webapp, but am having trouble debugging it. Where is for instance output from println sent? Also what is a good way of debugging XHR requests? the wrap-stack trace (in Chrome) opens a window containing unparsed html which cannot be closed.

3:15 thorwil: maacl: print output should appear on the repl from were you started the server

3:15 (at least, that's what happens with a jetty started on a lein repl)

3:16 maacl: thorwil: Ok, I start it from within the file and was expecting something in *slime-events*

3:17 Pupeno: kencausey: right now, yes, but it happened to me in other cases too.

3:25 maacl: thorwil: I don't get any output even if I start it from the REPL within emacs

3:27 kencausey: even in the simplest of test examples, not involving your webapp?

3:29 MasseR: Can I browse what symbols a ns exports?

3:33 maacl: kencausey: yes, if just call a function in the webapp from the REPL I see the result of println statements

3:34 clgv: MasseR: see ##(doc ns-publics)

3:34 lazybot: java.lang.SecurityException: You tripped the alarm! ns-publics is bad!

3:34 clgv: ups

3:34 ##(doc 'ns-publics)

3:34 lazybot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

3:35 clgv: ##(eval "(doc ns-publics)")

3:35 lazybot: java.lang.SecurityException: You tripped the alarm! eval is bad!

3:37 clgv: MasseR: well just see ns-publics - the bot doesnt like me ;)

3:38 MasseR: Yup, thanks

3:38 amalloy: clgv: ns-publics isn't allowed since it's a security risk

3:38 sorta

3:38 clgv: amalloy: an exception for doc or a proxy command for doc would be handy ;)

3:39 the proxy could just be a function and take a given symbol

3:40 amalloy: clgv: file an issue on https://github.com/cognitivedissonance/clojail - it has some special handling for doc, and giving it more might not be that hard

3:40 you could probably write a $doc command yourself if you wanted; getting special handling for (doc) in ordinary evals is harder

3:41 (the $doc command would have to be on lazybot)

3:41 clgv: yeah^^ like source and such

3:44 amalloy: lazybot: whaddaya say, do you want a $doc command???

3:44 lazybot: amalloy: Yes, 100% for sure.

3:45 clgv: lol

3:45 lazybot: you always agree with amalloy? :P

3:46 ibdknox: lol

3:46 you don't have the magic touch ;)

3:46 clgv: lazybot: you always agree with amalloy???

3:46 lazybot: clgv: Oh, absolutely.

3:46 clgv: ;)

3:46 ibdknox: botsnack

3:47 hm

3:47 lazybot: botsnack

3:47 lazybot: ibdknox: Thanks! Om nom nom!!

3:47 amalloy: is there anything better than a botsnack??

3:47 lazybot: amalloy: Definitely not.

3:47 ibdknox: hah

3:47 I'm sensing a pattern :-p

3:48 amalloy: ibdknox: new feature, inspired by fsbot in #emacs

3:48 ibdknox: haha fun

3:50 lazybot: are you tired??

3:50 lazybot: ibdknox: Definitely not.

3:50 maacl: What is the best way to generate debug information when using cake swank and emacs slime to develop a compojure app?

3:52 ibdknox: amalloy: wow, lazybot can do quite a lot

3:52 amalloy: ibdknox: most industrious lazy guy i know

3:52 ibdknox: haha

3:55 lazybot: 8ball

3:55 lazybot: ibdknox: You may rely on it.

3:56 ibdknox: lazybot: elite hacker

3:56 lazybot: h4ck3r

3:58 ibdknox: lazybot: fortune

3:58 lazybot: I have no fortune cookies. Please feed me some!

3:58 amalloy: ibdknox: try the ping plugin. one of the most useful

3:59 ibdknox: lazybot: ping

3:59 lazybot: ibdknox: Ping completed in 0 seconds.

3:59 ibdknox: lazybot: ping google.com

4:00 lazybot: ibdknox: FAILURE!

4:00 amalloy: ibdknox: actually there are two ping commands. one of them sucks

4:00 ibdknox: lol

4:00 amalloy: try: "amalloy: ping"

4:00 ibdknox: amalloy: ping

4:00 amalloy: yeah ibdknox what's up

4:00 ibdknox: lol

4:00 amalloy: (he /msgs you even if i'm too much of a jerk to highlight you)

4:01 ibdknox: yeah

4:01 haha

4:01 that's cool

4:01 lazybot: list

4:01 lazybot: I know about these topics:

4:01 amalloy: ibdknox: he also doesn't care what channel you ping from. i sometimes send him a private msg like "ibdknox: ping"; then he lets me know when you're around, without me having to bother you

4:02 ibdknox: oh nice, that's actually really useful

4:02 amalloy: *nod*

4:02 ibdknox: that addition of the milliseconds is a nice touch :-p

4:02 haha

4:03 I know *exactly* when someone shows up

4:03 the ultimate in stalking software :D

4:03 amalloy: ibdknox: not usually

4:03 it only tells you the two most-significant time units

4:03 ibdknox: ah

4:03 amalloy: eg, "1 hour and 42 minutes"

4:03 ibdknox: that's no fun :-p

4:04 amalloy: heh. well, i did it on purpose. fork it and take out the (take 2) :P

4:04 ibdknox: lazybot: thoughts?

4:04 lazybot: markov

4:05 hm

4:05 amalloy: ibdknox: disabled

4:05 ibdknox: ah

4:05 amalloy: i wrote the markov plugin and it worked fine, but when i added the mongo persistence layer it turned to total crap

4:05 $login

4:05 lazybot: You've been logged in.

4:05 amalloy: $loaded?

4:05 lazybot: :brainfuck :clojure :debug :dictionary :eball :embedded :fortune :github :google :haskell :help :internal :javadoc :karma :leet :lmgtfy :load :log :logger :login :macro :mail :max :mute :operator :ping :rss :sed :seen :shorturl :timer :title :translate :utils :weather :whatis :yesno

4:05 clojurebot: $what is love

4:05 lazybot: It's AWWWW RIGHT!

4:05 amalloy: hahahaha

4:06 ibdknox: lol

4:06 lazybot: lmgtfy irc

4:06 lazybot: http://www.lmgtfy.com/?q=irc

4:07 ibdknox: lazybot: brainfuck

4:07 lazybot: bf +++

4:07 lazybot: {:ptr 0, :cells {0 3}}

4:07 []

4:07 ibdknox: just because? lol

4:07 amalloy: ibdknox: i dunno. Raynes wrote a lot of plugins

4:08 ibdknox: it is interesting to see how simple a turing complete language can be

4:08 lol

4:08 that plugin is 73 lines

4:08 the part that does the evaling at least

4:09 amalloy: that seems kinda long, given the language. i've never looked at most of the plugins

4:09 ibdknox: lazybot: weather

4:09 amalloy: $weather 94109

4:09 $fcst 94106

4:09 lazybot: amalloy: Location not found!

4:09 ibdknox: amalloy: it's well spaced and such

4:09 amalloy: feh

4:09 $fcst 94109

4:09 lazybot: amalloy: 1:30 PM PDT

4:09 amalloy: TODAY: Mostly clear in the evening then becoming mostly cloudy. Patchy fog after midnight. Lows in the mid 50s. West winds 10 to 15 mph.

4:09 amalloy: TONIGHT: Mostly cloudy. Patchy fog in the morning. Highs near 60. Southwest winds 10 to 15 mph.

4:10 ibdknox: $ is a shortcut to get it to execute a command?

4:10 $lmgtfy brainfuck

4:10 lazybot: http://www.lmgtfy.com/?q=brainfuck

4:11 ibdknox: $botsnack

4:11 lazybot: ibdknox: Thanks! Om nom nom!!

4:11 ibdknox: ok

4:11 I've had enough fun with the bot

4:11 amalloy: is there any such thing??

4:11 lazybot: amalloy: Definitely not.

4:11 ibdknox: haha

4:12 time for sleep!

4:12 G'nite sir.

4:12 amalloy: night

4:13 clgv: is there any such thing???

4:13 lazybot: clgv: Oh, absolutely.

4:13 clgv: hehe ok confirmed

4:17 Pupeno: WTF? loading a file in lein repl works and in La Clojure it doesn't.

4:19 lnostdal_: j #java

4:41 Pupeno: Anybody know what might be wrong with La Clojure's command line: https://groups.google.com/forum/#!msg/lobos-library/oXLDpGFsAwU/Zr8MA-9fUPEJ ?

5:01 clgv: Pupeno: you might try to delete entries until you find something working and then adding again until you find the maximal working entryset, then you should know the problem

5:01 Pupeno: clgv: I removed all the jars from La Clojure, and it still fails :(

5:02 The command still looks quite different though, but that's as close as I can get with La Clojure.

5:02 clgv: the other way would be: under what circumstances can it happen that the role "lobos" is not created?

5:05 Pupeno: clgv: the role lobos doesn't exist and that's ok. The weird thing is that it's being used at all. Loading the file shouldn't ever try to do that, but somehow, it does, only in La Clojure.

5:05 clgv: hmm sounds like pretty weird side-effects. check the places where you have side-effects in that file

5:13 Pupeno: Well, in emacs it seems to work.

5:28 clgv: I removed all side effects and found that adding a jar is triggering the problem: https://groups.google.com/d/msg/lobos-library/oXLDpGFsAwU/92akh2KXIHoJ

5:43 Raynes: $mail idbknox I took that brainfuck code from rosettacode. Never even looked at it. Just noticed it worked and threw it in. If it's a monstrosity, I had *nothing* to do with it. ;)

5:43 lazybot: Message saved.

6:02 clgv: Pupeno: humm you have a dependency called lobos? does it have the namespace lobos.*? if so why do you also use that namespace? is it possible that lobos.config already exists in the lobos-dependency?

6:04 maacl: Can someone *please* tell me where std our directs to when using cake swank with Emacs/Slime?

6:04 Pupeno: clgv: yes, there's a dependency called lobos, it doesn't create a lobos.config namespace but expects a lobos.cofig to be created.

6:05 clgv: Pupeno: so maybe it has the default of using a role called lobos if you dont specify a different one?

6:06 Pupeno: clgv: it doesn't, the creator of Lobos doesn't know where that error is coming from and it only happens with La Clojure, not with lein repl.

6:09 Raynes: maacl: Very likely <project>/.cake/cake.log

6:09 That's where all input and output goes to die.

6:09 maacl: Raynes: thank you, will look there

6:11 Raynes: btw, are you going to the conj this year?

6:11 Raynes: maacl: Absolutely.

6:18 maacl: Any particular reason for asking, or do you plan on stalking me? ;)

6:18 maacl: Raynes: No, I just recalled last year and wondered if it was possible for you to go

6:18 Raynes: maacl: This year I have a job. :>

6:19 maacl: Raynes: Well that is both good and bad :-)

6:21 Raynes: maacl: Did cake.log have what you were looking for?

6:21 maacl: Raynes: yes, thanks a lot. I have been asking all morning with no response

6:22 Raynes: maacl: When that happens, the best place to go is the cake mailing list, where you *know* we'll see it.

6:22 maacl: Raynes: good to know

6:22 * Raynes is off to sleep.

6:22 Raynes: Later. :)

8:52 `fogus: dnolen: The video of your talk is a master-class in the state-of-art in pattern matching. Great job.

8:52 ambrosebs: +1

8:52 dnolen: `fogus: thx!

8:52 opqdonut: link please?

8:54 pyr: indeed great talk

8:54 Scriptor: opqdonut: http://vimeo.com/27860102

8:55 `fogus: dnolen: Do you have a list of influential papers/presentations? I need to make sure I'm up to speed.

8:55 opqdonut: yay, finally pattern matching

8:56 nachtalp: `fogus: there's a list on the github page

8:57 dnolen: which I need to rearrange

8:57 done

8:58 `fogus: Maranget paper, Predicate Dispatch paper, and the Racket paper on Extensible Pattern Matching.

9:04 `fogus: dnolen: This guy? http://cristal.inria.fr/~maranget/

9:04 dnolen: `fogus: yep.

9:04 `fogus: dnolen: Practical Predicate Disp?

9:05 dnolen: Efficient Predicate Dispatch, http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.47.4553

9:05 `fogus: Great! One down. ;-)

9:05 dnolen: Compiling Patterns to Good Decision Trees, http://pauillac.inria.fr/~maranget/papers/ml05e-maranget.pdf

9:05 `fogus: Thank you sir

9:05 dnolen: Extensible Pattern Matching For Extensible Languages, http://www.ccs.neu.edu/home/samth/ifl2010-slides.pdf

9:07 `fogus: dnolen: Do you typically hold court here? That is, do you have a mailing list, group, etc.?

9:08 arohner: `fogus: lol, hold court. I'm going to use that

9:08 `fogus: Sorry, I hold the patent on that particular sequence of words

9:08 algal: hello. newbie question. Is macports the recommended way to install clojure on os x? I expect to use it via my existing slime / aquamacs install.

9:09 arohner: algal: I use lein

9:09 dnolen: `fogus: mostly in here and on ML yeah. no mailing list or group for match yet. Not sure if it needs one really :)

9:09 arohner: algal: and unless you're lucky, an existing CL slime isn't compatible

9:09 algal: arohner: this is actually my problem. When I tried using macports to install clojure, the install of leiningen failed.

9:10 arohner: ugh.. You mean I need to maintain two different slime installs?

9:10 arohner: algal: yeah, sorry :-(

9:10 d/l lein from here https://github.com/technomancy/leiningen

9:10 manutter: algal: there was a guy here yesterday talking about setting up emacs to support both CL slime and Clojure slime

9:11 algal: (loved the short story, btw)

9:11 manutter: I think it was a user named rpg

9:11 algal: manutter: I thought he'd be at #arc.

9:12 Slightly confused. I thought leiningen was more a built tool rather than a development envrio... Hmm.. I should do my homework before bothering you chaps.

9:13 manutter: more seriously, is there a channel bot with yesterday's traffic?

9:14 manutter: There's an online log somewhere, I saw a link once...hmm...

9:14 dnolen: http://clojure-log.n01se.net/

9:14 algal: okay. googling clojure irc logs pulls it. sorry again.

9:33 chouser: dnolen: sorry if this is a dumb question, but for predicate dispatch couldn't the DAG be a function full of the same kind of cond forms that match produces?

9:34 dnolen: basically re-generating a new dispatch function each time the predicate is extended.

9:35 It would consume PermGen, but only when a user is defining a new function of their own anyway

9:38 dnolen: chouser: the dag would be a fn I think yes, but we don't want to eval. So perhaps a fn with a bunch of cond tests that actually gets their tests out of an object array is what I've been thinking.

9:39 MasseR: I'm learning clojure, and thought about implementing markov chain for text generation. My current version for creating the database is like this: http://pastebin.com/mX7vNz0f, but I get a stack overflow. What steps should I take it prevent that?

9:40 Chousuke: MasseR: use (rest xs) instead of (drop 1 xs) for starters

9:40 chouser: dnolen: I'm not sure you'd need eval. If extend-pred is a macro, it could generate the new dispatch function code and emit it along with whatever else it has to do.

9:41 Chousuke: also merge-with concat might be a problem, since concat creates a lazy seq always

9:41 dnolen: chouser: problem is that could be a LOT of code. decision trees are exponential. that's why people use backtracking.

9:42 better I think to convert the decision tree into a DAG with sharing.

9:42 MasseR: Chousuke: What should I use instead?

9:43 chouser: dnolen: ok, I'm willing to trust you've thought these things through. :-)

9:43 Chousuke: MasseR: since the value things are put in a vector, try merging with into

9:43 dnolen: chouser: Maranget shows in his paper that for real world match expressions it's rare for decision tree code to be more than 1.5-2X the size of the backtracking code.

9:44 chouser: however when we start treading into open set, I think you have to really think about how much code is getting produced.

9:44 Chousuke: ,(merge-with into {:a ['b]} {:a ['c 'd]})

9:44 clojurebot: {:a [b c d]}

9:45 MasseR: Oh nice, seems better now. At least from memory perspective. Thanks

9:45 chouser: dnolen: it just seems a shame to walk away from the nested 'if's that match produces, and all that hotspot can do with them.

9:46 Chousuke: MasseR: you can do destructuring in the function argument vector directly btw

9:46 tibell_: cgrand around?

9:46 @seen cgrand

9:46 Chousuke: MasseR: so the value function could just be (defn values [[x & xs]] ...)

9:46 MasseR: without the let

9:46 MasseR: Chousuke: Yes I know. I actually used to do that, but a lot of the "literature" around seems to prefer explicit taking/dropping/head/etc

9:46 dnolen: chouser: definitely.

9:46 MasseR: Oh that

9:47 Chousuke: MasseR: (rest foo) is always preferable to (drop 1 foo) though

9:47 MasseR: I had some syntax quirks, I tried with (defn [[x & xs] foo] ..

9:47 Chousuke: yeah that defines two arguments

9:47 one that gets destructured and another that doesn't.

9:48 MasseR: your makedb function can also be expressed without an explicit loop though

9:49 MasseR: Chousuke: If you mean (defn makedb [xs db] ( .. recur (rest ..) then I prefer my version

9:49 No need to create a wrapper function for easier calling

9:49 Chousuke: MasseR: no

9:50 (apply merge-with into (map values (partition 3 1 (words x)))) or something

9:51 MasseR: Hmm.. partition is handy.

9:52 Chousuke: MasseR: it might not behave the way you want if the number of elements is not evenly divisible though. check the docs because I don't remember the details

9:53 MasseR: Chousuke: Yup it apparently disregards those with length < 3

9:53 Chousuke: you can give it padding or something I think

9:53 manutter: partition-all

9:53 ,(doc partition-all)

9:53 clojurebot: "([n coll] [n step coll]); Returns a lazy sequence of lists like partition, but may include partitions with fewer than n items at the end."

9:53 Chousuke: oh, right

9:54 MasseR: it'll take a while before working without explicit loops becomes second nature, but keep in mind that they are seldom needed

9:55 manutter: it would be interesting to see that function expressed as a reduce

9:55 Chousuke: infinite lazy sequences get you far

9:55 MasseR: Chousuke: I actually have experience with Haskell, but as it doesn't have (easily) available partition, those functions that require more than 1 value are a bit .. unnatural

9:55 Chousuke: manutter: well you can replace apply in my version with reduce but it'll be less efficient

9:56 and will need a starting value

9:57 MasseR: Hmm.. Not sure I like how slimv changes my cw behaviour

9:57 manutter: isn't apply more likely to blow the stack, though? (not that I know what I'm talking about, but I thought I heard something about apply realizing the seq before passing the args to the function)

9:58 MasseR: manutter: Seems to work fine

10:01 manutter: well allrighty then

10:05 Chousuke: manutter: no

10:05 manutter: apply is lazy if the function is lazy

10:12 rpg: algal: Were you asking about my experience with swank/slime?

10:17 xian: Hi. I'm looking for a function like iterate but which takes no second argument, i.e. (take 4 (simple-iterate gensym)) => (G__3330 G__3331 G__3332 G__3333)

10:18 Chousuke: repeatedly?

10:18 xian: Yes, just like iterate without the second argument.

10:18 Chousuke: (doc repeatedly)

10:18 clojurebot: "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it"

10:18 Chousuke: :P

10:19 xian: lol, okay :)

10:19 * xian feels dumb

10:20 MasseR: Apparently good, descriptive function names have their cons too :D

10:23 manutter: rpg: algal was asking about running dual Clojure/CL slime setups under aquamacs

10:24 rpg: manutter: I didn't really find a good solution: what I do is have a defvar, lisp-mode-to-use that takes one of three values: slime (CL slime); allegro (Franz's ELI mode) or nil (none). The last is compatible with technomancy's clojure-jack-in

10:24 You can't really have a clojure-compatible SLIME version and an up-to-date CL SLIME version coexist.

10:24 mrBliss: rpg: I use this https://github.com/mrBliss/swank-clojure

10:25 rpg: My personal belief is that at some point the clojure community should fork SLIME, rename it so it doesn't conflict with the CL version, and then be free to turn it into a full-fledged clojure interaction mode.

10:26 manutter: doesn't sound like a bad idea (except that "forking slime" sounds like a name you'd call someone you really didn't like...)

10:26 rpg: I just don't think that a stable interaction can ever happen given the lack of a release mechanism for CL SLIME.

10:27 manutter: maybe "slime on a fork" would be better? ;-)

10:28 manutter: heh

10:28 rpg: mrBliss: thanks for the pointer. Very interesting....

10:29 manutter: My experience crashing swank-clojure by trying to use the "sync package name and directory" command still stings! ;-)

10:39 sleepynate: grr seq? vs. sequential?

10:41 chouser: sleepynate: depends on what you mean, I'm afraid.

10:41 algal: rpg: Yes, I was!

10:41 chouser: we've got a gnarly section in JoC that tries to clarify that

10:41 sleepynate: chouser: see the problem with putting question marks after predicates is that you think i'm asking as oppoed to complaining :)

10:41 chouser: :-)

10:42 sleepynate: chouser: i just had a recusion going wonky due predicating on the wrong interface

10:42 rpg: algal: I was just saying: "I didn't really find a good solution: what I do is have a defvar, lisp-mode-to-use that takes one of three values: slime (CL slime); allegro (Franz's ELI mode) or nil (none). The last is compatible with technomancy's clojure-jack-in"

10:42 algal: rpg: I've got slime installed for work with CL, and I'd like to get setup for clojure without too much duplication and with a clean uninstall path..

10:42 mrBliss: algal: try this https://github.com/mrBliss/swank-clojure

10:43 rpg: algal: I get a fresh emacs started up with no SLIME loaded at all, and then I use the "clojure-jack-in" facility (from technomancy's "radical simplification" blog post).

10:43 algal: mrBliss: thx. will check it.

10:43 rpg: algal: I have to do this cumbersome process of resetting the lisp-mode-to-use in my .emacs then starting a fresh emacs. But I have ALREADY had that problem, since I use both Franz's ELI and SLIME on different occasions, and they are incompatible.

10:46 mrBliss: rpg: I prefer my solution, I can fire up a Clojure and a CL (SBCL in my case) repl at the same time (same instance!)

10:46 algal: rpg: hmm.. ok. I'm only on SBCL so I'm not already committed to having to restart emacs for slime purposes.. It would be nice to avoid if possible.

10:47 rpg: mrBliss: Sounds good. In the end I decided I wasn't really willing to maintain a merged SLIME for myself alone. Seemed like it would be fighting the upstream maintainers too much. But more power to you for doing it!

10:48 algal: mrBliss: intriguing. so is this your fork of swank-clojure? or is this the standard swank-clojure ?

10:48 rpg: Again, my personal opinion is that having SLIME be the clojure mode is kinda like trying to use Python mode to program perl ;-) We'd just be better off with a separate Clojure interaction mode.

10:49 But since I don't know nearly enough clojure to do that, my opinion is of course not worth much to the people who actually do the Real Work involved.

10:49 mrBliss: algal: my fork differs only by a couple of changes. The SLIME protocol chaned a bit, and TerjeNorderhaug updated swank-clojure.

10:49 algal: rpg: you mean we need a SLIME fork dedicated to clojure?

10:50 rpg: algal: Yes, and with all uses of "slime-" changed to "scime-" or something.

10:50 no_mind: anyone here from clojure-conj organizing committee ?

10:50 mrBliss: rpg: it's not a merged version of SLIME, it's just a snapshot of SLIME. Like the one used with clojure-jack-in, but not stripped-down. It's a later snapshot that includes backends for other Lisps and slime-contrib.

10:51 algal: Do either of you chaps know if ELPA helps with this at all? For instance, does ELPA offer separate SLIME packages for CL and clojure?

10:51 manutter: rpg: name it CRIME: Clojure REPL Interaction Mode for Emacs.

10:51 :)

10:51 mrBliss: algal: the one on ELPA are only compatible with clojure

10:51 sjl: manutter: If there's a synonym for "interaction" that starts with a U we could have SCUM

10:52 mrBliss: s/are/is

10:52 lazybot: <mrBliss> algal: the one on ELPA is only compatible with clojure

10:52 rpg: mrBliss: I think it's great you did this, but isn't it a real uphill battle to try to identify a stable build of SLIME? The community of SLIME maintainers doesn't seem to be interested in supporting that idea.

10:52 mrBliss: rpg: hugoduncan found a stable build, see the README :-)

10:52 rpg: I am VERY impressed with the SLIME maintainers and their project, but I wish they were willing to issue releases instead of just commits...

10:53 algal: rpg: agreed.

10:53 rpg: mrBliss: I understand, but going forward is someone committed to repeatedly finding such a stable build? Stable for both CL and Clojure? *And* continuing to paper over the differences between the lisps?

10:54 mrBliss: rpg: I'm not trying to keep swank-clojure compatible with the HEAD of SLIME, but just with a not stripped-down version that offers the functionality I need and is compatible with CL.

10:54 MasseR: I remember there being a function which takes a map and a path. For example (überget x :attrs :number)

10:54 mrBliss: MasseR: ##(doc get-in)

10:54 lazybot: ⇒ "([m ks] [m ks not-found]); Returns the value in a nested associative structure, where ks is a sequence of ke(ys. Returns nil if the key is not present, or the not-found value if supplied."

10:55 rpg: mrBliss: Sounds great. I'm all for it!

10:55 MasseR: mrBliss: Thanks

10:56 rpg: mrBliss: so you try to keep your version of swank-clojure in sync with https://github.com/pallet/ritz/tree/master/slime ?

10:56 algal: what do most clojure programmers use? Is emacs in the minority b/c everyone's hanging on to netbeans/eclipse/etc..?

10:56 mrBliss: rpg: that version doesn't change, so it's an easy job :-)

10:56 rpg: do you know of any new features in SLIME that we're missing?

10:57 rpg: mrBliss: but eventually, surely, you'd want some of the new stuff (like nikodemus's cl indentation improvements), if you are also a CL developer, right?

10:57 (note: I don't know what's in the hugoduncan fork, and what isn't...)

10:57 sjl: algal: I use MacVim + SLIMV + a few VimClojure files. It's a bit of a mess.

10:58 algal: sjl: Yeah, that does sound awkward.

10:58 mrBliss: rpg: it's just the protocol stuff that can cause problems, cl-indentation shouldn't be a problem. I haven't actually tried the SLIME @ HEAD with this version of swank-clojure, so it's possible it works without problems

10:59 sjl: algal: Once you learn the idiosyncrasies of it it's not too bad. And using SLIMV means all the keybindings are pretty much the same as Lisp, which is nice.

10:59 mrBliss: rpg: hugoduncan just took a snapshot of SLIME trunk some time ago, he didn't actually remove anything (that I know of).

10:59 coopernurse: I've been happy with IntelliJ + La Clojure + lein -- REPL just seems to work, and IntelliJ will pick up on JARs downloaded by lein if you add the lib dir to your intellij module

10:59 algal: sjl: yes. I can learn a new language but not new keybindings.

11:00 mrBliss: algal: 61% of Clojure users use Emacs + SLIME according to http://cemerick.com/2011/07/11/results-of-the-2011-state-of-clojure-survey/

11:01 algal: mrBliss: interesting. but the situation is still so horked that there's no standard way to handle an emacs install used for CL and clojure.. odd.

11:02 bioinformaticsze: Can anyone recommend a persistent value store for working with clojure? I was going to try tokyo-cabinet but I thought it worth checking if there was a more commonly used clojure library/store.

11:02 cemerick: algal: Wanting to do both is unusual. The shenanigans that happen upstream in SLIME apparently don't help.

11:02 sjl: Really? That's weird. Vim works fine with both (just not connected to both at the exact same time).

11:04 algal: cemerick: shenanigans == churn with no stable releases ?

11:04 coopernurse: bioinformaticsze: how big is your data set? if it can fit in RAM then I've had good luck with Redis

11:05 cemerick: algal: that and "just use cvs HEAD"

11:05 algal: cemerick: yeah, I had to read that one twice the first time I saw it. Does it mean "b/c HEAD is *that* stable" or "because you can cope with *THAT* much instability".

11:05 bioinformaticsze: coopernurse: It's around 400 - 600k entries, each with a 200-400 character string.

11:06 cemerick: algal: …or "because we don't give a…"

11:06 bioinformaticsze: I have 4GB of RAM.

11:06 I guess that might be possible?

11:06 coopernurse: bioinformaticsze: ok, so ~500MB - yes, Redis would work with that data set

11:07 algal: cemerick: what annoys me more than the lack of stable releases is the paucity of the documentation. I mean, I have a hunch there's a decent stepping debugger interface in there somewhere, but where?

11:07 bioinformaticsze: coopernurse: Can you point me to the library?

11:07 coopernurse: the nice thing about it is that it has a rich set of operations for manipulating data structures, and it has a couple of persistence models depending on your read/write mix

11:07 tomoj: bioinformaticsze: if you wind up using redis you might check out the redis client in aleph

11:07 cemerick: algal: for CL, yes, IIRC; for Clojure, I don't think so.

11:07 tomoj: very minimal

11:07 but it works great

11:08 coopernurse: bioinformaticsze: https://github.com/mmcgrana/clj-redis

11:08 mrBliss: algal: http://vimeo.com/23932914

11:08 coopernurse: bioinformaticsze: http://redis.io

11:08 tomoj: oh, that's probably easier to use

11:08 bioinformaticsze: Thank you.

11:08 cemerick: algal: I remain very surprised that no one has done a hard fork or bottom-up reimpl of SLIME *just* for Clojure. But then, I'm no emacs-er, so I generally stay on the sidelines of that sort of stuff.

11:08 pyr: bioinformaticsze: for redis

11:08 cemerick: (short of shooting my mouth off in irc occasionally :-P

11:08 pyr: bioinformaticsze: i recommend also looking at jedis

11:08 tomoj: but it's synchronous..

11:09 pyr: ah, didn't see the aleph recommendation, that's good too

11:09 coopernurse: pyr: it looks like clj-redis wraps jedis in a clojure interface

11:09 bioinformaticsze: I'm still new to clojure so which ever library is easiest to use.

11:09 I'm trying out some work stuff in the clojure to see how it feels.

11:10 tomoj: don't check out aleph yet :)

11:10 pyr: tomoj: yeah, probably not the best choice to start with :)

11:10 bioinformaticsze: Ok

11:11 The clj-redis looks straight forward.

11:11 cemerick: mrBliss: I sit corrected; more good works by hugod :-)

11:12 tufflax: I can't write 'closure' anymore. I write 'clojure' (even when writing this, i failed to write 'closure' the first time (and now again!))

11:13 mrBliss: cemerick: I haven't gotten it working though

11:13 coopernurse: bioinformaticsze: excellent. yes, the operations in redis seem to map very well to functional programming

11:13 rpg: cemerick: I don't think a reimplementation is necessary; simply a fork-and-rename. As I said, I think the differences in the two languages are sufficient to suggest a different emacs framework (even if starting from the CL one is a good idea).

11:14 bioinformaticsze: coopernurse: Thank you for the recommendation

11:14 rpg: Also, the CL SLIME developers "own" the swank backend and the emacs front end and keep them in sync in the same repo. Trying to do this from outside the repo (maintaining only the swank backend) seems like a recipe for pain.

11:14 cemerick: rpg: Yeah, whatever the lead(s) want to do. It just seems like an obvious win (though of course, a ton of work) for Clojure/emacs tooling.

11:15 bioinformaticsze: Using homebrew it seems easy to get redis and leiningen working on my mac too

11:15 coopernurse: bioinformaticsze: yep, I use redis on my mac - it works well

11:16 and lein / clojars is a great combination. imho the packaging tools for clojure are what really make a solid dev platform

11:16 mrBliss: rpg: https://github.com/bigfoote/slclj is a rename of slime just for Clojure, but I still couldn't use a Clojure repl at the sime time as a CL repl with it.

11:18 bioinformaticsze: Is lein used mainly for creating clojars or can it also be used for creaing a workflow of scripts?

11:18 algal: speaking of lein, has anyone had problems using macports to install leiningen because of this bug in maven-ant-tasks ( https://trac.macports.org/ticket/30060 ) ? Or is everyone just installing it from source? or on ubuntu?

11:19 coopernurse: bioinformaticsze: lein is primarily a build / packaging tool for clojure. it supports maven, which gives you easy access to traditional Java libs. clojars is a separate project that stores clojure specific maven artifacts (libraries)

11:19 lein also has a plugin architecture, and many folks have written plugins for various applications

11:20 for example, ring has a lein plugin that will create a WAR file from your clojure web project

11:20 bioinformaticsze: Ok. Thank you.

11:20 I think I understand

11:21 Clojars is like rubygems.

11:22 And lein is like rake + bundler?

11:22 pyr: there is one big difference

11:22 bioinformaticsze: in ruby dependencies are per environment

11:22 bioinformaticsze: Sorry for the analogy, I am coming from Ruby.

11:22 coopernurse: bioinformaticsze: yes, that seems right

11:22 pyr: bioinformaticsze: in clojure (actually maven)

11:22 bioinformaticsze: they are per project

11:22 bioinformaticsze: I see

11:23 coopernurse: pyr: good point -- which is very useful for packaging / deployment

11:23 bioinformaticsze: They get vendored into the project.

11:23 pyr: bioinformaticsze: yes

11:23 bioinformaticsze: so lein, - as a maven frontend - takes the place of rvm + rake

11:23 coopernurse: bioinformaticsze: yes, but the tools are smart enough to create a local cache of JARs that are project independent (usually in: ~/.m2/repository)

11:24 bioinformaticsze: So I can use lein where I would use rake?

11:24 pyr: bioinformaticsze: short answer, yes

11:24 bioinformaticsze: That's great!

11:25 Thank you. This is very helpful to me.

11:25 pyr: bioinformaticsze: you can also get plugins for it which enhances its functionnality

11:25 bioinformaticsze: where in the ruby world you have rails as a separate command to start a new rails project

11:25 bioinformaticsze: I see.

11:26 pyr: bioinformaticsze: in clojure there is a noir plugin for leiningen, which once install lets you do: lein noir new cool_website

11:26 s/install/installed

11:26 lazybot: <pyr> bioinformaticsze: in clojure there is a noir plugin for leiningen, which once installed lets you do: lein noir new cool_website

11:26 pyr: lazybot: i love you

11:26 lazybot: botsnack

11:26 lazybot: pyr: Thanks! Om nom nom!!

11:26 bioinformaticsze: So everything can be automated/run from lein rather than clojure scripts

11:27 pyr: it's good practice to have tasks that modify the life of the software project live in lein, yes, as rake tasks to for ruby projects

11:30 bioinformaticsze: coopernurse: When you mean modify the life of the project, installing clojars etc?

11:30 I often used rake to build a set of analyses. E.g. populate a database, pull required records, analyse the records.

11:37 coopernurse: bioinformaticsze: you could use lein to automate tasks like that. I haven't done it, but the plugin model is very simple, so it would be easy to write plugins that are part of your project

11:38 that you would invoke via lein

11:38 bioinformaticsze: coopernurse: Great! Thank you. I'll have to give this a try.

11:46 Pupeno: Would you use http://www.jasypt.org/ to encrypt passwords in a web app?

11:48 algal: has anyone here looked into using clojurescript for graphics programming in the browser ?

11:48 pyr: Pupeno: no

11:48 duck1123: Pupeno: Thanks for that link. I might give this lib a try this weekend

11:48 Pupeno: pyr: what would you use?

11:48 pyr: Pupeno: https://github.com/ibdknox/noir/blob/master/src/noir/util/crypt.clj

11:49 Pupeno: this method

11:49 always you bcrypt for passwords

11:50 Pupeno: i'm a bit partial

11:50 Pupeno: pyr: how so? you wrote bcrypt?

11:51 pyr: Pupeno: no, the implementation in noir

11:51 that file

11:51 and I'm from the openbsd team, where we have a history with bcrypt

11:52 but it's now become a de-facto standard for strong hashing

11:52 http://codahale.com/how-to-safely-store-a-password/

12:05 whidden: So I was going to pose this question to #clojure :So I have a problem that deals with 3 collections of integers of various lenghts and I need to combine them into one collection such that they have some order. And in the process of writing the question the answer hit me in the face like a king salmon that had been lying on some untraveled river bank for a week. Just combine them and then sort by whatever order you wish!

12:06 If I would have posed the question sooner I wouln't have wasted a couple of hours writing a stupid loop that didn't work!

12:06 Each of you may pat yourselve on the back for giving such wonderful advise and insight!

12:14 Pupeno: I'm not sure why, but Slime seems to be appearing splitting the window vertically instead of horizontally, any ideas how to switch that?

12:15 Bronsa: Pupeno: it depends on the size of the window

12:15 Pupeno: Bronsa: I see, but how do you change it once it's done?

12:16 Bronsa: you can C-x 0 and then C-x 2

12:16 Pupeno: Thanks :)

12:41 bioinformaticsze: I'm struggling to write a plugin that can be found by lein.

12:41 Should I define my plugins under $PROJECT/src/plugin.clj ?

12:42 Then use the (ns plugin "description") syntax?

12:46 cemerick: bioinformaticsze: read https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md

12:56 bioinformaticsze: cemerick: Thanks!

12:58 PPPaul: has anyone used clutch?

13:01 cemerick: PPPaul: I'm a committer for it. Questions?

13:02 PPPaul: i'm following the github start guide

13:02 i'm getting an error when i do (:use asa...clutch)

13:02 cemerick: Sounds like either a typo or your dependencies aren't in order.

13:03 PPPaul: "could not initialize class clojure.data.json__init (utils.clj:26)"

13:03 cemerick: PPPaul: are you using lein? If so, ensure that you've run `lein deps`.

13:03 PPPaul: i did

13:03 i did lein deps

13:03 cemerick: Can you paste a full stack trace?

13:04 PPPaul: give me a sec

13:06 https://gist.github.com/1157374

13:08 does that help?

14:51 chewbranca: dnolen: yeah really like the idea of it, pattern matching is one of my favorite features from the brief exposure I've had with erlang, and as for hacker news, that video is way too much coding and theory, we really need a site like hacker hacker news or startup news lol

14:52 srid: self-organizing reddit communities?

14:52 more like -- reddit.com/r/self - where you see links relevant to *your* interests. similarly, for every other user of the site.

14:53 chewbranca: that could work, I mean I've learned a lot from hacker news over the years, but much less programming on there now

14:54 dnolen: chewbranca: yeah I feel even a year ago HN was much friendly excited about this kind of thing.

14:55 decision trees are big in AI, it's fun to see them applied to pattern matching.

14:55 AI/machine learning.

14:56 chewbranca: dnolen: so from what I understand, the order or your pattern definitions decides its priority correct? what's your thoughts on using order versus more of a declarative approach

14:56 dnolen: chewbranca: what do you mean?

14:57 chewbranca: dnolen: yeah fun to see the decision trees brought in, hadn't thought about using that, and that guy Luc has some interesting looking papers, was taking a peek at his "algebraic pattern matching in join calculus" as well

14:58 dnolen: chewbranca: using decision trees for pattern matching is an old technique. innovation here is using heuristics to simulate lazy pattern matching

14:59 chewbranca: dnolen: well I always go back and forth on order as priority, or exactness, as once you get rather large pattern matching sets going it can get tricky to track down bugs when order is a priority, although I could see that being less of an issue here

14:59 dnolen: chewbranca: are you talk about the fact that pattern matching is top down?

14:59 chewbranca: my experience with large pattern matching pain comes from nginx rules and routing in rails where overtime it can get a little tricky

14:59 dnolen: ahhh ok interesting

14:59 dnolen: yeah top down pattern matching

15:01 I've just run into situations before where you have a pattern that matches /foo/ and a pattern that matches /fooo/ and naturally you want to have the latter matched if the example is 'fooo', but you didn't order them properly so it matched /foo/

15:01 dnolen: chewbranca: never written very large patterns but I can imagine it gets complex. perhaps the next step - predicate dispatch - will shed some light how to do without the complexity.

15:01 i.e. give warning on subsumed patterns.

15:02 chewbranca: yeah I mean you could easily argue that having very large patterns is a bad design, or that you can just be more careful with how you structure them; I was just asking because its something I've been wondering about lately and you're more familiar with pattern matching than I am

15:03 dnolen: chewbranca: well the predicate dispatch approach I'm considering would use a logic engine. I'm hopeful that will 1) free you from thinking about order 2) warn you about ambiguities.

15:04 chewbranca: dnolen: very cool

15:08 nickmbailey: are github pull requests the standard way of submitting fixes to clojure contrib stuff

15:08 dnolen: nickmbailey: no you have to have submitted a CA, must to go through JIRA w/ issue + patch.

15:09 nickmbailey: didn't know there was a jira

15:09 CA stands for ...?

15:09 hiredman: ~ca

15:09 clojurebot: CA is Contributor Agreement: http://clojure.org/contributing

15:09 nickmbailey: i already sent a pull request haha

15:10 bioinformaticsze: Could anyone tell me what I'm doing wrong here?

15:10 (ns leiningen.database (:require [clj-redis.client :as redis]))

15:10 I'm getting a file not found error.

15:10 I've run lein deps

15:11 nickmbailey: good lord i have to send mail?

15:11 bioinformaticsze: I seem to be able to use the require outside of the (ns ...) list

15:11 PPPaul: cemerick!

15:13 cemerick: PPPaul!

15:13 technomancy: clojurebot: fax machine?

15:14 clojurebot: fax machine is http://achewood.com/index.php

15:14 technomancy: =(

15:15 nickmbailey: is there a way to fax/email the CA? or i really have to buy stamps for the first time in years

15:17 coopernurse: bioinformaticsze: can you post a gist of your project.clj and the .clj file you're using in src?

15:19 technomancy: clojurebot: forget fax machine |is| http://achewood.com/index.php

15:19 clojurebot: fax machine is http://tinyurl.com/ygc9w2

15:19 clojurebot: c'est bon!

15:25 bioinformaticsze: coopernurse: https://gist.github.com/1157747

15:25 coopernurse: Thank you

15:28 PPPaul: cemerick. it works! my db is alive!

15:28 cemerick: PPPaul: Fabulous.

15:28 My invoice is on its way.

15:28 ;-)

15:29 PPPaul: some neat new stuff coming to clutch soon, hopefully. Glad things are working out for you. :-)

15:30 dnolen: hmm looks like we can't really follow map destructuring style in map patterns.

15:30 chouser: ooh, why's that?

15:31 dnolen: chouser: well the keys have to be unique, shoulda noticed earlier but was busy thinking about other things.

15:32 {0 :a 0 :b} won't fly.

15:32 chouser: ah

15:32 of course

15:32 PPPaul: cemerick... what do you use for dates/times?

15:32 clj-time isn't working for me

15:33 cemerick: PPPaul: Just standard ISO date strings.

15:33 PPPaul: ok... more code for me

15:33 dnolen: chouser: it's why :as is so easy to support in Clojure, because maps are reversed in destructuring.

15:33 cemerick: PPPaul: https://github.com/cemerick/utc-dates

15:33 dnolen: chouser: so it also means we have to move :only out of the map pattern.

15:34 ({:a 0 b: 0} :only [:a :b]), not so bad really, but it was a nice dream before.

15:57 chewbranca: dnolen: ahhh interesting, just getting to the part of the video where you talk about predicate dispatch and top down ordering, I didn't even think about the issues with order and dynamically adding new predicate matches, that's tricky

15:57 dnolen: switching back and forth between watching this and handling emails :-)

15:59 dnolen: I see where you were going with core.logic integration now, cool stuff

16:11 coopernurse: bioinformaticsze: sorry, was in a meeting.. looking at your gist now

16:12 chewbranca: dnolen: hrmmm that gets tricky, looking at your example of (defpred foo ..., so lets say you have an initial match when a is 2, but then you extend-pred with a match of c is 3, what happens when you have a hash that matches multiple predicates? do you prioritize on the user extended predicate, or prioritize the original, or run them both? or can you leverage core.logic to the point where you can detect user added ambiguous cases

17:25 bioinformaticsze: No problem. You've aleady been a great help!

17:26 Netpilgrim: Well, I'm glad I haven't drawn too much criticism. I thought I was still not thinking functional enough with my visited variable. Thanks for your help guys. I'm off to the Clojure Web site to read some more.

17:27 jamiltron: Make heavy use of clojuredocs.org

17:27 Netpilgrim: jamiltron: Yeah, thanks. I've already found this site but not really looked at it.

17:37 amalloy: Netpilgrim: tooting my own horn here, have you tried 4clojure.org?

17:37 Netpilgrim: amalloy: No.

17:38 amalloy: if you're writing dfs with a visited atom, you should have little trouble with most of the 4clojure problems, but there are some tricky ones

17:40 Netpilgrim: amalloy: Nice idea. I'll have another look at it later.

17:43 amalloy: Using into and map instead of reduce and concat leaves me with nested lists with a lot of empty lists in it. Probably bad design on my part in returning empty lists whenever I reach leaves in the trees.

17:44 amalloy: Netpilgrim: mapcat, right? that should solve the problem, but i confess this sort of thing usually takes a couple tries for me

17:44 * dnolen is getting excited about random access collection patterns ...

17:45 Netpilgrim: amalloy: Is there a way for a function to return nothing, not even nil?

17:46 amalloy: no

17:46 Netpilgrim: amalloy: Thought so.

17:47 amalloy: Then returning an empty list for a corner case if a function usually returns a sequence is probably not a bad idea.

17:53 jeremyheiler: ,(seq ())

17:53 clojurebot: nil

17:53 jeremyheiler: If it returns a seq normally, wouldn't nill mak emore sense then?

17:55 dnolen: jeremyheiler: ? isn't what you just demonstrated and said the same thing?

17:55 jeremyheiler: Sorry, I wa replying to Netpilgrim

17:57 Netpilgrim: jeremyheiler: Could be that nil would be the more correct choice. I'm still new at this, and '() seemed to work fine.

17:59 jeremyheiler: Netpilgrim: If a function returns a sequence, and a sequence cannot be empty, than nil seems to make more sense than an empty list. I suppose if you have a use-case for wanting the empty list, that's fine.

18:01 Then again...

18:01 ,(empty? nil)

18:01 clojurebot: true

18:02 Netpilgrim: jeremyheiler: O, nil works perferctly fine here. BTW: I'm still not too sure about the use of the words sequence and collection. Is it right that sequence is basically an interface that all collections implement?

18:04 jeremyheiler: And if all collections are sequences, are there sequences that are not collections? Otherwise the words would be synonymous.

18:04 jeremyheiler: A sequence is a view on a collection.

18:04 Netpilgrim: jeremyheiler: That doesn't really explain anything for me. :)

18:05 lobotomy: hmm, is always returning a sequence and then using apply concat (or something similar) on the upper level considered good practice?

18:05 when i was learning the basics of clojure, the most difficult thing was trying to get a non-nested list of lists out of recursive functions :)

18:06 Netpilgrim: lobotomy: That was my problem, too. And mapcat solved it. I have no idea if it's good practice.

18:06 lobotomy: so nowadays i just do (if success (list result)) and otherwise, (apply concat (for [...] (recursive-call ...)))

18:06 but not sure if there's something better. yeah, mapcat would be similar to apply concat there i think

18:08 amalloy: lobotomy: i recently realized that the (apply concat (for ...)) construct is never necessary

18:08 &(apply concat (for [x (range 5)] (range x))) ;; option 1

18:08 lazybot: ⇒ (0 0 1 0 1 2 0 1 2 3)

18:09 amalloy: &(for [x (range 5), y (range x)] y) ;; option 2

18:09 lazybot: ⇒ (0 0 1 0 1 2 0 1 2 3)

18:09 jeremyheiler: Netpilgrim: collections in seqable (they implement clojure.lang.Seqable) which then returns a sequence that operates over the collection. This allows you to use any collection as a sequence, and therefore all the fuctions that operate on sequences.

18:10 collections are seqable**

18:10 TimMc: Where "seqable" means "can be passed to "seq", yeah?

18:13 Netpilgrim: jeremyheiler: This sounds like it's just interesting stuff about the internal implementation of Clojure. But can't I just use collections wherever the documentation talks about sequences without doing something like calling seq? When is seq ever necessary?

18:13 jeremyheiler: TimMc: yeah

18:13 amalloy: Netpilgrim: it's rarely necessary

18:13 but knowing whether you have a seq or some other kind of collection does frequently matter

18:14 Netpilgrim: amalloy: Could you give an example?

18:14 lobotomy: amalloy: hmm, not sure i see your point... are you saying that the double for works for every situation?

18:14 amalloy: &(let [coll (vector 1 2 3 4), seq-version (seq coll)] {:coll (conj coll 5), :seq (conj seq-version 5)})

18:14 lazybot: ⇒ {:coll [1 2 3 4 5], :seq (5 1 2 3 4)}

18:15 amalloy: lobotomy: any time you would (apply concat (for [...] body)), you can instead write (for [... x body] x)

18:15 lobotomy: here's a piece of some code i wrote just now: https://gist.github.com/1158162

18:15 (yeah, there are other issues etc, but)

18:16 how would i apply the "smarter for" in that?

18:16 TimMc: Netpilgrim: ##(let [mystery [1 2 3 4]] (if (seq mystery) "It's seq'able!" "Not seq'able"))

18:16 lazybot: ⇒ "It's seq'able!"

18:16 TimMc: And when something is seq'able, then you can call (first ...) on it, etc.

18:17 That's my major use for it, as a guard predicate.

18:17 amalloy: lobotomy: something like https://gist.github.com/1158172

18:17 Netpilgrim: TimMc: Hm, I guess it will come up some time in my code.

18:18 TimMc: &(let [coll (vector 1 2 3 4), seq-version (seq coll)] {:coll (cons coll 5), :seq (cons seq-version 5)})

18:18 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

18:18 amalloy: i'm pretty sure your filter is complete nonsense, but i added a :when just in case

18:18 TimMc: bah

18:19 amalloy: TimMc: cons takes args opposite from conj

18:19 TimMc: yeah

18:19 &(let [coll (vector 1 2 3 4), seq-version (seq coll)] {:coll (cons 5 coll), :seq (cons 5 seq-version)})

18:19 lazybot: ⇒ {:coll (5 1 2 3 4), :seq (5 1 2 3 4)}

18:20 amalloy: lobotomy: you see what i mean? pull the filter and the nested-iteration into the `for` bindings, and then there's no need to filter or concat

18:20 Netpilgrim: amalloy: Your example shows that sequences prepend with conj like lists. What is the difference between lists and sequences?

18:20 TimMc: Netpilgrim: ^ cons calls seq on its argument, conj does not -- amalloy's example was a little sneaky (you wouldn't call (conj (seq coll) ...), you would call (cons ... coll))

18:21 amalloy: TimMc: i disagree re: sneakiness

18:21 someone passes you a collection, and it might be a seq or something else, so you conj into it rather than consing

18:21 TimMc: You would, wouldn't you.

18:21 amalloy: thus, the person who passes it to you should know ehther it's a seq or a vector or what, to know what the result of the conj will be

18:22 TimMc: amalloy: I said (comp conj seq), not conj

18:22 (effectively)

18:22 amalloy: right...and i never do (comp conj seq) either

18:22 i'm supposing that those values get passed to you from elsewhere

18:23 Netpilgrim: that's a complicated question. lists are a kind of collection, and thus seqable. they conj to the front because that's the efficient way to do it for lists, just like for seqs

18:24 TimMc: ,(type (seq ()))

18:24 clojurebot: nil

18:24 TimMc: ,(type (seq (list 1 2 3)))

18:24 clojurebot: clojure.lang.PersistentList

18:25 TimMc: ,(type (list 1 2 3))

18:25 clojurebot: clojure.lang.PersistentList

18:25 TimMc: Oho!

18:25 jeremyheiler: ,(type (seq [1 2 3]))

18:25 clojurebot: clojure.lang.PersistentVector$ChunkedSeq

18:25 TimMc: ,(type (cons 4 [1 2 3]))

18:25 clojurebot: clojure.lang.Cons

18:26 jeremyheiler: hah

18:26 TimMc: So yeah, some seqs are implemented with list, others not.

18:27 lobotomy: amalloy, actually the when-let returns nil when the condition isn't met, which is why i have that filter complement nil :)

18:27 amalloy: lobotomy: ##(apply concat '[(seq A) nil (seq B)])

18:27 lazybot: ⇒ (seq A seq B)

18:27 amalloy: you don't have to filter the nil out, is my point

18:28 lobotomy: ah, ok

18:28 Netpilgrim: I'm all for interesting implementation details but I still don't see why it's necessary or useful to have sequences in the language when there are lists and arrays and ways to transform between them.

18:28 amalloy: sequences are FANTASTIC

18:28 lobotomy: and it apparently works when it's all nil. heh

18:28 the more you know!

18:28 amalloy: you don't have to *know* whether you have a list or an array or what. that's the whole beauty

18:28 jeremyheiler: TimMc: Interestingly, It seems that both PersistentVector.ChunkedSeq and PersistentList extends ASeq

18:28 lobotomy: i mean apply concat works with all nil

18:29 anyway, trying to get that to work with the actual code, and something's expecting a list where there's now only a boolean

18:29 amalloy: TimMc: "So yeah, some seqs are implemented with list, others not." - this is backwards

18:29 TimMc: Netpilgrim: They are two different abstractions that interconvert nicely.

18:30 amalloy: Apparently!

18:30 amalloy: list is a collection which implements seq directly, and so returns itself when asked for a sequential view

18:30 the others need some munging to get sequentialized, so they return a different type

18:30 lobotomy: how do i get a backtrace that's actually worth a damn... slime is saying the error happens in mything.core$eval12317.invoke(NO_SOURCE_FILE)

18:31 while running the unit tests from the command line tells me it happens in a similar eval thing in mything.test

18:33 Netpilgrim: amalloy: But why isn't it enough to say that there are functions like first or what have you that work on both lists and arrays (possibly sets and maps?) without worrying the programmer about some implementation voodoo that makes using this unified interface possible?

18:33 lobotomy: oh well, it's bedtime anyway ;p

18:33 TimMc: Netpilgrim: first calls seq on its argument

18:33 sorry, misread

18:33 I should head home before I do any more damage. :-P

18:34 amalloy: because by introducing seq as a globally-used interface, you only have to implement map once, for seqs; not once for maps and once for sets and...

18:34 Netpilgrim: TimMc: That's exactly what I mean: It's something done internally. Why do I have to know about it?

18:34 amalloy: it also means you can create your own data types that act as seqs, and first/map/etc will work on them without a problem

18:36 Netpilgrim: amalloy: Couldn't lists be used instead of seqs? Are there list functions that aren't seq functions?

18:36 amalloy: i think you should write some more clojure before you decide that the underlying architecture is wrong

18:37 Netpilgrim: amalloy: Sorry, I wasn't suggesting anything of the kind. I'm just trying to understand it – not even the architecture, just how to use the language and what the constructs are for.

18:37 amalloy: the seq abstraction is extremely powerful, and having to work explicitly with N different data types is a tremendous limiting factor

18:38 &(nth (range) 1e8)

18:38 lazybot: Execution Timed Out!

18:38 jeremyheiler: From Joy of Clojure: It is better to have 100 functions operate on one data abstraction than 10

18:38 functions on 10 data structures.

18:38 —Rich Hickey

18:38 amalloy: too large, i guess? anyway, lazy sequences mean that you can work with lists that are a hundred million elements long without needing to use up any memory

18:38 by only creating elements as they're needed, and throwing them away when they're not

18:39 Netpilgrim: amalloy: Only seqs can be lazy, not collections?

18:39 amalloy: So lazy seqs would be an example of seqs that aren't collections?

18:39 amalloy: &(instance? clojure.lang.IPersistentCollection (seq (range 10)))

18:39 lazybot: ⇒ true

18:40 amalloy: seqs are collections

18:40 Netpilgrim: amalloy: Argh, I thought I had it. :)

18:40 amalloy: but the point is that many collections can't be lazy; they instead choose to realize all their elements at once in order to provide other guarantees, like fast random access

18:42 but often all you *need* is to be able to walk through the items one at a time, and you don't care how you get those items. so then you say to the collection, "hey, gimme a sequential view of yourself", and you work with that

18:42 Netpilgrim: amalloy: So to finally get my definitions straight: seqs are collections and other collections are not seqs but can always made into seqs?

18:42 amalloy: yes

18:43 Netpilgrim: Heureka! :)

18:43 amalloy: Thanks for your patience.

18:46 jeremyheiler: Netpilgrim: Sorry if I cause some confusion

18:46 caused*

18:46 lobotomy: amalloy: in my code, it seems your extended for thing just doesn't work. the base case returns a map, but putting the "item rec-result" there somehow does (apply vec that-map) or something, which i don't quite get

18:47 dnolen: BitVectors here we come :D

18:47 lobotomy: and that's probably why it gives those errors about expected list, got boolean

18:47 Netpilgrim: jeremyheiler: No problem. My confusion couldn't be improved upon.

18:48 lobotomy: when i take away the "item rec-result" bit, it for some reason (apparently) works, except that there are empty lists, and it returns nested lists :)

18:48 Netpilgrim: jeremyheiler: BTW: The Joy of Clojure is already on its way to me. I've ordered it this afternoon.

18:48 jeremyheiler: Netpilgrim: You'll like it, it's a really good book

18:49 Netpilgrim: jeremyheiler: It sounds really good. I can't wait. But it will probably not arrive before Monday.

18:55 lobotomy: amalloy: apparently for turns the things it gets into vectors? or something? i don't fully understand what goes on there, but it seems if you have the "item rec-result" line there the item gets mangled

18:55 amalloy: &(seq {:a 1 :b 2})

18:55 lazybot: ⇒ ([:a 1] [:b 2])

18:56 amalloy: &(for [entry {:a 1 :b 2}, x entry] x)

18:56 lazybot: ⇒ (:a 1 :b 2)

19:00 lobotomy: &(for [a [1 2 3] x (assoc {} a (- a))] x)

19:00 lazybot: ⇒ ([1 -1] [2 -2] [3 -3])

19:00 lobotomy: &(for [a [1 2 3]] (assoc {} a (- a)))

19:00 lazybot: ⇒ ({1 -1} {2 -2} {3 -3})

19:00 lobotomy: so if i want the latter, how to make that work with the "both things inside for" thing? or is there no way?

19:15 chouser: lobotomy: what return value do you want there?

19:38 ibdknox: anyone in the bay area looking for a Clojure job? :)

19:39 amalloy: ibdknox: no, but i'm still curious

19:40 ibdknox: I joined a YC backed startup a while ago

19:40 www.readyforzero.com

19:40 * srid wonders if anyone in vancouver uses Clojure professionally

19:40 ibdknox: and we're looking for some folks :)

19:40 srid: I heard that the creator Noir joined RFZ. is that you, ibdknox?

19:41 ibdknox: srid: yep yep

19:41 srid: good for you. i'm still learning clojure.

19:41 Raynes: Alas! I have submitted abstracts for the Conj! Now I shall live in fear of public speaking.

19:41 ibdknox: haha

19:42 Raynes: what's the worst that could happen ;)

19:42 Raynes: I could have to speak!

19:42 srid: it is hard to believe that one can make money with esoteric parenthesizes ;-)

19:42 ibdknox: haha

19:42 srid: you can make a lot if you do it right ;)

19:42 amalloy: srid: the money to be made is in the very small number of *other* characters you use

19:43 srid: the worst that could happen is that amygdala can trigger an intense fear response. damn the amygdala.

19:46 ibdknox: well in case anyone *is* interested, you should shoot me an email: chris@readyforzero.com

20:24 chewbranca: interesting, so clojure sorted sets sort on case sensitive values, but test uniqueness on non case sensitive values

20:24 amalloy: chewbranca: i am willing to bet about a million dollars that this is untrue

20:24 chewbranca: (sorted-set "bar" "Baz")

20:25 amalloy: &(sorted-set "bar" "Baz")

20:25 lazybot: ⇒ #{"Baz" "bar"}

20:26 amalloy: &(sorted-set "bar" "Baz" "baz")

20:26 lazybot: ⇒ #{"Baz" "bar" "baz"}

20:27 chewbranca: yeap, typo on my end :/

20:28 amalloy: good call

20:28 amalloy: it's a good thing, because i don't have a million dollars

20:28 chewbranca: hahaha

21:48 duck1123: Midje works in 1.3, right?

22:16 amalloy: duck1123: try it and see

22:36 duck1123: I keep getting no method errors from keyword in one project, it works in the other

22:59 srid: what is the recommended way to name a clojure library? eg: https://github.com/antoniogarrote/clj-haml uses "clj-haml" ... is "clj-" a common prefix, or should it just be "haml"?

23:00 redinger: In general, no clj- prefix. However, that is a Clojure port of HAML, so in that case it makes sense.

23:06 TimMc: wait wait wait

23:06 jeremyheiler: Did you just attribute an Alan Perlis quote to Rich Hickey?

23:06 jeremyheiler: http://www.cs.yale.edu/quotes.html #9

23:09 srid: i think RH merely adapted that quote to use 'data abstractions' (instead of 'data structures')

23:09 i'm just guessing.

23:10 redinger: also, the twitter api is named "clojure-twitter" and the oauth api is named "clj-oauth"

23:10 and there is "com.twinql.clojure/clj-apache-http"

23:11 * srid is wanting to write a clojure API for api.stackoverflow.com

23:11 srid: so I'd name it "stackoverflow"?

23:12 gregh: the api can apply to all stackexchange sites, not just stackoverflow

23:12 amalloy: i'm sure someone would call it stackojureflow

23:13 but if anyone suggests that for real you should murder them

23:13 duck1123: clj- is for when you can't think up a good name

23:14 srid: another naming related question - why are some clojars named "com.zacharykim/clj-http" instead of "clj-http"?

23:15 redinger: yeah, I think if you go with something generic like stackoverflow, you'd have to go with a clj- prefix. Whereas if you go with something like German literary figures, you can skip the prefix

23:15 srid: clj-stackexchange, perhaps.

23:15 alandipert: i think there's an argument for tossing clj/clojure- on the front if it's not consumable from other jvm langs

23:16 srid: someone named their Lucene api "clucy". heh.

23:24 TimMc: srid: I like clever, simple, quasi-descriptive names. No mention of implementation. I wrote a (not great) behavioral circuit simulator called "feedback" and am writing a JS DOM/Canvas yoking thing called "syzygy".

23:24 Good names are hard, though.

23:42 coopernurse: srid: +1 for clj-stackoverflow

23:50 amalloy: srid: what do they expose in their api? what would i use it for?

23:52 srid: i want to write something similar to http://weeklyreddit.appspot.com/ - to get, say, a feed of top stackoverflow posts on the [clojure] tag in the past week.

23:55 they expose pretty much everything I believe.

Logging service provided by n01se.net