#clojure log - Jan 11 2011

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

0:22 qbg: Perhaps I can make an alpha2 release of syntax-rules tonight

0:44 amalloy: $mail cemerick it occurs to me your first-draft benchmark was a nice satirical comparison of clojure to java: clojure takes N seconds to get something done; java takes 2N and returns null :)

0:44 sexpbot: Message saved.

0:56 qbg: Yes, new release out

1:27 Berengal_work_: Is there a way to apply a java method the way you apply regular functions?

1:27 As in the function "apply"

1:37 bortreb: what's the latest clojure resource for reading from a file blazingly fast in map-reduce style?

1:38 something that can do parallel line processing of a 50 Gb log file for example?

1:39 amalloy: Berengal_work_: i don't think so

2:10 Berengal_work_: int

2:10 oops

2:23 vIkSiT: hi all

2:23 i'm currently using the randomAccessFile java class to tail a file - but it stops working if the log file rotates. Does anyone know how to ensure that the class keeps track of the new file?

2:24 https://gist.github.com/774156 is what i use

2:25 amalloy: vIkSiT: do you want it to follow the new, rotated-in file, or the rotated-out file with the new name?

2:26 vIkSiT: the rotated-in file.

2:26 so if i tail current.log, then it should always follow current..

2:27 amalloy: not that i really have any idea how to solve your problem :P

2:27 vIkSiT: hehe

2:27 amalloy: well, once java has the file open, it has a pointer to the file's id, not its name

2:27 vIkSiT: i'm trying to figure out what to google for - rotating files or following files

2:27 amalloy: just like any other process

2:27 vIkSiT: amalloy, right

2:27 except - the inode changes

2:27 amalloy: vIkSiT: i just tried both of those searches

2:27 vIkSiT: so there has to be some way to keep track of the linked to file

2:27 amalloy, hehe

2:28 amalloy: perhaps see what log4j does?

2:31 vIkSiT: hmm yes thats an idea

2:34 amalloy: or actually the unix tail command. i think it just polls/stats the filename every so often

2:36 *chuckle* $ tail -F mylogfile | java -cp .....

2:36 LauJensen: Is there a tool to convert a standalone jar to an .exe ?

2:37 amalloy: LauJensen: why? don't windows installs come with a file association for jars these days?

2:38 LauJensen: For some reason its a requirement of USB vendors to have applications delivered as .exe files in order to split it and hide parts of it on the drive itself

2:38 amalloy: that is priceless

2:39 int main(void) {exec("java -cp ...");}

2:41 LauJensen: hehe

3:41 amalloy: raek: exceptions are making me weep at the moment. are we getting your map exceptions, or something similar, soon?

3:42 tomoj: map exceptions?

3:44 amalloy: tomoj: https://github.com/raek/map-exception

3:44 contributed as an idea to clojure.core, but from the sound of http://dev.clojure.org/display/design/Error+Handling+Comparisons?focusedCommentId=950796 we'll end up with something else

3:45 (that is, i already know we won't be getting these things in a huge hurry, but i want raek to make soothing noises)

3:46 Raynes: amalloy: Don't count your chickens before they hatch. raek has been rewriting Irclj's message parser for the better part of 2010. ;)

4:09 LauJensen: Raynes: Always great with some of that Alabama wisdom :)

4:11 ejackson: LauJensen: you're right about my blog. All the ideas I've had for it would take too long to do and I'm being lazy

4:12 LauJensen: ejackson: well, at least you're man enough to admit it :)

4:13 ejackson: i have a few kettles in the fire, and at least one of them will end up on the blog

4:13 LauJensen: well, dont sell your kettles before they burn as Raynes would say

4:14 ejackson: or my teapots will come home to roost...

4:14 LauJensen: hehe

4:14 bortreb: anyone know of a good resource to learn about processing huge log files in clojure?

4:15 LauJensen: bortreb: depends on what you mean by good. Alex Osbourne has a blog that shows how to parse 45 Gb in about 8 minutes. I have a blogpost about parsing 50Gb weather data

4:16 gregh: bortreb: try http://stackoverflow.com :)

4:16 bortreb: I was wondering if there was some clojars library or something I am overlooking

4:16 is 45gb in 8 minutes "good" ?

4:16 LauJensen: bortreb: no, its fast

4:16 ejackson: bortreb: nathanmarz's cascalog is a tool that might be useful for you

4:17 LauJensen: Ruby took 45 hours I think

4:17 ejackson: casalog for parsing logs?!

4:17 ejackson: depending on how sophisticated your definiton of parsing is :)

4:17 and how big your logs

4:17 LauJensen: ..and how much syntax you want to learn

4:18 raek: the plan seems to be to define the "map exception"/condition class first

4:18 LauJensen: Isnt casalog that query language that looks like [?age <> ?person >-@> ::filter] ?

4:18 amalloy: LauJensen: that looks more like clojure than most things do :P

4:18 LauJensen: For you know. When you what the age of the person to be confused for a fish swimming towards a filter

4:18 ejackson: yeah,

4:19 gregh: I've had good success recently processing big file by memory mapping them (on a 64-bit machine)

4:19 ejackson: it allows pretty arbitrary logic statements to be executed against gigantic files on a hadoop system

4:19 LauJensen: gregh: Thats nice - It sucks when you have 'bad success' doing that

4:19 ejackson: Man you'll earn your money as a consultant if you point people to Hadoop and Casalog when all they want is to parse a log file

4:19 bortreb: maybe bad success is getting handed more log parsing jobs because you're sooooo good at it?

4:20 afekz: naah, "bad success" is probably some jazz term or something

4:20 ejackson: ok, i was misled by the 'huge' in bortreb's query. I'll admit its probably overkill :)

4:20 LauJensen: jazz is bad sucess :)

4:20 bortreb: thanks, I'll read the blog then :)

4:20 LauJensen: ejackson: no no - While you're at it, get him an internship at Google so he can parse the logs on their hardware, thats really the only way to go

4:21 Everytime I need to skim a logfile, I always get an internship somewhere :)

4:21 ejackson: LauJensen: naaah, that's to 2009 - Twitterface or something.

4:21 TobiasRaeder: morning :)

4:22 LauJensen: Morning :)

4:22 ejackson: yello

4:23 TobiasRaeder: Anyone here using align in emacs?

4:23 jwr7: Is there a way to specify a timeout on an agent action? My agents perform network I/O which (as it turns out) may hang — I'd like to have a way of getting an exception if I/O takes too long.

4:24 …and the obvious solution (use futures in agent actions) seems overly complex.

4:24 raek: jwr7: why not use (future ....) instead of send?

4:24 amalloy: jwr7: the obvious solution is to set a timeout on the network io itself

4:25 raek: future objects have a .get method that acccepts a timeout value

4:25 jwr7: raek: well, the agent metaphor works really really well for me.

4:26 amalloy: well, this would mean using futures to perform I/O operations, lots of additional complexity.

4:27 amalloy: jwr7: there's no reason it should mean that

4:27 raek: ok, if you need to asynchronously keep track of some state rather than synchronously (ref/atom), then I guess agents are the best fit

4:27 jwr7: I was actually surprised there isn't a way to specify a timeout when calling send/send-off — I thought people would have ran into this already.

4:27 amalloy: jwr7: http://download.oracle.com/javase/1.4.2/docs/api/java/net/Socket.html#setSoTimeout%28int%29

4:27 raek: agents are not the main mechanism for "sending off stuff for running in another thread"

4:28 s/main/most basic/

4:28 sexpbot: <raek> agents are not the most basic mechanism for "sending off stuff for running in another thread"

4:28 jwr7: amalloy: the network I/O I do accesses Amazon S3 using the jets3t library…

4:29 raek: in my case agents are a perfect fit. I need serialized async operations on a data structure.

4:29 raek: ok. then agents sounds perfect.

4:30 (agents tend to be somewhat over-used)

4:30 jwr7: so I guess the answer to my original question ("Is there a way to specify a timeout on an agent action?") is "no"

4:30 raek: yes, I know — but in this case they are really perfect. I would be reimplementing agents if I chose anything else.

4:30 raek: jwr7: yes, that is true. how should the action be aborted?

4:31 the simplest way is to make the action cooperative and let itself be interrupted

4:31 jwr7: raek: I'd expect a java.util.concurrent.TimeoutException which would cause an agent error.

4:31 …which the rest of my application already knows how to deal with.

4:32 raek: exception handling is tricky when doing asynch stuff

4:32 jwr7: put differently, I'd like an agent implemented using futures — and I actually thought that is exactly what send-off does

4:32 raek: you can of course catch it in the action, and store it somewhere

4:33 yes, agents are implemented on top of two ExecutorServices

4:33 jwr7: raek: as I said, the application already has to deal with agent errors and it does. It's tricky, but all concurrent systems are.

4:34 so the obvious way to implement what I need would be just to wrap my action in a future call with a timeout.

4:34 but that means I'd be creating twice the necessary number of threads, for no good reason

4:35 raek: hrm, yes

4:35 jwr7: …and I might end up doing it anyway, as it is the only solution I can think of right now.

4:36 raek: what should the operation on the data structure be in case of a timeout?

4:36 jwr7: raek: nothing — no change at all.

4:37 raek: agent semantics — either the action succeeds or it doesn't, you don't get states in between.

4:38 raek: and the lib does not provide any way of setting a timeout?

4:38 (the network IO thing)

4:39 everything would have been simple if the blocking IO call could just throw an exception if it takes too long time

4:40 jwr7: raek: I'm going through the docs right now. But I'd like a more reliable mechanism, as in "whatever happens, there is a global timeout".

4:40 raek: socket timeouts won't kick in if the data starts dribbling at 5 bytes a second for 2 days.

4:40 raek: so I'd much rather have an absolute limit on the amount of time an agent action may take.

4:40 raek: then you pretty much need a thread that you can inerrupt

4:41 also, it's too bad that blocking socket operation do not throw an InterruptedException when the thread is interrupted

4:42 but another thread can close the socket, which will stop the blocking op

4:42 jwr7: raek: I think I'll try a macro that wraps an agent action in a future with a timeout on deref. E.g. instead of defn'ing my agent actions I'll defagentaction them.

4:43 raek: don't forget to future-cancel it

4:44 jwr7: raek: hmm — what do you mean? I don't understand that?

4:44 raek: futures provide a way of signalling that you don't care about the result anymore

4:45 that will try to interrupt the thead if possible

4:45 most blocking operations (except sockets) will then throw an InterruptedException

4:46 so if the network operation takes too long time, you'd want to signal it that it can stop doing what it does, since you don't care about the result anymore

4:48 (let [ftr (future ...)] (try (.get ftr 1 TimeUnit/MINUTES) (catch TimeoutException e (future-cancel ftr) (throw e))))

4:49 also, I really recommend the book http://www.javaconcurrencyinpractice.com/

4:59 shortlord: is there any elegant way to test if a coll contains at least one logical true value? It seems strange to use 'some' and then check for 'nil?' and 'false?'

5:00 mrBliss: shortlord: (some identity coll)

5:00 nathanmarz: LauJensen ejackson: cascalog can be used for local, in-process computation. I do that a lot when developing or when I have a small enough dataset to poke at

5:00 LauJensen: really? interesting

5:00 guess I dont get to make fun at ejackson then :(

5:00 nathanmarz: LauJensen ejackson: at some point it will have a fork-join implementation which will be even better

5:01 ejackson: nathanmarz: that's awesome news

5:01 LauJensen, nathanmarz : I'm glad not to be totally wrong - I usually default thus.

5:02 nathanmarz: it just runs hadoop in "local mode", which just means it's in process and there's no daemons to deal with

5:02 LauJensen: nathanmarz: Have you got some docs on this somewhere?

5:03 nathanmarz: on running it in local mode?

5:03 LauJensen: On the whole setup

5:04 nathanmarz: there's nothing to running it in local mode, just include it as a dependency in leiningen and open up a repl

5:04 this post: http://nathanmarz.com/blog/news-feed-in-38-lines-of-code-using-cascalog.html talks about using it on a real cluster

5:05 oh and you'll want hadoop as a dev dependency: [org.apache.hadoop/hadoop-core "0.20.2-dev"]

5:05 setting up a good wiki is a priority over the next month :)

5:07 ejackson: nathanmarz: I saw from some tweets that you were playing with redis. Any joy ? I've been using it recently in clojure and have been v. impressed with it.

5:07 persisting a sorted set directly is magic

5:08 nathanmarz: ejackson: i haven't played with redis at all... or tweeted about it

5:08 ejackson: hmmm......

5:08 nathanmarz: i know the runa guys use it

5:09 ejackson: i must be losing my mind, going to examine the logs.....

5:09 (not with cascalog...)

5:10 ugh, whatever.

5:10 LauJensen: nathanmarz: thanks

5:20 nathanmarz: LauJensen: sure thing

5:31 shortlord: it's not possible to set 2 validators for one single ref, is it? which means I would need to 'and' both functions, right?

5:40 ejackson: shortlord: that's what i'd do.

5:44 LauJensen: shortlord: Likely you'll use cond or condp and make a list of requirements for validation

5:45 or you could take ejacksons advice and simply let the validator log the event, upload it to Google Docs and then inspect the logs manually with your coworkers via a VPN connection implemented in C

5:47 shortlord: LauJensen: the google docs thingy is a hell of a great idea! thx a lot, I'll do that :)

5:47 LauJensen: well, thank ejackson :)

5:47 ejackson: lmao

5:47 shortlord: thx, ejackson :)

5:47 ejackson: your invoice in the post - BOTH of you

5:48 LauJensen: yea ejackson's a _real_ consultant :)

5:48 shortlord: ^^

5:48 ejackson: LauJensen: i've got a _special_ rate for you buddy.

5:52 * ejackson looks around for another way to make a tit out of himself.

6:21 shortlord: is it possible to validate a ref based on the old and the new ref value?

6:23 bsteuber1: ,(doc set-validator!)

6:23 clojurebot: "([iref validator-fn]); Sets the validator-fn for a var/ref/agent/atom. validator-fn must be nil or a side-effect-free fn of one argument, which will be passed the intended new state on any state change. If the new state is unacceptable, the validator-fn should return false or throw an exception. If the current state (root value if var) is not acceptable to the new validator, an exception will be...

6:25 bsteuber1: so I guess no

6:29 raek: shortlord: pre- and post-conditions for the state transition function could perhaps do something similar

6:30 jwr7: The docstring for future says "…yields a future object that will

6:30 invoke the body in another thread, and will cache the result…" — cache it until when? What if my future returns a 1GB object and my heap is 3GB?

6:30 shortlord: raek: ok, that will do, thx

6:30 jwr7: assuming I don't hold on to the ref, will the result still be stored somewhere?

6:31 raek: jwr7: what it means is that evert time you dereference it you will get the same value (it is only computed once)

6:31 it will only be around as long as you hold a reference to the future

6:31 jwr7: raek: oh, that's cool then.

6:32 raek: caches in java are often implemented with some variant of weak references, whose entries will be GC'ed when no-one else has a reference to the object

6:32 so it probably wouldn't be a problem even if it was holding it in a cache

6:33 jwr7: raek: thanks. That sounds ok.

6:54 raek: I've dropped my old .emacs file and started to use emacs starter kit, but I'm getting stuck on one detail:

6:55 when doing C-x C-f, it enters some fuzzy matching mode (whis is very nice) but sometimes I want to visit exactly what I have written

6:56 e.g. create the file foo-project/src/util.clj instead of reopen my old bar-project/src/util.clj

6:56 how can I do this? what am I missing?

6:56 Chousuke: hm.

6:57 it should allow that

6:57 just type the full path

6:58 and be quick enough that the search doesn't trigger :P

6:58 it has a timeout after you stop typing.

6:58 raek: when I finnish ".clj" it replaces the path with my other file

6:58 bsteuber1: raek: try C-f when in the minibuffer

6:59 at least that works with my fuzzy completion there

6:59 raek: ah, wonderful!

7:00 Chousuke, bsteuber1: thanks

7:00 bsteuber1: yeah, I was also quite happy after finding this :)

7:00 raek: being quicker-than-emacs worked, but C-f is much more convenient... :-)

7:07 Raynes: cemerick: Morning.

7:07 cemerick: morning :-)

7:09 raek: Raynes: regarding irclj: guess what... I got stuck on the error handling.

7:10 Raynes: raek: That statement was promptly accompanied by a rimshot by the house band. :p

7:10 bsteuber: when debugging gui apps from swank, closing the applications main window always kills the swank process - any idea how to prevent this?

7:11 tomoj: isn't there some flag you set for what to do on close?

7:12 .setDefaultCloseOperation

7:13 the default shouldn't be EXIT_ON_CLOSE, though...

7:13 raek: creating a JFrame, showing it and closing it does not do that for me

7:13 the slime-swank session remains alive

7:15 bsteuber: hmm, so maybe my application does sth. special - it's quite big and chaotic (and not mine)...

7:16 tomoj: if it's swing, grep for EXIT_ON_CLOSE

7:16 or DISPOSE_ON_CLOSE maybe

7:17 ..ON_CLOSE should do it

7:18 bsteuber: tomoj, raek: found it, there's a custom listener calling System.exit - so thank you :)

7:46 ejackson: hello cemerick

7:51 cemerick: ejackson: good afternoon :-)

7:52 ejackson: cemerick: indeed :D

7:55 cemerick: amalloy: pling?

8:41 edw`: Could someone give me an example usage of `longs'? I'm trying to create an array of unboxed numbers.

8:44 chouser: edw`: 'longs' just casts. you probably want (long-array [1 2 3])

8:45 edw`: Ah. Thanks.

8:53 Dranik: chouser, does long-array create an array for unboxed values?

8:54 chouser: ,(long-array [1 2 3])

8:54 clojurebot: #<long[] [J@413be>

8:54 chouser: yep, an array of primitive longs.

8:59 Dranik: ,(int-array [1 2 3])

8:59 clojurebot: #<int[] [I@1288e12>

8:59 Dranik: wow! :-)

9:07 Somelauw: I really don't like scala.

9:08 Scriptor: why not?

9:11 Somelauw: It is too complicated.

9:11 It's errors are unclear

9:11 And it is hard to read.

9:12 It looks ugly

9:12 LauJensen: http://michid.wordpress.com/2010/08/24/so-scala-is-too-complex/

9:13 Somelauw: And it is has too much impliciteness.

9:14 I will read it, but it probably won't convince me.

9:14 clgv: you do have example for what you claim? It would be interesting to see.

9:14 cemerick: LauJensen: That's a silly post. Verbosity ≠ complexity.

9:15 LauJensen: cemerick: They are very related, though I dont agree with that posts conclusion of course. Scala is waay too complicated

9:16 AWizzArd: LauJensen: but this guy from the blog was cheating a bit in the Java version.

9:16 He could have made the fields public, so no getters/setters were needed.

9:16 cemerick: "Complicated for what" is the better question.

9:17 LauJensen: But, verbosity and complexity are *entirely* orthogonal, if they're to mean anything at all.

9:17 AWizzArd: He could also import scala and call the same functions as in the Scala example.

9:18 The Java code would still be longer, but way shorter than what he presented in his blog.

9:18 Somelauw: His java code, isn't idiomatic java, but he is just converting all scala functions to java first.

9:18 LauJensen: cemerick: Assembly code is very simple, every line does only one thing. But if I tasked you to read the source for Notepad written in Assembly, Im sure you'd think it was complex because of the shear vastness of code. So ytou see, they are related

9:19 http://grep.codeconsult.ch/2010/08/26/so-java-is-more-complex-than-scala-you-must-be-kidding/

9:19 Fossi: all there is to say about scala: "+: fail"

9:19 cemerick: LauJensen: No, I'd think it was verbose.

9:19 LauJensen: cemerick: You're too stubborn for reason

9:20 cemerick: LauJensen: Words mean particular things; just stating that A is related to B doesn't make it so.

9:21 Perhaps one may not like a language because it tends to encourage/require verbosity, but that doesn't mean that the language is simple, or complex.

9:22 AWizzArd: LauJensen: yes good, this second post shows a more realistic scenario.

9:23 LauJensen: You guys remember this one?

9:23 life1d=: '_#'{~ (3(2=+/\) 0,],0:)^:a:

9:24 AWizzArd: Maybe one could say that complexity is introduced when there are "many cases".

9:24 LauJensen: AWizzArd: Generally speaking, you could say "complexity is introduced, shortly after cemerick is introduced" :)

9:24 Somelauw: LauJensen, Java code can be much shorter than your example suggests: http://pastebin.com/FkswZt96

9:25 It won't compile since it is quickly written.

9:25 LauJensen: Somelauw: You have to type slow for the compiler to work? crazy....

9:26 Somelauw: No, it won't compile since I am too lazy to debug it, but it demonstrates that java doesn't have to be written in the way your article suggests.

9:26 LauJensen: Its not my article

9:27 shortlord: can I use 'loop' without 'recur'? My function is not linear-recursive, so recur is not an option

9:27 Somelauw: You posted it.

9:27 Chousuke: shortlord: no.

9:28 Raynes: I like it when I'm looking for something that I figure wont exist only to find out that precisely what I'm looking for does exist. c.s/trim-newline for example.

9:28 Chousuke: you can call your function in the loop but it needs a recur to actually be a loop. :P

9:29 cemerick: shortlord: you can also recur to the head of your function, but I presume that's not suitable either

9:29 hoeck: Somelauw: nice, thats what I thought too

9:29 shortlord: Chousuke: so I'd have to do alle my bindings first, then create another function within the main function and call that inner function manually?

9:29 Chousuke: shortlord: you can call the main function too?

9:29 shortlord: ordinary recursion works normally, it just won't be optimised

9:29 shortlord: but I don't want the bindings to be overwritten

9:30 Chousuke: I'm not sure what you need to do :/

9:30 But using loop without recur sounds weird. :P

9:30 shortlord: I am doing some dereferencing in the first entry, which should not happen in the first recursion

9:30 LauJensen: shortlord: it sounds like you're on an imperative path

9:30 Chousuke: what point is there in looping if the loop variables are constant?

9:31 raek: you could use a helper function

9:31 shortlord: the loop variable is not constant

9:31 raek: ...which would call itself

9:31 Chousuke: maybe you should come up with some example code illustrating what you need.

9:32 then it's easier to tell you if there's a better way.

9:33 shortlord: ok

9:33 where can I find a good pastebin with clojure highlighting?

9:34 Chousuke: gist is good

9:34 cemerick: gist.github.com is good

9:34 Chousuke: :P

9:34 * Chousuke won by taking shortcuts

9:35 shortlord: https://gist.github.com/774476

9:36 the last line is where the recursion should eventually occur, but the important thing is the 'let'

9:36 I only want to do that binding once

9:36 and not every time I use that function recursively

9:37 'loop' sounds like the perfect match, but I can't use 'recur' since the function won't be linear recursive

9:37 so I guess the only way to do is would be a helper function, right?

9:37 Chousuke: using an inner helper function sounds like it would work. Close it over the let binding

9:38 shortlord: Chousuke: ok, thx

9:41 fliebel: morning

9:41 Hm, seems I'm back to fliebel again. Whatever.

9:45 ejackson: fliebel: you been dabbling in schizophrenia or MPD ?

9:45 fliebel: ejackson: No, just trying to / nick pepijndevos

9:46 cemerick: fliebel: it takes some doing to change default nicks.

9:46 or, it took me a few days to figure out the magic combination between NickServ and my irc client.

9:47 fliebel: cemerick: Meh, probably not worth the effort and trouble.

9:57 Raynes: fliebel: What is 'fliebel'?

9:58 What does the name mean, I mean.

9:58 fliebel: Raynes: Nothing, well, uuuhm. *goes up to translate.google.com*

9:58 Raynes: sexpbot can do that.

9:59 $trans es en hola

9:59 sexpbot: hello

9:59 fliebel: $trans nl en fliebel

9:59 sexpbot: fliebel

10:01 fliebel: It's a bit of a made-up word, but what I usually mean with it, is 'something', usually something random, or a small extension, like a candle pit.

10:02 Raynes: Interesting.

10:02 fliebel: really?

10:02 Raynes: Americans don't make up words.

10:03 fliebel: Raynes: But you do have slang I believe? That's the same thing.

10:03 Raynes: Well, yeah.

10:05 markskilbeck: Americans don't make up words? "Color", "Humor", "Weapons of Mass Destruction"...

10:08 fliebel: markskilbeck: You're saying American *is* slang? ;)

10:08 gtrak: $trans en ru hello

10:08 sexpbot: привет

10:09 cemerick: Raynes: I daresay we're produce new words more efficiently than we should ;-)

10:10 Raynes: cemerick: Indeed. Slang completely slipped my mind.

10:11 cemerick: "Proper English" *is* slang until it's "proper". :-)

10:12 Raynes: Not isn't always the creation of new words as much as they are repurposing of old words. For example, "ice" is slang for crystallized methamphetamine.

10:17 fliebel: Python is hard, mainly due to misplaced braces and missing commas.

10:18 cemerick: __all__ _the under_scoring ended up bothering me after a while.

10:18 clgv: and messed up tabs ;)

10:19 fliebel: __these__ methods are magic though :)

10:19 cemerick: yeah, but you end up writing and using them a fair bit to do certain things

10:19 clgv: but there is a great library in python for algebra and other fields of computational mathematics :)

10:20 I did work with it 2 years ago while writing my thesis...

10:20 fliebel: Hm, I was looking for a specific property of Python lists, which they don't have. I thought I could do some_list[300] = 3 and it would do that on a list 5 items.

10:22 fogus`: Anyone have a favorite way to map a function to every other value in a seq (without using take-nth)? i.e. (map-eo - [1 2 3 4]) ==> [1 -2 3 -4]

10:23 fliebel: fogus`: Why not take-nth?

10:23 opqdonut: the simplest is just to write out map-eo using loop

10:23 fogus`: fliebel: Because that's what I already use and was hoping for a better way

10:24 fliebel: fogus`: ##(map (comp - last) (partition 2 [1 2 3 4 5 6]))

10:24 sexpbot: ⟹ (-2 -4 -6)

10:24 mrBliss: not so pretty: ##(mapcat (fn [[a b]] [a (- b)]) (partition 2 [1 2 3 4]))

10:24 sexpbot: ⟹ (1 -2 3 -4)

10:24 AWizzArd: If you want to do it index based then an index would be required. But if you have one then for can be used for that.

10:25 for can combine map+filter.

10:25 opqdonut: ,(map #(%1 %2) (cycle [inc identity]) [1 1 1 1 1])

10:25 clojurebot: (2 1 2 1 2)

10:25 opqdonut: I kinda like that

10:25 is there a better name for #(%1 %2) ?

10:27 AWizzArd: ,(map-indexed #(if (even? %1) %2 (- %2)) [10 20 30 40])

10:27 clojurebot: (10 -20 30 -40)

10:27 AWizzArd: this could also work for you fogus`

10:27 fogus`: BTW, map-eo shouls also work like this: (map-eo - [1 2 3 4] [1 2 3 4]) ==> (1 0 3 0)

10:27 opqdonut: errrr

10:27 should it choose the first or the second?

10:27 consider (map-eo - [1 2 3 4] [5 5 5 5])

10:29 fogus`: It should work just like map, but only on e every other elem

10:29 opqdonut: ...

10:29 AWizzArd: fogus`: what would happen for (map-eo - [10 20 30 40] [1 2 3 4]) ?

10:29 fogus`: (10 18 30 36)

10:30 AWizzArd: so, for even indexes it should just return the object from its first argument-sequence?

10:31 opqdonut: ,(let [app (fn [f & rest] (apply f rest)) fst (fn [f & rest] f)] (map app (cycle [fst -]) [10 20 30 40] [1 2 3 4]))

10:31 clojurebot: (10 18 30 36)

10:33 fogus`: AWizzArd: right. First seq is special in that way

10:35 raek: fogus`: why include n/2 dummy values in the second seq?

10:36 (map-eo - [10 20 30 40] [:dummy 2 :dummy :4])

10:37 fogus`: raek: ?

10:37 AWizzArd: fogus`: I would probably suggest to go with map-indexed if you have one argument seq and probably map when you have several and just do the checking yourself

10:38 ,(map-indexed #(if (even? %1) %2 (- %2)) [10 20 30 40])

10:38 clojurebot: (10 -20 30 -40)

10:38 AWizzArd: ,(map #(if (even? %1) %2 (- %2 %3)) (range) [10 20 30 40] [1 2 3 4])

10:38 clojurebot: (10 18 30 36)

10:39 fogus`: AWizzard: oooo

10:40 opqdonut: (my solution is general!)

10:40 (yes, it's also somewhat horrible)

10:41 mrBliss: ,(letfn [(map-eo [f & colls]

10:41 (apply map #(%1 %&) (cycle [first #(apply f %)])

10:41 colls))]

10:41 (map-eo - [10 20 30 40] [1 2 3 4]))

10:41 clojurebot: EOF while reading

10:42 mrBliss: I shouldn't copy paste it from a repl ##(letfn [(map-eo [f & colls] (apply map #(%1 %&) (cycle [first #(apply f %)]) colls))] (map-eo - [10 20 30 40] [1 2 3 4]))

10:42 sexpbot: ⟹ (10 18 30 36)

10:42 AWizzArd: fogus`: although, if you require it often then maybe something like (def map-eo (fn [f & args] (apply map #(if (even? %1) %2 (apply f %2 %&)) (range) args))) would be handy

10:44 fogus`: These are pretty nice... but now how to make map-eo-nth :-O ;-)

10:45 AWizzArd: That is left for the interested reader.

10:46 ejackson: exercise for the student...

10:46 fogus`: LOL

10:46 ejackson: or, if it was really written by an academic: the extension to map-eo-nth is trivial.

10:46 fogus`: Thanks all. It was fun

10:47 AWizzArd: fogus`: plus you would need to specify if F should be applied to every nth element, or if every nth element is the one to which F will *not* be applied.

10:48 (map-eo-nth 3 - [10 20 30 40 50 60 70 80 90]) ==> (-10 20 30 -40 50 60 -70 80 90) ?

10:48 Or (10 -20 -30 40 -50 -60 70 -80 -90)?

10:48 fogus`: AWizzArd: Which makes me very happy that Clojure has avoided the proliferation of kwargs

10:49 i.e. (map - [10 20 30 40 50 60 70 80 90] :from 0 :every 4)

10:50 AWizzArd: But what would be the result?

10:51 From your map-eo I would interpret it as: F is *not* applied to every n-th element, but to all others.

10:51 So (map-eo-nth 3 - [10 20 30 40 50 60 70 80 90]) should result in ==> (10 -20 -30 40 -50 -60 70 -80 -90)

10:53 fogus`: AWizzArd: No idea... I was just playing

10:54 Guest66680: does anybody know if clojureql can do "select ... where column in(v1,v2,v3...)"?

11:06 answer to own question: it can be done by using clojureql.predicates/in directly; clojureql.core/where doesn't seem to support it

11:30 zanes: I have some confusion about using Clojure with Emacs and swank. I just finished setting everything up and when I evaluate an expression with C-x e the output goes to the minibuffer rather than the REPL buffer. Is that normal?

11:30 mrBliss: zanes: perfectly normal

11:31 (although you probably mean C-x C-e :)

11:31 LauJensen: Guest66680: You're on a dated version, 1.0.0 does support (where (in ....))

11:33 fliebel: Funny, this morning I thought sorting was a strange thing. Sorting as I knew it involved pretty much comparing every element to every other element, while the way I sort a pile of cards is much simpler. So I wrote a Clojure function to do that, and then found out it's called pigeonhole sort. Anyway, here's my implementation: https://gist.github.com/774664

11:36 Berengal_: fliebel: Sorting can be pretty interesting

11:36 fliebel: Sad thing is that it is still slower than the built in sort.

11:38 Berengal_: What does the built-in sort use?

11:38 fliebel: No idea...

11:39 Scriptor: I wonder if it's optimized depending on what the list is like

11:39 Berengal_: Probably

11:39 fliebel: Berengal, Scriptor: http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#sort(byte[])

11:40 Berengal: Is that what clojure uses?

11:40 Scriptor: ah, quicksort

11:40 fliebel: Berengal: Yes

11:40 Scriptor: https://github.com/clojure/clojure/blob/b578c69d7480f621841ebcafdfa98e33fcb765f6/src/clj/clojure/core.clj#L2329

11:41 Berengal: fliebel: How does that work when clojure structures are trees?

11:41 Scriptor: there's the exact clojure code, looks like it basically wraps Array.sort

11:41 mrBliss: "The java.util.Arrays.sort function officially uses a Dual-Pivot Quicksort, though the OpenJDK implementation recently switched from a modified mergesort to a Timsort."

11:43 Berengal: I don't think the Timsort version has been officially released yet

11:43 mrBliss: I got it from this interesting comparison: http://stringoftheseus.com/blog/2011/01/10/api-sorting-algorithms/

11:45 Berengal: Seems there are some good benefits to be had from specializing sort on certain structures

11:45 Particularly lists and vectors

11:46 fliebel: What would be then main reason my sorting thing is a lot slower than Java sort?

11:49 Somelauw: You can't quicksort a linked link, can you?

11:49 mrBliss: Somelauw: it would be slowsort :)

11:50 Berengal: Somelauw: Depends on how you define quicksort. You can't do the clever swapping during partitioning

11:50 mrSpec: Hello! I have function thats returns list of structures. But max-key doesnt takes list as argument, but structures. Is it possible to put all elements from list as argument into this function?

11:51 Somelauw: apply

11:51 mrBliss: ,(apply max-key first [[1 2] [4 3] [2 3]])

11:51 clojurebot: [4 3]

11:51 mrSpec: thanks!

12:07 ymasory_: clojurebot: (println (count (str (filter (fn [ch] true) "abc"))))

12:07 clojurebot: Counterclockwise aka ccw at http://code.google.com/p/counterclockwise/

12:08 ymasory_: why would that be 26 and not 3?

12:08 mrBliss: ,(str (filter (fn [ch] true) "abc"))

12:08 clojurebot: "clojure.lang.LazySeq@1ecc1"

12:09 mrBliss: ,(println (count (apply str (filter (fn [ch] true) "abc"))))

12:09 clojurebot: 3

12:10 ymasory_: i still don't understand

12:11 ejackson: ,(str (filter (fn [ch] true) "abc"))

12:11 clojurebot: "clojure.lang.LazySeq@1ecc1"

12:11 ejackson: ,(count (str (filter (fn [ch] true) "abc")))

12:11 clojurebot: 26

12:12 mrBliss: ymasory_: str on a seq serializes it, i.e. "clojure.lang.LazySeq@1ecc1", you have to 'apply' str. ##(doc str)

12:12 sexpbot: ⟹ "([] [x] [x & ys]); With no args, returns the empty string. With one arg x, returns x.toString(). (str nil) returns the empty string. With more than one arg, returns the concatenation of the str values of the args."

12:12 ejackson: you need to use apply like mrBliss says

12:12 raek: or use pr-str

12:12 ymasory_: i see thank you

12:12 raek: ,(pr-str (filter (fn [ch] true) "abc"))

12:12 clojurebot: "(\\a \\b \\c)"

12:20 S11001001: ,(String. (into-array Character/TYPE (filter (constantly true) "abc")))

12:20 clojurebot: "abc"

12:59 mrSpec: Can't I do: (subvec (sort ...) 0 5) ? What should I use instead of subvec?

13:00 qbg: (take 5 (sort ...))

13:01 mrSpec: o! thanks :)

13:01 hiredman: sort doesn't return vector, subvec works on vectors, why would you expect that to work?

13:04 mrSpec: yes, so I was looking for some other function which would work.

13:20 Berengal: Is there a way I could have a function drop into a repl and let me manually return a value?

13:24 opqdonut: (eval (read)) ?

13:25 for example, user=> (defn f [] (+ 1 (eval (read)))) (f) ENTER (+ 1 1) ENTER evaluates to 3

13:25 raek: read does not work very well if you try to use it in the emacs repl

13:26 opqdonut: ok, sure

13:26 Berengal: Nor is it a proper repl, where you can muck around as much as you like

13:27 opqdonut: well you can spawn a repl using some mechanism and then use refs or something for communication

13:27 raek: opqdonut: you could also use swing (consider the ask part): https://gist.github.com/480608

13:27 opqdonut: heh

13:27 raek: ...in case that program has access to an X display

13:28 Berengal: raek: A safe assumption, considering it's mostly useful for development

13:28 opqdonut: but that's not a real repl either

13:28 Berengal: No, indeed not

13:29 raek: how would a real repl respond?

13:29 Berengal: (exit return-value)

13:29 or something

13:29 raek: (def *query*)

13:29 opqdonut: Berengal probably wants to be able to evaluate a bunch of exprs and see the results and then say (the-final-answer-is foo)

13:30 Berengal: Yes.

13:31 raek: (let [p (promise)] (later-var-root #'*query* (constantly p)) (deref p)) ;; receiver end

13:31 (deliver *query* 123) ;; sender end

13:31 Berengal: That would probably work just fine

13:32 raek: a bit ugly, since it only allows one pending query

13:32 Berengal: That can be hidden with some queuing and plumbing functions

13:32 And it won't be a problem if there's only one thread anyway

13:33 (It will be a problem if it's the same thread as the repl thread)

13:33 raek: you could perhaps generate a unique number for each, print a message to the user containing that, and let him answer with (answer <id> <value>) or something

13:33 ok, just generalizing... :-)

13:35 Berengal: Well, implementing some queuing and a decent interface, such as switching from one query to another, automatically binding query-locals and whatnot should only be a couple of lines of code anyway

13:38 Now I only need to figure out how to instantiate an arbitrary class with arbitrary args

13:39 raek: Berengal: you need java reflection to do that at run-time

13:40 Berengal: raek: Nothing like (apply .newInstance class args)?

13:41 Oh, neat, java.lang.reflect.Constructor takes an Object[] :)

13:42 raek: no, since 'new'/dot-at-the-end is a special form

13:43 if compile-time is fine, you could always make a macro that expands into a 'new' form

13:43 amalloy: Berengal: clojure.lang.Reflector does the things you want, yes?

13:43 Berengal: amalloy: Hadn't looked at that. Thanks for the tip

13:43 raek: I know, but I was hoping there was an equivalent alternative

13:46 amalloy: ,(clojure.lang.Reflector/invokeConstructor java.util.Date (into-array [10 10 10]))

13:46 clojurebot: #<Date Thu Nov 10 00:00:00 PST 1910>

13:46 amalloy: Berengal: tada!

13:46 Berengal: amalloy: nice :)

13:49 signalseeker: Can someone refer me to an uptodate post on setting up clojure with emacs/slime? Thanks

13:49 technomancy: signalseeker: if the swank-clojure readme doesn't cover it please mention what's missing/confusing on the mailing list.

13:51 signalseeker: technomancy: I was looking for a starting point because there are tons of blog posts about it. Let me give it a shot

13:51 raek: (jochu's repo is first on google, but technomancy's one is the up to date one)

13:53 technomancy: are your changes always pulled into jochu's repo?

13:54 technomancy: raek: no; I need to push a deprecation notice to jochu's readme.

13:59 Berengal: Has anyone tried the clojure maven plugin on windows?

14:01 I tried it today, but couldn't get it to start swank. I found a couple of issues on github regarding errors in command-line handling, but they were both solved

14:54 mrSpec: one more newbie question... what is the name of funtion remove-if in clojure? I've used it but forgot its name :(

14:55 hiredman: you mean remove?

14:57 mrSpec: sorry, not remove remove-if-not

14:57 ossareh: my love for -> / ->> grows daily

14:58 kotarak: (->> "Strange things happen" println (when fiasco))

14:58 mrSpec: I have list: '({:a 1 :b 2} {:a 3 :b 4}) and I'd like to get elements where :a is 1

14:59 raek: mrSpec: filter

14:59 mrSpec: thanks!

15:00 ossareh: mrSpec: filter, map, apply and reduce are really really helpful functions - definitely where I'd start a book where I writing one.

15:01 dakrone: ,(filter #(= (:a %) 1) '({:a 1 :b 2} {:a 3 :b 4}))

15:01 clojurebot: ({:a 1, :b 2})

15:21 danwerner: hi there

15:22 i'm trying to find a var in clojure.core: letfn*

15:22 kotarak: letfn* is a special form, IIRC

15:24 danwerner: kotarak: that's interesting. do you know why it wasn't implemented as a macro?

15:24 LauJensen: hey danwerner

15:24 kotarak: danwerner: no. Probably because you can't get the mutual recursiveness from Clojure's other constructs.

15:25 danwerner: kotarak: yes, makes sense. thanks meikel

15:26 LauJensen: hey lau. hope you got some calm & peace during the christmas celebrations

15:27 LauJensen: danwerner: I sure did - Especially since I dont celebrate christmas :) Have you put Clojure to good use at the work place yet?

15:31 danwerner: LauJensen: I might have found just the opportunity. we'll have to build a web scraping cron job thingy that doesn't depend on the rest of the code base, and isn't mission-critical, so I'll try to convince my superior to give Clojure a shot

15:31 LauJensen: Great, that sounds like a perfect fit

15:32 danwerner: LauJensen: Yes, especially with enlive -- I'm glad you convinced me to give it another try

15:33 LauJensen: Yea scraping with Enlive is really a treat

15:35 danwerner: is there a general word about how clojure-in-clojure is coming along?

15:35 LauJensen: danwerner: I dare not even ask anymore

15:43 fliebel: danwerner: Someone else has done a unofficial CinC.

15:44 danwerner: mhh, i wonder whether it would make sense to incrementally convert the java part of the implementation to deftype/def{interface,protocol}, a naive almost 1:1 port of the current structure that could then be refined

15:45 fliebel: nice. do you have an URL or something?

15:45 fliebel: I'm searching

15:46 ah! https://github.com/jarpiain/cljc

15:47 SergeyD: Slightly off-topic question: what does it mean "ANN:" in the beginning of a Clojure email subject?

15:47 danwerner: SergeyD: ANN = announcement

15:47 fliebel: danwerner: If you use it, please tell me how it goes, or blog about it or something.

15:47 SergeyD: danwerner: thanks :)

15:51 goodmike_mh: Does anyone know why I would be unable to require clojure.string? I'm in a swank session I started from lein swank, in a project that lists [org.clojure/clojure "1.2.0"] as a dependency.

15:52 but I get "Could not locate clojure/string__init.class or clojure/string.clj on classpath"

15:52 I swear I've been here before.

15:53 ossareh: goodmike_mh: could you throw your ns statement into a gist or pastebin or something?

15:54 goodmike_mh: string is definitely available to you - likely it is either a syntax issue or a conflict in bringing it in (I think replace occurs in both string and core)

15:54 goodmike_mh: If I just try '(require '[clojure.string :as str])' at the REPL, it fails

15:54 (require '[clojure.string :as str])

15:55 I can pastie the project.clj

15:55 Licenser: goodmike_mh: be careful with that, str is a function :)

15:55 cal it cs that is what I usually do

15:56 ossareh: goodmike_mh: the problem isn't going to be in project.clj - string is part of c.core

15:56 goodmike_mh: right

15:56 Licenser: anyway I need to go to bed :) take care and good luck with fingind that strings of yours

15:57 brehaut: Licenser: i didnt think requiring a namespace with an alias overrides a var with the same name?

15:57 Licenser: or do you just mean its bad style?

15:57 ossareh: goodmike_mh: fwiw that form evals for me - so likely to be something else.

15:57 goodmike_mh: @Licenser It's common to see clojure.string required as str

15:58 ossareh: what ns are you in when you do that? is it a new ns?

15:58 goodmike_mh: E.g. the project I'm working in is fogus's Marginalia

15:58 user

15:59 danwerner: ossareh: did you try something like lein clean; lein deps to rebuild your dependencies? i seem to recall that accidentally having different clojure versions mixed in your libs can cause problems

15:59 ossareh: goodmike_mh: for you ^

15:59 goodmike_mh: danwerner: I'll try, thanks.

15:59 danwerner: oops ;)

15:59 ossareh: =)

16:02 goodmike_mh: danwerner: ran lein clean then lein deps then lein swank ...

16:02 In the terminal window I see Could not locate clojure/string__init.class or clojure/string.clj on classpath

16:03 danwerner: fliebel: thanks for the link to cljc. i'm looking for a way to write clojure on top of javascript, but cljc seems out of my league (complexity wise). especially not porting it to js :)

16:03 technomancy: goodmike_mh: what's *clojure-version* say?

16:03 fliebel: danwerner: There is already a basic project that does some Clojure to JS.

16:03 brehaut: goodmike_mh: eval *clojure-version* in your repl

16:03 danwerner: fliebel: i'm looking at https://github.com/kriyative/clojurejs right now

16:04 goodmike_mh: technomancy: {:interim true, :major 1, :minor 2, :incremental 0, :qualifier "master"}

16:04 fliebel: If you can get that to a state where it compiles Cljc, you're there, I think.

16:04 * technomancy scratches his head

16:05 Berengal: So a promise looks very much like an I-var. Is there any discussion around adding M-vars too?

16:05 goodmike_mh: Does leiningen create your own sandbox of dependencies per project? Or could it be getting confused because of other versions of Clojure or other libraries?

16:05 danwerner: fliebel: it doesn't have persistant data structures, though, and really only translates a clojure-like language to javascript. (which in itself is pretty cool already.)

16:05 technomancy: goodmike_mh: it does, but *clojure-version* confirms you have the right one

16:06 goodmike_mh: I blame fogus for everything.

16:07 amalloy: mrSpec: i was at lunch, but it looks like you got only a vague answer re filter

16:08 &(filter (comp #{1} :a) [{:a 1 :b 2} {:a 3 :b 4}])

16:08 sexpbot: ⟹ ({:a 1, :b 2})

16:08 amalloy: mrSpec: ^ is the easiest and most idiomatic way to do what you were trying to do

16:10 goodmike_mh: So, here's what I did. Would someone like to run through these steps to reproduce (or not?)

16:10 1. git clone https://github.com/fogus/marginalia.git

16:10 danwerner: goodmike_mh: is the error message caused by "lein swank", which then refuses to run?

16:10 goodmike_mh: 2. cd marginalia

16:10 3. lein deps

16:10 4. lein swank

16:11 technomancy: 3 is actually unnecessary now

16:11 goodmike_mh: danwerner: error comes from swank

16:11 technomancy: really? lein swank will pull in deps?

16:11 technomancy: goodmike_mh: you only need to call deps manually when you change project.clj

16:12 even that should be unnecessary in lein 2

16:12 goodmike_mh: but if you've just cloned a project repo, you would need to lein deps to start, right?

16:13 technomancy: no

16:13 goodmike_mh: wow

16:13 danwerner: goodmike_mh: followed your steps, got "Connection opened on local port 4005\n#<ServerSocket ...>

16:13 technomancy: goodmike_mh: just cloned marginalia; works for me

16:13 * goodmike_mh weeps silently

16:13 danwerner: goodmike_mh: i used lein 1.3.1 though

16:14 goodmike_mh: Oh well. The gods are against me.

16:14 technomancy: goodmike_mh: is it any different in lein repl vs swank?

16:14 goodmike_mh: good question...

16:14 no difference. same error message, although REPL starts.

16:16 danwerner: Leiningen 1.3.1 for me too.

16:16 danwerner: goodmike_mh: do you perhaps have any stale swank processes open that use the wrong clojure version?

16:16 technomancy: goodmike_mh: no reason not to run the latest; try "lein upgrade"

16:17 goodmike_mh: danwerner: killing my terminal windows and emacs...

16:17 running 'lein upgrade'

16:18 Now running Leiningen 1.4.2 on Java 1.6.0_22 Java HotSpot(TM) 64-Bit Server VM

16:18 danwerner: technomancy: lein 2 is not yet "stable", is it?

16:18 mrSpec: amalloy: Ok, thanks! :)

16:18 goodmike_mh: lein repl gives me the same error

16:18 technomancy: danwerner: it has maybe two commits on that branch so far

16:19 fogus`: you want to set :eval-in-leiningen true in marginalia's project.clj if you want tests etc. to run in the same process as lein

16:19 danwerner: technomancy: lein swank gives "That's not a task" if i don't do "lein deps" before

16:20 technomancy: danwerner: oh right; that would only work if you had swank installed for your user

16:20 goodmike_mh: I just tried lein repl in a new project made from lein new, and no error message.

16:20 technomancy: but in general lein will know to run deps when it's needed

16:21 danwerner: goodmike_mh: "ls lib/" for me says "clojure-1.2.0.jar clojure-contrib-1.2.0.jar dev/ hiccup-0.3.0.jar markdownj-1.0.2b4.jar". is it the same for you?

16:21 goodmike_mh: in Marginalia?

16:22 clojure-1.2.0.jar dev markdownj-1.0.2b4.jar

16:22 clojure-contrib-1.2.0.jar hiccup-0.3.0.jar

16:22 yuck

16:22 danwerner: goodmike_mh: yes. "ls lib/dev/" is: "clojure-1.2.0.jar hiccup-0.3.0.jar jsch-0.1.42.jar lein-clojars-0.5.0-20091119.123056-6.jar markdownj-1.0.2b4.jar clojure-1.2.0.jar hiccup-0.3.0.jar jsch-0.1.42.jar lein-clojars-0.5.0-20091119.123056-6.jar markdownj-1.0.2b4.jar"

16:22 goodmike_mh: clojure-1.2.0.jar dev markdownj-1.0.2b4.jar clojure-contrib-1.2.0.jar hiccup-0.3.0.jar

16:23 danwerner: looks the same, yes

16:25 danwerner: mystifying

16:27 fogus`: technomancy: Is the lack of :eval-in-leiningen causing issues?

16:27 technomancy: fogus`: it's complicating things since there are two processes where there should be one.

16:28 it's unlikely it's causing issues, but it could be masking the causes of issues like the above

16:28 fogus`: technomancy: sold

16:28 fliebel: fogus`: How far along is JoC?

16:29 fogus`: fliebel: done

16:29 fliebel: fogus`: "Softbound print: February 2011 (est.)"

16:29 cow_: can someone tell me what is the right function to compare to java byte arrays? (byte[])

16:29 fogus`: fleibel: Sounds about right to me

16:30 cow_: s/to/two/

16:30 sexpbot: <cow_> can someone tell me what is the right function two compare two java byte arrays? (byte[])

16:31 cow_: i have two separate arrays with the same contents and (=) returns false.

16:31 fogus`: technomancy: this is what you mean correct? https://github.com/fogus/marginalia/commit/f9f212ffbfa5e8f9d1556eeca240a20803d4aa80

16:31 fliebel: cow_: Uh? .equals?

16:31 technomancy: fogus`: quite

16:31 fogus`: Thank you sir

16:31 technomancy: fogus`: also, for plugins the convention is to put a one-liner in the namespace docstring and the longer version in the defn's docstring

16:31 makes the lein help output prettier

16:32 np

16:32 fogus`: OK. I will take care of those other changes tonight.

16:32 cow_: ,(.equals (.getBytes "abc") (.getBytes "abc"))

16:32 clojurebot: false

16:32 amalloy: &(apply = (repeatedly 2 #(into-array Byte/TYPE (range 10))))

16:32 sexpbot: java.lang.IllegalArgumentException: argument type mismatch

16:33 technomancy: fogus`: minor point, but I thought I'd mention it.

16:33 cow_: (= (.getBytes "abc") (.getBytes "abc"))

16:33 ,(= (.getBytes "abc") (.getBytes "abc"))

16:33 clojurebot: false

16:33 amalloy: cow_: java arrays don't implement equals by value

16:33 try seq-ing them first

16:33 cow_: amalloy: right... i'm trying to discover if there is a function

16:33 ahhh... ok

16:33 amalloy: &(= (seq (.getBytes "abc")) (seq (.getBytes "abc")))

16:33 sexpbot: ⟹ true

16:34 amalloy: cow_: kinda a hack imo, but it will work

16:34 cow_: amalloy: thanks. i forgot all about that

16:34 goodmike_mh: I can require other core libraries, e.g. (require '[clojure.walk :as walk]) is fine.

16:35 what's special about string?

16:35 danwerner: goodmike_mh: IIRC it got promoted to core in 1.2. what happens if you require clojure.contrib.str-utils2?

16:36 goodmike_mh: danwerner: It works fine

16:36 (require '[clojure.contrib.str-utils2 :as foo])

16:36 no errors

16:37 danwerner: goodmike_mh: okay, works for me as well. it's deprecated but hasn't been removed yet

16:39 goodmike_mh: Thanks, danwerner and technomancy, for the help. I'll try coming back to the problem in a bit.

16:41 dakrone: ,(.compareTo (java.nio.ByteBuffer/wrap (.getBytes "abc")) (java.nio.ByteBuffer/wrap (.getBytes "abc")))

16:41 clojurebot: 0

16:41 dakrone: ,(.compareTo (java.nio.ByteBuffer/wrap (.getBytes "abc")) (java.nio.ByteBuffer/wrap (.getBytes "nth")))

16:41 clojurebot: -1

16:41 dakrone: cow_: ^^

16:42 amalloy: dakrone: goodness, that seems like much heavier machinery than necessary

16:43 dakrone: amalloy: may be :)

16:54 TakeV: I have a list of structs, and each struct has a list of hash maps. How do I filter the top list so that I get just a list containing structs with a certain component in their hash maps?

16:55 goodmike_mh: OK, so when I unpack the clojure JAR file in my project's lib directory, there is no string.clj in there

16:55 amalloy: TakeV: this sounds like what mrSpec was doing an hour or two ago

16:56 danwerner: goodmike_mh: wow

16:56 goodmike_mh: yeah

16:56 I must be special.

16:58 danwerner: goodmike_mh: do you have string$*.class ?

16:58 goodmike_mh: nope

16:59 TakeV: amalloy: Hmm, I don't see it.

16:59 amalloy: TakeV: do you really mean each struct has a *list* of hash-maps (like foo is {[{:a 1} {:b 2}]}), or do you mean something more normal like the values in your struct are hash-maps?

16:59 danwerner: goodmike_mh: i'd rid my ~/.m2/repository/org/clojure directory from all evil by deleting it

16:59 goodmike_mh: hmm. decisive action.

16:59 danwerner: goodmike_mh: then lein clean; lein deps would be forced to acquire new jars

16:59 TakeV: amalloy: Sorry, each struct has a list of hash-maps.

17:00 amalloy: TakeV: and that one list is always under the same key, like :maps or something?

17:00 danwerner: is there any way to import functions marked as :private true in another namespace?

17:01 'use and 'require both complain

17:01 TakeV: amalloy: Yes. :components

17:01 qbg: danwerner: Sounds like a bad idea

17:02 TakeV: amalloy: I want to split off a list from the top level by what components the bottom levels has, update them, then remerge them back into the main list.

17:02 danwerner: qbg: i'd like to use clojure.core/assert-args without copying it

17:03 goodmike_mh: danwerner: nuking the maven repo file seems to have worked.

17:03 qbg: Its probably a bad idea to use something that is not part of a documented interface

17:03 But if you really need to, you can go through the var

17:03 danwerner: goodmike_mh: cool. no missing clojure.string anymore?

17:03 goodmike_mh: It can't hide from me anymore!

17:04 amalloy: (filter (comp #(some #{:a} (mapcat keys %)) :components) all-the-structs) maybe?

17:04 qbg: Though I'm not sure how well that will work considering it is a macro

17:04 Probably won't

17:06 amalloy: TakeV: ^

17:06 qbg: You could do (def ^{:macro true} assert-args @#'clojure.core/assert-args)

17:06 TakeV: amalloy: Sorry, trying to figure out what that does.

17:08 amalloy: heh, me too

17:08 TakeV: amalloy: What does "#{:a}" do?

17:08 amalloy: &(class #{})

17:08 sexpbot: ⟹ clojure.lang.PersistentHashSet

17:08 danwerner: qbg: nice hack. i've seen somebody else use assert-args before, and he copy&pasted it as well. might be worthwhile to add it to the public interface since it's so useful

17:08 amalloy: &(map #{:a} [:a :b])

17:08 sexpbot: ⟹ (:a nil)

17:09 amalloy: TakeV: constructs a set containing the single keyword :a. when called as functions, sets return something truthy iff the set contains the function argument

17:10 TakeV: amalloy: Oh, right. Sorry, I was parsing that as a fn macro.

17:11 S11001001: &(#{false} false)

17:11 sexpbot: ⟹ false

17:11 S11001001: false

17:11 amalloy: S11001001: yeah, i know. very sad

17:11 so if you want to include false, you can put a (complement nil?) at the front of that comp

17:11 S11001001: better to remember that it returns the thing, then

17:12 or just use (partial contains? #{...})

17:14 tomoj: amalloy: would you rather sets returned booleans?

17:15 amalloy: tomoj: i'm not sure. it seems rare that i use the self-returning feature, and common that i use it in a filter, but that could be sampling bias

17:16 tomoj: seemed rare to me too

17:17 amalloy: same thing with (some), really - i never want (f x) back, i always want x

17:17 can call f my damn self if i want :P

17:20 Berengal: raek: That drop-into-repl thing? Works like a charm

17:26 Are there any persistent dequeues around?

17:30 amalloy: Berengal: chouser's finger trees would work, but i'm not sure how stable they are

17:30 $google chouser github finger tree

17:30 sexpbot: First out of 30 results is: Chouser/talk-finger-tree - GitHub

17:31 https://github.com/Chouser/talk-finger-tree

17:31 amalloy: Berengal: it's actually at https://github.com/Chouser/finger-tree - not sure why google finds the wrong one

17:32 qbg: Maybe the talk is more interesting than the code

17:32 amalloy: qbg: chris is an interesting talker

17:32 Berengal: They aren't already in core/contrib?

17:32 Ooh, talk, where?

17:32 amalloy: Berengal i don't think they are, no

17:33 qbg: I think they the finger trees might move to contrib after 1.3

17:36 Berengal: I can't really depend on something that isn't automagically downloaded...

17:36 arohner: is there a preduce anywhere?

17:36 Berengal: Do vectors support easy adding at the front?

17:37 tonyl: list do

17:38 Berengal: But lists don't support easy adding at the end

17:38 amalloy: Berengal: it's probably in clojars

17:39 well, i guess not

17:39 Berengal: amalloy: I couldn't find it there

17:39 S11001001: well "easy", if it just does (vec (cons elt vec)) then what is it doing really?

17:40 hmm, there's a binding problem there

17:40 amalloy: Berengal: you can download it and put it there yourself, if you want to make it available for auto-download

17:40 Berengal: amalloy: What, even though I'm just some random person on the internet?

17:41 amalloy: Berengal: indeed!

17:41 Berengal: Quite the free-for-all :)

17:42 amalloy: Berengal: just don't make it look like an official finger-tree release

17:42 put it under berengal/finger-tree instead of (chouser|finger-tree)/finger-tree

17:42 Berengal: Ah, ok

17:43 Eh... Cons doesn't implement IPersistentStack?

17:44 Guess that means it's time for bed

17:45 tomoj: S11001001: seems if you call vec at all you've already lost

17:49 amalloy: tomoj: ##(nth (iterate vec (range 100)) 10000) doesn't cost too much :)

17:49 sexpbot: ⟹ [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99]

17:52 tomoj: that's a very short vector

17:52 amalloy: tomoj: but i suspect (vec [...]) is a no-op

17:52 tomoj: (vec (conj v x)) can be hundreds of times slower than just (conj v x)

17:52 for a long vector

17:52 I would've thought so too

17:52 maybe I screwed my test up

17:53 ,(let [v (vec (repeat 1000000 0))] (time (when (vec (conj v 0)))) (time (when (conj v 0))))

17:53 amalloy: $source vec

17:53 sexpbot: vec is http://is.gd/kAbaj

17:53 clojurebot: Execution Timed Out

17:53 qbg: ,(class (vec [1 2 3]))

17:53 clojurebot: clojure.lang.PersistentVector

17:54 qbg: ,(class (vec '(1 2 3)))

17:54 clojurebot: clojure.lang.PersistentVector

17:54 danwerner: is there a manual for sexpbot/clojurebot somewhere? =)

17:54 amalloy: tomoj: wow, you're right

17:54 $help

17:54 sexpbot: You're going to need to tell me what you want help with.

17:54 amalloy: bah

17:54 tomoj: ,(apply identical? ((juxt identity vec) [1 2 3]))

17:54 clojurebot: false

17:55 ossareh: http://github.com/Rayns/sexpbot/wiki/Plugin-quick-start-guide

17:55 amalloy: danwerner: usage manual or dev manual?

17:55 danwerner: amalloy: usage, e.g. what's the difference between & and ##

17:56 amalloy: danwerner: & only works at the beginning of a string, whereas ##(inc 1)-style requests are allowed ##(inc 2) anywhere

17:56 sexpbot: (inc 1) ⟹ 2

17:56 (inc 2) ⟹ 3

17:58 danwerner: amalloy: thanks

17:58 amalloy: danwerner: np. i added the ## feature, and i'm more or less the only person who uses it :)

17:59 danwerner: amalloy: well, ##(identity "not anymore") ;-)

17:59 sexpbot: ⟹ "not anymore"

18:00 ossareh: #("image we only spoke through sexpbot")

18:00 fail.

18:00 amalloy: ossareh: it's so hard to hit the same key twice in a row, eh?

18:01 ossareh: hah, that or I really don't know the difference between 3 and 7

18:01 danwerner: ##"any form"

18:02 amalloy: danwerner: actually ## only triggers on ##(

18:02 danwerner: ##(str "ah" "not" "any" "form")

18:02 sexpbot: ⟹ "ahnotanyform"

18:02 amalloy: it's on my todo list

18:02 for sometime in 2011

18:06 danwerner: amalloy: have you looked at the clojurebot source II lately? it now uses conduit for its data shoveling

18:08 amalloy: danwerner: not lately, but i remember seeing the conduit thing

18:10 danwerner: amalloy: most of the people i've asked who used monads in clojure at times, eventually discontinued to do so. have you used monads in clojure yet?

18:11 amalloy: no. read about them a few times and sorta understand what the idea is, but i haven't internalized them enough to notice when i ought to use them

18:33 raek: with all the on-by-default goodies of emacs-starter-kit, I am king of the world.

18:36 danwerner: raek: does that include proper paredit support for clojure? i remember i had to patch something up manually

18:37 raek: yes, it includes fixes for { }

18:37 at least that was what I had to patch

18:38 arohner: is there a preduce implemented anywhere?

18:39 amalloy: arohner: preduce can't work unless your function is associative, so i don't think there's a built-in

18:39 it might even have to be commutative? i'm not sure

18:40 arohner: amalloy: yes, it has to be commutative. That's pretty standard. Google's map reduce has no problems running massively parallel

18:40 rhickey has a couple of side projects that contain preduce, but both require jsr166, which I can't find anywhere

18:48 ossareh: arohner: is jsr166 the fork/join stuff?

18:48 arohner: ossareh: yeah

18:50 ossareh: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166y/

18:50 arohner: ^

18:51 arohner: ossareh: thanks. I've seen that, still trying to figure out how to make clojure happy with it :-(

19:00 danwerner: arohner: i've never tried it, but it should be sufficient to put http://clojure.googlegroups.com/web/jsr166y.jar on your classpath

19:02 arohner: danwerner: aha, thanks

19:02 danwerner: that's a different version from the 'official' one

19:06 danwerner: arohner: in what way different?

19:06 arohner: danwerner: the ParallelArray.class is in a different namespace/package

19:07 apparently the up to date official version has it in a different location than it was when rhickey built that one

19:07 danwerner: i see

19:07 arohner: and clojure.parallel imports the old location

19:08 danwerner: arohner: have fun then, and a good night

19:09 arohner: danwerner: I will! thanks for the tip

19:26 Zane19: hi

20:32 a_strange_guy: /msg NickServ identify w3r5z7

22:00 currentB: so if I want a program to continually print lines while it's running, what's the best way to avoid the nil that's being returned to constantly be shown in the repl?

22:01 amalloy: currentB: don't evaluate that line at the repl top-level?

22:01 currentB: k

22:01 amalloy: &(do (println 10) "not nil")

22:01 sexpbot: ⟹ 10 "not nil"

22:01 amalloy: &(do (println 10))

22:01 sexpbot: ⟹ 10 nil

22:13 amalloy: chouser: is https://github.com/Chouser/finger-tree the state of the art on finger trees, or has development moved somewhere else?

22:16 dnolen: amalloy: I thought fingers-tree were here, https://github.com/clojure/data.finger-tree

22:17 amalloy: dnolen: aha, thanks

23:46 gtech: if you evaluate a buffer in emacs of a series of expressions is it normal that only the last output is printed?

23:46 last expression*

23:53 ah using, pr doesn't newline so it overwrites the output

Logging service provided by n01se.net