#clojure log - Jan 19 2010

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

0:00 defn: seen _ato?

0:00 clojurebot: seen _ato?

0:00 clojurebot: no, I have not seen _ato

0:00 defn: on freenode you can do a nickserv info on the nick

0:00 derrida: defn: well, i can't create one using that swank-project command

0:00 defn: derrida: create one?

0:00 derrida: defn: so i just used an existing project i downloaded

0:01 http://sprunge.us/VZMU

0:04 defn: derrida: get rid of the repositories line in the file, as well as that 2nd :dev-dependencies [[lein-clojars...]] line

0:04 that shouldn't be necessary

0:05 derrida: defn: thats the one you told me to add?

0:05 defn: no i told you to add the swank-clojure line

0:05 not the other one

0:05 derrida: ohhhh

0:06 defn: change org.clojure/clojure "1.1.0-alpha-SNAPSHOT" to "1.1.0-master-SNAPSHOT"

0:06 run lein deps again

0:06 rinse, repeat

0:07 derrida: hm

0:07 still not working

0:08 is it a problem that clojure 1.0 is being used with 1.1 contrib?

0:08 woah this is the java line starting the repl: java -classpath /home/derrida/.clojure/clojure-1.0.0-SNAPSHOT.jar:/home/derrida/.clojure/clojure-1.2.0-master-SNAPSHOT.jar:/home/derrida/.clojure/clojure-slim-1.0.0-SNAPSHOT.jar:/home/derrida/.clojure/clojure-slim-1.2.0-master-SNAPSHOT.jar:/home/derrida/.clojure/clojure-slim.jar:/home/derrida/.clojure/clojure-sources-1.0.0-SNAPSHOT.jar:/home/derrida/.clojure/clojure-sources-1.2.0-master-SNAPSHOT.jar:/ho

0:13 * derrida facepalms

0:13 derrida: defn: i think i found it

0:16 nah. same stuff http://pastie.org/784329

0:16 oh well, it's been fun

0:26 alexyk: somnium: I recompiled the heck out of clojure/contrib/leiningen congomongo and can no longer use it :(

0:27 says can't locate somnium/congomongo.clj on the classpath

0:27 I see that congomongo.jar has src/clj/congomongo.jar

0:27 how is it being added to classpath as somnium/congomongo.clj?

0:30 defn: derrida: wish i could be of more help, but im not sure what you're trying to accomplish

0:30 derrida: i want to use clojure tha way i use clozure

0:31 defn: im not familiar with clozure so you'll need to be more explicit

0:32 derrida: did you ever use slime prior to clojure?

0:33 i use it as an integral part of my development process where i'm really interacting with my code (as i code/while i code)

0:33 alexyk: derrida: http://data-sorcery.org/2009/12/20/getting-started/

0:33 derrida: afaict, this is just a clojure repl inside of emacs?

0:34 alexyk: that sounds very promising from the first sentence :>

0:34 alexyk: i assumed that had to be the case which is why i'm feeling a bit unraveled by the whole thing

0:35 alexyk: yeah, stick to your current editor or use a careful setup guide

0:35 derrida: defn: more specifically, i will compile a file (derrida.lisp) [C-c C-k]

0:35 alexyk: ? i love emac

0:35 s

0:35 alexyk: ah ok, sry

0:36 derrida: defn: then, from the slime-repl, i'm able to access the running code

0:37 defn: currently, this is not happening and beyond just not happening emacs goes into a state of "constant polling" where it seems to just be endlessly trying to connect to the repl

0:38 technomancy: derrida: how are you launching slime?

0:38 derrida: when i hit [C-c C-k] for .1 second i see it say [Not Connected] in the minibuffer

0:38 M-x slime

0:38 technomancy: derrida: what's the content of ~/.swank-clojure?

0:39 derrida: the three jars that were installed by elpa (which didn't work) so i tried adding the root folder of swank-clojure in there also and had the same result

0:39 currently looks like this: clojure-1.1.0-master-20091202.150145-1.jar clojure-contrib-1.1.0-master-20091212.205045-1.jar pom.xml README src/ swank-clojure-1.1.0.jar target/

0:40 technomancy: derrida: are you on an older build of Emacs maybe?

0:40 hyp3rvigi1ant: derrida: i was having the same problem with slime...sometimes it would eventually connect after it polled for a few dozen times, but most of the time it would poll for hundreds of times with no results

0:40 derrida: git pull

0:40 technomancy: ^^

0:41 (about the git pull)

0:41 hyp3rvigi1ant: i wasn't going to say but i could have sworn it's connected a few times here too :)

0:42 i just assumed ihad accidentally started clozure instead

0:42 technomancy: derrida: all your deps seem to be in place, but maybe you could try just rm -rf ~/.swank-clojure and try again?

0:42 derrida: sure

0:42 technomancy: using swank-clojure and slime from elpa?

0:42 derrida: yeah, everything from elpa

0:42 hyp3rvigi1ant: i just tried it again now, and it's polled almost 250 times already, with no connection...but when i start swank using lein, and i connect to it from emacs, it works fine

0:42 derrida: i totally wiped emacs to get a clean slate

0:42 technomancy: hmm... I can't repro

0:43 never heard of that problem before

0:43 derrida: google cropped up some results

0:43 no answers

0:43 hyp3rvigi1ant: well, that's very interesting

0:43 technomancy: not finding clojure.lang.RT means it's a problem with Clojure, not with Swank or Emacs

0:43 hyp3rvigi1ant: I'm on Ubuntu using GNU Emacs 23.1.1 (i486-pc-linux-gnu, GTK+ Version 2.18.3)

0:43 of 2009-11-10 on vernadsky, modified by Debian

0:43 Ubuntu 9.10

0:44 derrida: how do you start swank from lein?

0:45 i have added nothing to my .emacs btw?

0:46 alexyk: somnium: pinggg

0:46 derrida: technomancy: what are you saying?

0:47 hyp3rvigi1ant: derrida: lein swank

0:47 you need to have [leiningen/lein-swank "1.1.0"] and [swank-clojure "1.1.0"] as dependencies in your project.clj file

0:48 derrida: so you would do this for each project you were working on?

0:48 hyp3rvigi1ant: that's what i do...i've been using lein since earlier today, though, lol...not a pro

0:49 derrida: :)

0:51 hyp3rvigi1ant: i do have swank-clojure jar-path, jar-home, and classpath set in my .emacs file...not sure if i have it set correctly or anything, though

0:52 derrida: technomancy: afaict that error is not saying it can't find clojure.lang.RT .. it's saying it can't find the swank class

0:53 technomancy: it's the standard ClassNotFoundException

0:56 technomancy: derrida: java.lang.NoClassDefFoundError: clojure/lang/RT (swank.clj:0)

0:56 derrida: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/NoClassDefFoundError.html

0:56 is this a different error?

1:03 hyp3rvigi1ant: would you mind showing me those lines from you .emacs

1:05 hyp3rvigi1ant: derrida: here's what it is currently: http://pastie.org/784366

1:06 derrida: thank you

1:06 hyp3rvigi1ant: np

1:14 alexyk: technomancy: how do I tell lein to start swank on a specific port?

1:22 technomancy: albino: it should accept it as a command-line argument

1:22 albino: okay

1:22 defn: Streaking

1:23 lol, oops

1:36 wooby: hello, i can't seem to get leiningen to recognize the 'swank' task

1:36 tomoj: did you add lein-swank to the dev-dependencies?

1:37 wooby: i've added swank-clojure to dev-deps, would anyone happen to know if there's something else i need to do?

1:37 aha

1:37 tomoj: yes, see the README.md in lein-swank/ for the details

1:37 though, back when I tried it last (which was a while ago) it didn't work right

1:38 when I slime-connect'd, the classpath wasn't set up right, so that I couldn't compile with C-c C-k

1:38 wooby: ah

1:38 tomoj: that may have been a problem with my setup or it may have been fixed since

1:39 wooby: i had it working at some point myself

1:43 wee, took some tinkering but it's working now

1:43 thanks again tomoj

1:46 tomoj: sure

1:46 I should try it again sometime

1:46 there is a small probability that I might get to use clojure in the wild for backend processing :D

1:46 (I currently prefer haskell or erlang :/ but those are even smaller probabilities)

1:47 replaca: Q: how do I get clojure-mode/slime to indent a macro's body form without telling it explicitly? I thought if I sent the macro to the slime buffer that would do it

1:48 technomancy: replaca: that's not implemented in the clojure backend currently, only for CL

1:49 replaca: the correct answer is "name your macro with-*"

1:49 =)

1:49 replaca: technomancy: ahh, ok. memories from the old days :-)

1:50 with-* would be a bad name for my macro :). It's a variant of for that makes maps

1:50 sparing me infinite into {}s

1:51 suddenly this week (for ...) and (merge-with ...) are my best friends

1:51 technomancy: merge-with is awesome

1:52 replaca: indeed. I'm in the midst of gluing multiple two-level maps together into three level maps

1:53 trying to figure out what's happening with thousands of our machines after they leave our factory

2:10 wooby: hm, anyone ever get "java.lang.Error: can't load apple.laf.AquaLookAndFeel" with swing on mac?

2:41 defn: wooby: sorry no -- someone did a tutorial on swing + mac not too long ago

2:41 check disclojure.org -- that's probably your best bet

2:43 wooby: defn: thanks, i managed to fix it... custom swank stuff conflicting with elpa

2:43 elpa's swank that is

2:45 defn: wooby: ah

2:45 wooby: now i'm cookin' ;)

2:45 thanks anyways, and goodnight

3:25 LauJensen: Anybody putting in work on clojure-android?

3:49 quizme: If i have a string like "{:a 1, :b 2}" how do I read that string as data?

3:49 i want to say something like (def x (eval "{:a 1, :b 2}"))

3:51 i want that Java string to be converted into a hashmap.

4:00 LauJensen: ,(read-string "{:a 5 :b 10}")

4:00 clojurebot: {:a 5, :b 10}

4:01 unfo-: cool! didn't know that

4:01 it's good to hang out here :)

4:01 spariev_: quizme: also see http://stackoverflow.com/questions/1885448/how-do-you-evaluate-a-string-as-a-clojure-expression

4:01 quizme: ok thank you

4:03 read-string ... that's what i wanted. thanks

4:05 LauJensen: np

4:14 defn: just a note to anyone who has been dragging their feet: The Joy of Clojure is absolutely the Book to Buy

4:15 it doesn't try to be "learn clojure in 24 hours", which is sort of how I felt while reading through pragprog's clojure book

4:16 chouser is undoubtedly the guy to be writing a book on clojure -- absolutely awesome job

4:16 esj: defn: agreed its a knockout

4:17 really helping me understand the Tao of Clojure

4:18 gko: Is Joy of Clojure for 1.0 or pre-1.1 ?

4:19 defn: not sure where it's at -- they have about 4 chapters done, and the first four chapters is better than anything ive read

4:20 100+ pages for 4 chapters, with a TOC that boasts 14 IIRC

4:20 it's going to be a monster reference

4:22 esj: what am I misunderstanding here:

4:22 ,((set '(1 2 3 4 5)) 3)

4:22 clojurebot: 3

4:22 esj: ,((sorted-set '(1 2 3 4 5)) 3)

4:22 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.lang.Number

4:22 esj: :(

4:23 why can a sorted-set not be used as a predicate for its members ?

4:32 dnolen: ,((sorted-set 1 2 3 4 5) 3)

4:32 clojurebot: 3

4:32 dnolen: esj: ^

4:32 esj: interesting ! thanks.

4:33 euwyn: defn: thanks for the heads up on the joy of closure. was just working through pragprog.

4:33 dnolen: ,((apply sorted-set '(1 2 3 4 5)) 3)

4:33 clojurebot: 3

4:44 esj: ,(class (sorted-set 5 1 4 2 3))

4:44 clojurebot: clojure.lang.PersistentTreeSet

4:44 esj: ,(class ( sorted-set [5 1 4 2 3]))

4:44 clojurebot: clojure.lang.PersistentTreeSet

4:45 esj: so this is a laziness effect in constructing the sorted-set, I guess.

4:54 maacl: Is there a swank-clojure command to execute tests? I am using swank-clojure-project

4:57 technomancy: maacl: sure, clojure-test-mode

4:57 it's another library to get from elpa

4:57 maacl: Ah - thanks

4:58 technomancy: you might run into a bug installing it; if so just rm -rf ~/.emacs.d/elpa/swank-clojure before installing clojure-test-mode and it will reinstall swank-clojure

4:58 I've fixed the package.el bug, but it hasn't made it out to the repos yet

4:59 maacl: technomancy: thanks - it will work from the actual code buffer - or do I have to switch to the buffer that contains the tests?

5:00 technomancy: it has to be from the test buffer

5:03 maacl: technomancy: would be hard to add the capability to swank-clojure-project to run tests in /tests - it think that would be very useful

5:03 technomancy: maybe also autorun tests if anything changes in the src tree

5:06 LauJensen: technomancy: Is there a swank-clojure-bleeding-edge which clones, builds and installs ?

5:07 technomancy: LauJensen: once you have a checkout, lein install should be enough for the java side

5:07 but coordinating the elisp side with the java side is really hard

5:07 *jvm side

5:07 LauJensen: oh really?

5:08 I thought all you had to do was issue a command and wait for a return code

5:34 derrida: is it just me or does maven seem ungodly slow a lot of the time? heh

5:35 http://dpaste.com/147356/

5:35 harblcat: this is an out-of-the-blue question, but would anyone know of any board-game engines in clojure?

5:40 or really, any sort of material at all on the subject? I've looked at something called "Zillions of Games", and the way to make a new game is to use something akin to lisp (specialized s-expressions), so it shouldn't be too hard to do the same in clojure.

5:41 LauJensen: harblcat: for all things related to gaming I recommend having a look at JMonkeyEngine

5:43 harblcat: LauJensen: it is a java library?

5:46 LauJensen: ~google jmonkeyengine

5:46 clojurebot: First, out of 6440 results is:

5:46 jMonkeyEngine.com

5:46 http://www.jmonkeyengine.com/

5:46 LauJensen: Yes sir - You need to make some kind of interface, I did one ages ago

5:47 ~sofiaba

5:47 clojurebot: sofiaba is http://wiki.github.com/Lau-of-DK/sofiaba

5:47 LauJensen: Its in a state of bitrot, but you'll see how easy it is to initialize a full 3d world with dynamic water, lighting etc

5:47 harblcat: LauJensen: thanks a lot!

5:48 LauJensen: ah I see the URL has changed http://github.com/LauJensen/sofiaba

5:49 Unfortunately I no longer had the screenshots - they were gorgeous

5:49 clojurebot: forget sofiaba

5:49 clojurebot: I forgot sofiaba

5:51 harblcat: woah, grappling hook was made in that engine. I didn't even know..

5:55 LauJensen: Somebody made a massive 12 (?) part tutorial, showing how to build a capture the flag race-game, a must-read

5:58 harblcat: I've got a lot of studying to do, I think :)

5:58 thanks again!

6:00 LauJensen: np

6:00 But just to be clear, if what you just need a simple board game ala checkers - Maybe rolling your own isn't a bad idea

6:00 (I'd hate to waste your time)

6:22 lypanov: hey rhickey

6:22 rhickey: lypanov: hi

6:25 angerman: is it a good idea to span hundrets of agents? or should I better keep an agent pool around the size (e.g. 4 times the system's cores)?

6:25 djpowell: agents aren't threads - the functions that you dispatch to them run on a thread-pool

6:26 rhickey: angerman: depends on what they are doing, if computation, not much reason to have more than ncores

6:26 but send takes care of that

6:27 angerman: rhickey: I'm pulling data from a database table, process it, and send it of to some writer-agents, that write the data to the according file

6:27 rhickey: send-off will create many, which makes sense if some are blocking, doing nothing

6:27 best idea if there is some I/O in the mix is to put a knob on it

6:53 angerman: Well I used to have a dispatch agent, that was set up as watcher over all the worker agents.

6:53 and when ever a workeragents state changed, it assigned a new task to the agent, until the task queue was empty

6:56 and I was just wondering if it was simpler to just create an agent for each task and wait till all are done

7:00 maybe futures are what I'm looking at?

7:01 LauJensen: agents carry state, futures launch seperate threads, conceptually they are different

7:02 angerman: If I send multiple tasks to an agent, the agents works them down one by one, right?

7:22 LauJensen: Yes

7:26 At least thats how I understand http://github.com/richhickey/clojure/blob/master/src/jvm/clojure/lang/Agent.java#L240

7:26 angerman: LauJensen: I ahve 1300 taks to be completed.

7:27 I guess a straight forward approach would be to partition them on size n

7:27 and have n agents work down those taks.

7:27 LauJensen: What are the tasks?

7:27 angerman: The issue I'm facing though is that the time for each task may vary. And thus in the end I have n-1 agents done and one agent still crunchin away for some time to be

7:28 LauJensen: read data from the database according to a query, process the data and send it off to be written out to a file

7:28 LauJensen: Are we talking 10ms tasks or 10min. tasks?

7:29 angerman: 5-10min

7:29 maybe some are 1 min.

7:31 LauJensen: rhickey: What did you mean when you advised him to put a knob on it ?

7:32 rhickey: LauJensen: make the number of agents used a variable/argument to the process

7:33 angerman: rhickey, LauJensen: ok, that makes sense so far.

7:33 rhickey: angerman: the true answer to irregular task processing times is something like fork/join

7:33 angerman: I'm still not so certain how to implement a mechanism to chew down a queue in parrallel.

7:33 I'm luck though that I don't need the returnvalue.

7:35 LauJensen: I'm wondering if rhickey approach won't just result in behavior very similar to (pmap #(process-task %) tasks)

7:35 angerman: LauJensen: I guess I'm looking for a pdoseq

7:36 LauJensen: angerman: (dorun (pmap)) should do fine then

7:36 I think if you let 500 agents loose they'll just crater your I/O performance

7:37 angerman: Hm. But pmap does have an synchronization overhead, right?

7:38 LauJensen: ~source pmap

7:39 rhickey: pmap's sliding window is pretty handy, you might need to partition first in order to create large enough work units

7:40 angerman: rhickey: so you basically mean glue 3-5 tasks together

7:41 rhickey: angerman: it depends on how much work is in one task, no need to do that unless pmap is slower than map

7:41 angerman: rhickey: each task takes between 1min and 10min

7:42 rhickey: but you still have issues with irregular task times, as pmap won't get far ahead of a slow task

7:42 angerman: oh, then pmap overhead is nothing relative to those times

7:42 angerman: Hm. I'll try pmap

7:42 rhickey: pmap overhead can be a problem when the job is: +

7:43 angerman: a problem with pmap for you might be that your jobs are I/O bound, not computation bound, is that correct?

7:43 angerman: well. the sql server runs locally. so it's mostly cpu bound

7:44 rhickey: well, if I/O bound you can actually benefit from having more threads than cores, to a point

7:44 subject to your I/O system

7:45 angerman: I'll try and see how the system-meter looks

7:45 LauJensen: rhickey: since pmap will wait for a lingering task, perhaps its best just to settle on 4, 8 or 16 threads and feed them tasks as they finish, that way pmap wont just wait

7:45 rhickey: where do the tasks come from?

7:46 LauJensen: 4/8/16 = knob

7:46 djpowell: (I have some slow IO from clojure being processed by some java, and dragging stuff through a LinkedBlockingQueue seems to work well for me)

7:47 LauJensen: angerman: How long do you expect the total processing time to be ?

7:47 rhickey: djpowell: yes, I was just about to recommend stuffing work in queue, then having a set of futures each of which loops taking one job from queue until done

7:48 as long as the jobs come from a known place in advance, vs being the results of other jobs

7:48 angerman: LauJensen: at least a night

7:49 rhickey: no. I know them in advance

7:49 LauJensen: angerman: If this is an ever growing dataset you're working on, maybe you should consider making it a map-reduce job and running it on Hadoop ? That'll clear any scheduling concerns you might have

7:49 angerman: LauJensen: It's for now a one-shot

7:50 LauJensen: Ah ok

7:50 angerman: working with MicroArray Data is just painful at best

7:51 LauJensen: This is where Rich jumps in saying "Pain, does not exist, in this Dojo! DOES IT?" :)

7:51 And Chouser goes "No sensei!" :)

7:52 angerman: Hm. It's not clojure specific.

7:52 rhickey: angerman: then you can have one future fill a LBQ http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/LinkedBlockingQueue.html with a fixed capacity, and N other futures looping pulling out a job and doing it

7:53 workflow => queue

7:53 djpowell: I guess you need to put N 'poison' objects into the queue after the data, so that the consumers can shut themselves down

7:53 rhickey: djpowell: no, they shutdown when no job to pull

7:53 angerman: If I know the size I need in advance, I can just create a queue of that size right?

7:54 rhickey: angerman: no, you probably don't want all jobs in memory at once, just use a capacity a bit larger than the number of workers

7:54 angerman: rhickey: I'm having the jobs in a list already. (?)

7:55 rhickey: lbq ctor takes a capacity, when the queue reaches that size the producer blocks

7:55 angerman: if it already fits i nmemrory, then stick into lbq with no bound, that's fine

7:55 djpowell: rhickey: how will the consumers no that there is no job to pull? won't they just block forever?

7:55 angerman: djpowell: using poll

7:56 djpowell: s/no/know

7:56 rhickey: poll, not take

7:57 djpowell: what if the producer is dead slow though? the consumer might take the last one before the producer has added the next

7:57 rhickey: djpowell: that's not angerman's situation

7:58 djpowell: ah ok - sry - wasn't really paying attention

7:58 angerman: djpowell: using a global flag to indicate the producers state?

7:58 rhickey: djpowell: in the general case, non-infinite queues need termination messages, yes

7:59 angerman: usually you'd try to put something in the queue

8:00 angerman: yes, that's probably a better idea ...

8:00 rhickey: then the protocol is: peek for termination, poll with timeout

8:01 don't remove termination, leave for others

8:02 angerman: hmm. how do I block for a seq of futures?

8:02 rhickey: angerman: to know when you are done?

8:02 use a countdown latch

8:02 http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html

8:03 have launcher set it up with n set to number of workers, each worker counts down when done, launcher blocks on await

8:04 angerman: thanks

8:04 rhickey: java.util.concurrent's workflow stuff is very good, and works well with Clojure. I didn't wrap it, but should, since few people know about it

8:06 djpowell: angerman: 'Java Concurrency In Practice' is a good book if you want to learn about it.

8:07 it is a bit overwhelming otherwise, knowing what to use when

8:07 angerman: djpowell: thanks. I've had abandoned java for years.

8:07 Sometimes just using it under the hood in Matlab, to plug holes

8:15 LauJensen: rhickey: I was thinking of wrapping u.concurrent as well, but where in the eco-system does this fit compared to the fork/join stuff from par ?

8:17 rhickey: LauJensen: j.u.c is workflow (queues/latches), cache-like collections, and exectutors. Only the latter overlaps with fork/join

8:17 LauJensen: Ok, thanks

8:17 rhickey: the big utility of j.u.c. for Clojure users is in the workflow

8:18 fork/join will be preferable to executors

8:19 defn: chouser: Your book is fantastic.

8:20 LauJensen: rhickey: I haven't digged into fork/join yet, but can their executors be combined with the workflow from util.concurrent ?

8:21 rhickey: LauJensen: they can, it's all just threads under the hood. But like any thread pool, you have to be concerned about blocking starving the pool

8:21 angerman: hm. Did the agent logic change in 1.1?

8:24 I htink this http://pastie.org/784694 did work previously

8:25 LauJensen: (send printe....) typo ?

8:26 angerman: no, those came from typing of from head

8:26 LauJensen: ah, the reader macro ^ is deprecated

8:27 angerman: but depricated doesn't mean dead. right?

8:31 _fogus: defn: On behalf of chouser, Thanks! :-)

8:55 angerman: Today is a bad day :(

8:57 AWizzArd: uh oh..

8:57 angerman: things just don't work out today for me.

8:58 AWizzArd: Are those things you have control over? Such as computer programs? ;-)

8:58 angerman: right now it's mostly clojure errors I'm having serious trouble to understand

8:59 Don't know how to create ISeq from: clojure.lang.Keyword in the (ns ... block)

9:00 AWizzArd: You could delete everything from the file with the exception of the (ns ...) which is in the beginning. Then compile and see if it works.

9:00 If it does work then paste some parts of the other code back, and try again. And that way put more and more code back into the file.

9:01 angerman: http://pastie.org/784744

9:01 AWizzArd: If it does not work then you have indeed an error in the (ns ...) form.

9:01 Why so many uses of :use?

9:01 I suggest to have exactly one :use in the ns form

9:04 dnolen: angerman: that's probably an error in your own library your trying to include right? I removed those use exprs and it worked fine for me.

9:05 angerman: hm. I'll try to dig some deeper.

9:05 AWizzArd: you can comment out all lines and bring them in one by one, seeing at what point the error pops up

9:06 angerman: AWizzArd: will do the bisection method :D

9:06 naj. paredit doesn't want me to comment-out

9:07 chouser: #_

9:07 put that before an expression to make it "disappear"

9:08 dnolen: angerman: that should only happen on the last expr because of trailing parens, you just need to move those extra parens down

9:10 jcromartie: #_ is just weird

9:10 angerman: Thanks for all the help, there seems to be some serious issue on my side. I can (use '...) all of the libs with no problem. I'll better restart the repl

9:18 Sorry. I was editing the wrong file and thus never got any sensible difference

9:19 LauJensen: Does anybody know where _ato Alex Osbourne is camping these days?

9:33 defn: is there anything like nokogiri for clojure?

9:37 chouser: i've been using #_ after reading your first few chapters

9:38 chouser: great job on the book again -- it's exactly what I've been looking for

9:41 chouser: defn: we mentioned #_ in the first we chapters?

9:41 Maybe I should read that book.

9:42 esj: chouser: yeah, I learnt about #_ from your book

9:43 chouser: Anyway, glad you're enjoying it. If you ever get a chance to work on a project with _fogus, I'd highly recommend you do. :-)

9:43 _fogus: chouser: It's in the Style section ;-)

9:43 * _fogus blushes

9:45 * LauJensen pats fogus on the back!

9:46 esj: a pat and run ?

9:46 chouser: drive-by back-pat

9:47 angerman: do i need any special plumbing to use future?

9:48 chouser: ,(let [x (future 5)] @x)

9:48 clojurebot: 5

9:48 cgrand: I've been mulling over the idea of using #_(namespaced/symbol yadi yada) as a way for tools (mainly IDEs) to add structured comments and markers. eg #_(tools.annotations/review "this is displayed as a post-it" :author "someone")

9:49 chouser: cgrand: huh!

9:49 I have a couple snippets of code with #_"comments like this"

9:49 defn: #_TODO

9:50 angerman: ,(let [t (for [n (range 5)] (future n))] t)

9:50 clojurebot: (#<Object$IDeref$Future$2b9be1f9@13b2b95: 0> #<Object$IDeref$Future$2b9be1f9@1aa7618: 1> #<Object$IDeref$Future$2b9be1f9@2f4356: 2> #<Object$IDeref$Future$2b9be1f9@edd295: :pending> #<Object$IDeref$Future$2b9be1f9@19c4d4b: :pending>)

9:50 _fogus: I love using #_ in these ways which is why I added it to the comments section... but I think I should add a few extra words regarding using it alongs these lines.

9:51 defn: ,(#_let #_[t (for [n (range 5)] (future n))] #_t)

9:51 clojurebot: ()

9:51 defn: #_ is like a fork lift coming to take away your form

9:52 maybe a snow plow

9:52 chouser: heh. nice. I like fork lift

9:52 qbg: It is a bottomless hole with a sign warning about it from the wrong side

9:52 _fogus: ,(let [x (future (do (Thread/sleep 5000) (+ 41 1)))] @x) ; ... 5 seconds later

9:52 clojurebot: 42

9:53 angerman: I must not mix future and loop?

9:53 defn: hi _fogus -- nice book

9:54 chouser: there's nothing wrong with that.

9:54 _fogus: defn: Thanks!

9:57 stuarthalloway: irc4019

10:01 anybody have a function that takes a lazy seq of input-streamable things and exposes it as a single inputstream?

10:02 * chouser panics

10:02 * lypanov reboots chouser

10:02 chouser: how would you close such things?

10:03 stuarthalloway: each one closes as it is consumed

10:04 like contrib read-lines does

10:06 stop me now if I am crazy...

10:07 cgrand: something built on java.io.SequenceInputStream?

10:07 chouser: the way read-lines closes things makes me nervous

10:07 stuarthalloway: that's where I am headed

10:07 and it has the close semantics I am describing

10:08 for my use case I think SequenceInputStream will be find

10:08 the number of seqs to push together is small, but the individual seqs are larg

10:09 defn: clojurebot: skynet?

10:09 clojurebot: I will become skynet. Mark my words.

10:10 jkdufair: suggestions on why println on other threads does not print on stdout in clojure box on windows?

10:11 chouser: jkdufair: did you check your inferior-lisp buffer?

10:11 defn: *print-readably* can technically change between threads right?

10:12 oops nevermind

10:13 chouser: what's a better name for a clojure-lint tool?

10:14 defn: hm

10:14 flint

10:14 it's functional

10:14 functional lint

10:14 chouser: :-)

10:14 jkdufair: chouser: thank you!

10:14 chouser: not bad

10:15 angerman: Ok, now I'm getting a Rejected Execution Exception

10:15 defn: did you have a name in mind?

10:15 chouser: nope

10:15 ohpauleez: chouser: are you making a clojure lint?

10:15 chouser: ohpauleez: mulling it

10:15 angerman: ,(def printer (agent nil :meta {:out *out*}))

10:15 clojurebot: DENIED

10:16 angerman: :D

10:16 ohpauleez: I've wanted one for awhile

10:16 datka: A clojure lint would be a great tool

10:16 chouser: ran into a bug in my code yesterday that took way to long to track down.

10:16 defn: chouser: glint would also be acceptable I think -- fewer google results to compete with also

10:16 give out or reflect small flashes of light : her glasses were glinting in the firelight.

10:16 chouser: I'm not sure, but I think a lint-like tool would have helped (if I had thought to run it. :-/ )

10:17 datka: Clijnt

10:17 esj: ljnt

10:18 ohpauleez: CKB - Chouser|Clojure Killin' Bugs

10:18 defn: Tijnt

10:18 somnium: Eastwood (clojure -> lint -> clint)

10:19 ohpauleez: this is looking like a Notorious BIG song, and less like tizzool :)

10:19 angerman: clojure 1.1.0 is stable right?

10:19 defn: aye

10:20 chouser: somnium: oh, nice.

10:20 angerman: what's the appropriate line for the project.clj?

10:20 somnium: chouser: in the spirit of Leiningen :) (kind of)

10:20 defn: angerman: [org.clojure/clojure "1.1.0-master-SNAPSHOT"]

10:21 angerman: defn: hmm. I'm using that.

10:21 stuartsierra: 1.1.0 is in maven central now

10:21 angerman: *clojure-version* -> {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"}

10:21 does that match?

10:21 Raynes: (defmacro with-thread [& forms] `(.start (Thread. ~@forms))) Weeee, mah first macro.

10:22 stuartsierra: Raynes: that won't actually work

10:22 defn: angerman: try "1.1.0"

10:22 bedtime

10:22 night all

10:22 ohpauleez: night

10:22 angerman: defn: contrib as well?

10:22 stuartsierra: angerman: I'm working on numbered contrib releases, stay tuned

10:23 angerman: stuartsierra: thanks.

10:24 what's the supposed *clojure-version* string for 1.1.0?

10:25 * triddell just purchased the MEAP book and can't wait to check out the new chapters

10:26 Raynes: stuartsierra: That isn't surprising.

10:26 dnolen: how does one type hint types created by deftype ?

10:27 angerman: http://pastie.org/784871

10:27 hm

10:27 I dont' get why

10:27 Raynes: dnolen: #^Nameoftype seems to work.

10:31 spariev_: angerman: do you use emacs+slime ? if so, check the version of lein-swank, should be 1.1.0

10:31 * hyp3rvigi1ant1 also just purchased the MEAP book

10:32 angerman: spariev_: I found lein to load the old clojure. So I fixed that

10:32 Still I cannot use my printer agent

10:32 I'm sure it used to work

10:33 or is there an issue with my code? (http://pastie.org/784871)

10:35 I can't even execute "(pmap #(* % %) (range 0 10))"

10:36 spariev_: angerman: I was just about to suggest checking that )

10:36 I had the similar exception trying to use pmap in slime, upgrading lein-swank in project.clj fixed my problem

10:37 like, :dev-dependencies [[leiningen/lein-swank "1.1.0"]]

10:37 angerman: yep, that's exactly how I have it

10:38 chouser: angerman: looks like you may have already shut down your agent pool?

10:43 rhickey: aargh, this fn metadata ended up being a huge deal - now I've got to optimize compiled metadata storage, complete sidetrack

10:46 jcromartie: hmm, is (decorate ...) broken right now in compojure?

10:46 java.lang.IllegalArgumentException: No method in multimethod 'update-response' for dispatch value: class clojure.lang.Var

10:47 http://gist.github.com/281015

10:48 stuartsierra: Who runs the build server at tapestry.formos.com?

10:48 jcromartie: hitting any of my routes results in an the exception posted above

10:49 ah wait I think I get it

10:49 (decorate) is not meant to be used inline like that, right?

10:52 stuartsierra: ~seen dysinger

10:52 clojurebot: dysinger was last seen quiting IRC, 242 minutes ago

10:53 rhickey: ~seen devlinsf

10:53 clojurebot: no, I have not seen devlinsf

10:53 triddell: stuartsierra: probably Howard Lewis Ship, or hlship in irc I believe

10:53 stuartsierra: creator of tapestry and clojure fan

10:53 stuartsierra: ~seen hlship

10:53 clojurebot: no, I have not seen hlship

10:54 angerman: hmm. seems like leiningen was interfering with the libs form the leiningen checkout

10:54 stuartsierra: triddell: thx

10:55 rhickey: sean's latest video, Abstraction Grafting, left me puzzled. All of the multimethods were variadic, but clearly only took one arg

11:08 stuartsierra: rhickey: just looking at the code, maybe he wants to allow variadic forms like (date 2010 1 19)

11:10 rhickey: stuartsierra: I don't understand

11:10 won't that just convert 2010 into a time?

11:11 stuartsierra: as it's written now, yes

11:11 I don't really understand either

11:13 AWizzArd: Why does Clojure not use githubs issue system? I am just curious, no criticism or suggestion to use it.

11:14 stuartsierra: AWizzArd: rhickey liked Assembla, that's all

11:15 AWizzArd: So, github is just the store for the central repositories, while assembla is for the project management, issue tracking and so on, while the official homepage is for documentation and collecting all basic information.

11:16 stuartsierra: pretty much

11:17 AWizzArd: ok

11:18 lypanov: hey headius

11:19 headius: lypanov: hello there

11:19 * lypanov has found a new home

11:22 headius: lypanov: oh yeah? likin you some lisp?

11:24 lypanov: headius: it was either scala or clojure and rich did a neat devoxx talk, so clojure it is.

11:24 :P

11:25 headius: well, there's certainly less syntax to learn

11:29 the-kenny: Anyone who can tell me the type of Urlencode which translates + to %252B ? (I think it's a java-thing)

11:31 _fogus: ,(java.net.URLEncoder/encode "+")

11:31 clojurebot: "%2B"

11:31 the-kenny: Tried that, with every encoding mentioned in the doc

11:32 _fogus: ,(java.net.URLEncoder/encode (java.net.URLEncoder/encode "+"))

11:33 clojurebot: "%252B"

11:33 the-kenny: Wow

11:33 chouser: oh dear

11:33 the-kenny: Looks like Google Wave is recursive

11:33 :D

11:33 _fogus: double secret encoding. ;)

11:34 lypanov: more security! we use ssl twice!

11:35 chouser: ,(take 5 (iterate #(java.net.URLEncoder/encode %) "+"))

11:35 clojurebot: ("+" "%2B" "%252B" "%25252B" "%2525252B")

11:35 chouser: infinite security

11:36 _fogus: Looks more like lazy security to me :p

11:36 the-kenny: lol

11:38 jcromartie: that's hilarious

11:38 p.s. you can include wacky things in a compojure route-param if you URL-encode it

11:38 like an email address

11:38 it's ugly as sin but it works

11:49 krumholt__: hi. how would i define a lazy-seq of all natural numbers with lazy-seq?

11:50 chouser: (defn incs [i] (lazy-seq (cons i (nums (inc i)))))

11:50 (incs 1)

11:51 Raynes: ,(take 5 (lazy-seq (iterate inc 1)))

11:51 clojurebot: (1 2 3 4 5)

11:51 Raynes: Was what I came up with.

11:51 chouser: Raynes: lazy-seq is doing nothing useful there.

11:51 Raynes: I just noticed that.

11:51 chouser: But of course it's better to use iterate than what I did

11:51 Raynes: ,(take 5 (iterate inc 1))

11:51 clojurebot: (1 2 3 4 5)

11:52 krumholt__: ok thanks

11:52 Raynes: That's what happens when you fail to read the doc string. :>

11:52 (defn incs [i] (iterate inc i)) ; Anyways.

11:53 chouser: Raynes: right, that's much better.

11:53 * Raynes did something right. :D

12:00 lpetit: ,(take 5 (fn incs [i] (lazy-seq (cons i (incs (inc i)))))

12:00 clojurebot: EOF while reading

12:02 lpetit: grr

12:02 ,(take 5 ((fn incs [i] (lazy-seq (cons i (incs (inc i))))) 1))

12:02 clojurebot: (1 2 3 4 5)

12:03 lpetit: or as devlinfs would say : (defn incs (partial iterate inc) :-)

12:03 argh, must really go to sleep early today

12:04 (def incs (partial iterate inc))

12:04 go to bed

12:24 lypanov: LauJensen: man i've lost days on this arch thing :P

12:24 * lypanov had forgotton how much time choice takes away

12:25 LauJensen: Its good that you get some practice :)

13:02 konr: Is there a way to use a regexp to match but then return just part of it? something like (function #"value=\([0-9]*\)" "\1" "<tag value=30>") => 30 ?

13:02 stuartsierra: konr: re-groups

13:08 the-kenny: If you're parsing xml, I would recommend using a xml-parser :)

13:09 alexyk: I've tried upgrading clojure, contrib and congomongo, and leiningen, and got a mess. E.g., this: java.lang.NoSuchMethodError: clojure.lang.RestFn: method <init>()V not found (coerce.clj:1)

13:09 Raynes: I thought that said circumcision.

13:10 I parsed XML for the first time yesterday! :D

13:10 alexyk: upon trying to (ns mongol (:use somnium.congomongo))

13:10 the-kenny: clojurebot: clojure.lang.RestFn

13:10 clojurebot: ant clean and rebuild contrib

13:10 alexyk: what's that error? trying 1.1.0 for clojure and 1.1.0-master-SNAPSHOT for c.c.

13:11 Raynes: alexyk: Last time I got that, it was because my contrib wasn't built against my clojure.

13:11 alexyk: okok

13:11 the-kenny: alexyk: Are you building clojure and contrib from source?

13:11 alexyk: the-kenny: used to, but now want leiningen to get the right ones. Which c.c. does go along with clojure 1.1.0?

13:12 the-kenny: alexyk: Sorry, no idea. But if you're building contrib from source, try "ant clean" before this..

13:12 Wait, I can tell you the lein-entries for one of my projects

13:12 alexyk: ok

13:12 the-kenny: [[org.clojure/clojure "1.1.0-alpha-SNAPSHOT"]

13:12 [org.clojure/clojure-contrib "1.0-SNAPSHOT"]]

13:13 sorry for bad line-breaks

13:13 alexyk: the-kenny: I used to use alpha, now it's 1.1.0

13:13 the-kenny: oh wait, let me try it

13:13 alexyk: there was a message about versioning of c.c. today on build.clojure.org, but I guess lein looks at clojars

13:15 Chousuke: hmm

13:16 is there any quick way to use leiningen to run examples for a project? :/

13:16 the-kenny: clojure 1.1.0 (without snapshot) and c.c "1.0-SNAPSHOT" works for me (at least I can start a repl within emacs)

13:16 Chousuke: Write a plugin!

13:16 Would be useful

13:17 noidi: how can I set the value of a field of a java object?

13:18 (.field object) works for reading, but the obvious attempt at writing -- (.field object new-value) didn't seem to work :)

13:19 Chousuke: (set! (.f o) someval) I think

13:20 noidi: Unable to resolve symbol: set! in this context

13:20 Chousuke: what.

13:20 (doc set!)

13:20 clojurebot: excusez-moi

13:21 Chousuke: hm

13:21 noidi: ah, I just checked if the function exists by typing "set!" in the repl :)

13:21 Chousuke: right

13:21 noidi: should've known it's a special form

13:21 Chousuke: it's a special form

13:22 noidi: thanks, that works

13:22 Chousuke: the syntax is pretty common lispy (in a good way)

13:23 noidi: if the (.f o someval) syntax worked, one could initialize objects with doto

13:23 Chousuke: though Clojure has little need for generic-whatever-they-call-them because of the empasis on not mutating things. :)

13:23 emphasis*

13:23 noidi: yup, this is for Java interop

13:24 hyp3rvigi1ant1: is there a lein plugin for searching clojars and/or mvnrepository?

13:28 alexyk: after upgrading, I can't load congomongo anymore in lein repl, getting: java.io.FileNotFoundException: Could not locate somnium/congomongo__init.class or somnium/congomongo.clj on classpath: (NO_SOURCE_FILE:1). Yet It's a dependency in project.clj. What can be the issue?

13:29 the jar has the structure src/clj/somnium/congomongo.clj

13:29 how does clojure know to read that out of it?

13:29 hiredman: yeah, that doesn't look right

13:29 alexyk: it also has that very project.clj in the jar

13:30 hiredman: sounds like someone jar'ed up the source tree

13:30 instead of running lein jar

13:31 alexyk: I get this after lein install or lein jar

13:31 why would lein be screwed up here?

13:31 hiredman: so you are generating the har?

13:31 jar

13:32 alexyk: I was just doing lein install

13:32 and that produced the crooked jar

13:32 lein jar does the same src/clj

13:32 hiredman: the jar should not have the project.clj in it

13:34 the-kenny: I thin lein jar does include the project.clj too

13:34 I've seen some jars with it

13:37 alexyk: ah what a mess. lein repl cannot launch a specified clojure version, jars are effed, pre-cooked one has a different version and exhibits RestFn. I'm itching for a Makefile.

13:37 and this is only because I've upgraded lein.

13:38 how can you launch a swank server with lein on a non-standard port?

13:38 the-kenny: alexyk:hm.. I don't think so

13:38 But it should be easy

13:39 File a feature request for it :)

13:39 alexyk: my filing technique is shouting "technomancyyyyy!" :)

13:40 the-kenny: heh

13:40 hiredman: always makes me think of chrestomanci

13:50 hyp3rvigi1ant1: alexyk: try: $ lein swank <port>

13:50 alexyk: ok

13:51 yeah

13:52 can I also specify host? It should bind to the externally visible IP

13:53 hyp3rvigi1ant: doesn't look like you can specify the host

13:54 here's the entire lein-swank plugin source code (one function): http://github.com/technomancy/leiningen/blob/master/lein-swank/src/leiningen/swank.clj

13:55 alexyk: wow

13:59 the-kenny: ahhh lein swank has the port argument already?

13:59 didn't know that

14:02 hyp3rvigi1ant: i didn't either, until i just now looked at the source, and then tried it, lol

14:09 stuartsierra: ~url

14:09 clojurebot: something

14:09 stuartsierra: ~paste url

14:11 lisppaste8: stuartsierra pasted "N-element tuples with deftype" at http://paste.lisp.org/display/93626

14:13 cemerick: stuartsierra: sweet. Should go show that to the #scala people. http://scala-tools.org/scaladocs/scala-library/2.7.1/Tuple9.scala.html#Some%2819%29

14:16 stuartsierra: Don't know much Scala, but that looks weird all right.

14:17 alexyk: cemerick: what did I miss which is better in clojure? :)

14:17 stuartsierra: I thought about allowing type hints too.

14:17 Maybe another day.

14:17 alexyk: "N-element tuples with deftype" at http://paste.lisp.org/display/93626

14:18 alexyk: nice

14:19 cemerick: referring to 2.7.1 dates you :)

14:20 and scala people have real types, for the record :)

14:22 cemerick: alexyk: the point is, there's one file/implementation for each tuple arity in scala

14:22 the types have nothing to do with it

14:23 chouser: stuartsierra: excellent. now add primitive support

14:23 alexyk: cemerick: I think the static-ness of tuples makes it necessary, same in haskell and ocaml; you can't convert to lists either.

14:23 cemerick: alexyk: see, now you're making my argument for me ;-)

14:24 chouser: I think you could do something this in template-haskell

14:24 alexyk: I remember a horrible protracted sesion on #ocaml where I'd ask how to convert a tuple to a list, and an FP dogmatic would say, "you shouldn't do that" like 20 times.

14:24 cemerick: actually, wouldn't template haskell make that possible?

14:24 chouser: damn! ;-)

14:25 alexyk: cemerick: my haskell is very rudimentary. But this is the dynamism vs static-ness.

14:25 cemerick: stuartsierra: interesting that you capitalized the key bindings.

14:25 Chousuke: hmm, I wonder if the template macro would look any better if done using clojure.template

14:25 chouser: alexyk: no this is macros vs. not.

14:25 cemerick: alexyk: ah, I don't think so. Some better metaprogramming facilities in the scala compiler would make this possible.

14:26 alexyk: the same dogmatic, #ocaml is generally very friendly and a magic way was provided using some special magic.

14:26 * cemerick thinks chouser is monitoring my brainwaves :-P

14:26 Chousuke: it doesn't look like it has much actual programmatic construction of code.

14:27 stuartsierra: No, there's not much code-construction.

14:27 Most of the code is the same for tuples of any size.

14:28 The annoying part was ~'quoting all the method names and arguments.

14:28 rhickey: stuartsierra: awesome!

14:28 stuartsierra: rhickey: thanks!

14:29 Chousuke: hm. I think the generated case impl prevents from using template

14:30 stuartsierra: So if I add type declarations, should it be per-element or one type for the whole tuple?

14:30 cemerick: per-element, I'd think

14:30 chouser: stuartsierra: I have the same construction, and for similar reasons, here: http://tinyurl.com/yb8bggv/finger_tree.clj#LID39

14:30 stuartsierra: cemerick: That was my first thought, but at that point you're basically writing deftype again.

14:31 chouser: a macro for making types, calls to make the types, and then a multi-body fn to construct the right kind.

14:31 if I add primitive support to the finger-tree digit types, all fields would have the same type.

14:32 my digits are rather less featureful than your tuples

14:33 stuartsierra: chouser: You aren't trying to support all the Vector interfaces.

14:33 rhickey: stuartsierra: for Clojure, tuples are just specific small vectors. Vectors have uniform element type (only Object right now, but another interesting case of data-structures-as macros is vectors of longs and doubles)

14:33 chouser: right, just Indexed. ISeq for destructuring.

14:34 rhickey: should use nth, not get for tuples/vectors

14:34 chouser: plus my tree-specific stuff: DoubleSeq, Measure, Splittable

14:34 stuartsierra: rhickey: it supports both nth and get, like vectors

14:35 But the examples should probably use nth.

14:35 rhickey: right, but I hate to see example code with get

14:35 heh

14:35 get on vectors only when supporting associative things more generally

14:36 I'd like to get rid of the need for those ~'s

14:37 stuartsierra: rhickey: Some of them are not necessary, but it was easier to leave them all in than figure out which ones.

14:37 rhickey: hrm

14:37 stuartsierra: I can't use auto-gensyms in some cases because I have nested backquote-unquotes

14:38 chouser: I didn't need ~' for any of the method names

14:38 rhickey: so, metadata on fns is ready for public consumption. One issue right now is macro arglist metadata includes the implicit &form and &env args

14:39 clojure.core/for

14:39 ([&form &env seq-exprs body-expr])

14:39 * stuartsierra will be back in a few

14:39 rhickey: I need to strip them at some point in the chain

14:39 chouser: is the fn metadata copied to the var, or... ?

14:40 rhickey: chouser: right now var to fn

14:40 big pain having it both places, but breaking change to take off var

14:40 chouser: yeah

14:40 rhickey: with-meta works on fns

14:42 chouser: oooh

14:43 cemerick: that's pretty exciting

14:43 * rhickey anticipates much awful runtime nonsense

14:44 cemerick: this includes arities? That's probably the #1 requirement out there.

14:44 rhickey: what are people doing with runtime arity?

14:46 in any case, it's just the arglists metadata

14:47 * rhickey waits for good answer before pushing :)

14:47 chouser: for what people are doing with runtime arity?

14:47 rhickey: yes

14:48 or runtime fn metadata in general

14:48 cemerick: I'm trying to remember what my use case was... :-/

14:48 chouser: one example someone descibed was a fn that wanted to except either a one- or two-arg predicate.

14:48 so var metadata was useless

14:49 rhickey: chouser: what's a one or two arg predicate?

14:49 i.e. what do you pass?

14:49 cemerick: oh, right, I wanted to be able to decorate fns with arities and acceptable type tags so that candidate fns could be selected from a library/population given a set of args

14:49 chouser: He wanted both (foo (fn [a] ...)) and (foo (fn [a b] ...)) to work

14:50 cemerick: I ended up passing around [fn-info-map fn] vectors.

14:50 rhickey: chouser: I'd have to know the specifics to understand that - if you take one arg you get passed foo and if 2 foo and bar?

14:51 cemerick: so full runtime dispatch

14:52 cemerick: rhickey: with lots of layers of indirection, backtracking as necessary, etc. But being able to describe the 'surface' of each fn was critical.

14:52 rhickey: hmm

14:53 cemerick: "signature" is too weak of a term for what we were doing, so we came to call the characterization of each function (a 'feature' in bayesian terms) its surface

14:54 rhickey: cemerick: but you didn't want to package the fn in a descriptive map?

14:54 chouser: rhickey: I think so, like (fn [a _] ...) would have worked, but is uglier.

14:55 cemerick: rhickey: that's roughly what we ended up doing, although we kept the description separate.

14:55 rhickey: chouser: I'm still unclear (and I know its not your thing you're describing) what one or two things would get passed

14:56 cemerick: rhickey: to be clear, the difference between what your doing and what you *could* do is very small.

14:57 as long as we can decorate fns with metadata, I'm super-happy :-)

14:57 rhickey: note that fn equality is still identity based

14:58 cemerick: we put all sorts of stuff in our surface descriptions anyway, so leaving the :arities [1, 2, 5, [6 '&]] pair in there is fine for me.

14:58 rhickey: is anything else really possible/

14:58 ?

14:59 * cemerick imagines hashes based on original source? *ugh*

14:59 rhickey: cemerick: well, it can't be behavior based, but could (but isn't) be based around same type plus equal closed-overs

14:59 cemerick: rhickey: sounds like a difficult path with little to gain from it

15:00 rhickey: two such fns would give same results given same args, and would isolate metadata

15:00 cemerick: we'll see if people get breakage from fn != same fn + meta

15:01 cemerick: IMO, if you're comparing fn equality, you're already in rough shape

15:01 rhickey: there was never a reason to create another version of the same fn before

15:02 meh, fns are values, can be map keys etc

15:03 cemerick: I've always thought about fns as being black boxes, quite unlike other values -- can't be serialized, can't be compared, no notion of equality, etc.

15:08 Chousuke: equality for functions is defined at least in a theoretical sense. Hmm

15:08 cemerick: Sure, in the f(x) -> y sense, but a real implementation of that is probably intractable.

15:10 hiredman: it's the halting problem

15:10 isn't it?

15:10 cemerick: to brute-force it, yeah

15:11 rhickey: cemerick: I agree, in general, but a particular fn is = to itself in any system, yes?

15:11 cemerick: if you were to do something like aggressively normalize the source of two equivalent fns, you might get them to hash out equally, but I wouldn't bother :-)

15:11 rhickey: so, that fn with-meta should still be =, given what with-meta is supposed to do and metadata's relationship to equality

15:12 at least one could argue that, and I expect someone will

15:12 cemerick: rhickey: Yeah, it probably should be, but *meh*

15:13 arohner: rhickey: one use of fn arity metadata is macros / fns that wrap it

15:13 at one point, I wanted to make a function that took another function, wrapped it, and def'd a new function with the same arity

15:14 and I wanted the old arity to stick it in the doc string of the new fn

15:14 cemerick: Hell, if I didn't know how fns were implemented under the covers, I might expect a meta-altered fn to drift in equality from the original fn anyway due to JIT recompilation.

15:15 rhickey: cemerick: really?

15:15 cemerick: rhickey: *if* I didn't know how fns were implemented, etc., but did know that code was being regenerated and replaced all the time.

15:17 rhickey: if you're really worried about it, you could add an :original-fn slot to new meta on fns. :-P

15:17 alexyk: did str-utils2 remain in c.c. 1.1.0-master-SNAPSHOT?

15:17 * cemerick : adding warts, one day at a time

15:17 ambient: btw, anyone else done any musical audio synthesis with clojure? or written a clojure-lib for realtime audio?

15:19 alexyk: I do (:require [clojure.contrib.str-utils2 :as s2]) and it gives me a class not found. Why suddenly?

15:20 hiredman: str-utils2 may have been renamed to str-utils, I forget

15:21 the-kenny: ohh and str-utils is dropped?

15:21 hiredman: possibly

15:22 I saw some discussion of it, dunno if it actually happened

15:22 alexyk: darn, I can't find str-utils2/replace

15:23 what can I replace replace with?!

15:23 (replace string from to)

15:23 the-kenny: ,(doc replace)

15:23 clojurebot: "([smap coll]); Given a map of replacement pairs and a vector/collection, returns a vector/seq with any elements = a key in smap replaced with the corresponding val in smap"

15:23 hiredman: ,(.replace "foo" "foo" "bar")

15:23 clojurebot: "bar"

15:23 alexyk: in a string!

15:23 the-kenny: alexyk: you have to say .replace, not replace :)

15:23 There's a difference

15:23 hiredman: ,(.replace "foo" "foo" "bar")

15:23 clojurebot: "bar"

15:24 alexyk: I used to use str-utils2 tp get rid of the . apparently... hmm

15:24 the-kenny: oh sorry, I didn't see one of your comments

15:24 chouser: str-utils2 replace is a multimethod

15:24 stuartsierra: as far as I know str-utils2 has NOT replaced str-utils

15:24 alexyk: chouser: which is what ?

15:25 all I know that require c.c.str-utils2 used to work and now doesn't

15:25 but, here Javaism will save the day

15:26 hiredman: ok

15:26 then the problem is something else

15:26 alexyk: I've just spent inordinate amount of time to: upgrade leiningen and clojure; determine lein repl won't respect clojure versions; try swank and eff with firewalls, ports, and tunneling; replace lein repl with zsh: var=( lib/**/*.jar ); print ${(j.:.)var}

15:27 stuartsierra: alexyk: what versions of Clojure/contrib are you using?

15:27 alexyk: stuartsierra: 1.1.0-master-SNAPSHOT on both

15:27 as delivered by lein

15:27 lein deps

15:27 stuartsierra: Oh, can't help with lein, but I expect that's the problem.

15:28 They're pulling a bad build or something.

15:28 alexyk: stuartsierra: what's the latest correct coupling?

15:28 stuartsierra: I don't know, I don't use lein.

15:28 alexyk: and is it gettable via build.clojure.org maven repo? I'll use raw maven, forget lein

15:29 stuartsierra: yes, there are contrib release candidates on build.clojure.org now

15:29 see my announcement on the clojure-dev list

15:29 alexyk: right, from the email this morning, correct? which clojure do they work with?

15:29 stuartsierra: alexyk: version numbers match; contrib 1.1 => clojure 1.1

15:30 rhickey: I'm not sure metadata is the right way to get arity from a fn. Arity is a property of the fn. Arglists meta is for humans

15:30 alexyk: is c.c. supposed to work with variations, e.g. both 1.1.0 and 1.1.0-master-SNAPSHOT?

15:30 Raynes: contrib 1.1 new snapshot seems to run with clojure 1.2 master snapshot.

15:30 So, that's what I've been pulling down fro my stuff.

15:31 stuartsierra: If you're using snapshots, use matching branches. If you're using releases, use matching release numbers.

15:32 lisppaste8: stuartsierra annotated #93626 "N-element tuples with type declarations" at http://paste.lisp.org/display/93626#1

15:33 alexyk: so is multimethod is a function with variants by arity?

15:34 hiredman: nope

15:34 http://clojure.org/multimethods

15:34 rhickey: ok, fn metadata is up

15:35 stuartsierra: cemerick: tuples with primitives!

15:36 chouser: stuartsierra: beautiful

15:36 cemerick: nice

15:36 stuartsierra: thx

15:36 rhickey: stuartsierra: neato - now onto vectors of primitives? :)

15:36 cemerick: stuartsierra: you should add comparisons to arrays

15:37 rhickey: cemerick: that would be wrong

15:37 mutable things should have identity-based equality

15:38 cemerick: rhickey: I'm just curious about the relative perf

15:38 rhickey: oh, make a comparison

15:38 Raynes: for* (late correction)

15:38 cemerick: right

15:38 Raynes: rhickey: Hah! We used words of the same length to end our sentences!

15:38 You owe me a coke.

15:38 alexyk: hiredman: thanks, dreaded OO stuff.

15:39 BenUncle uncleBen = new UncleBenUncle("Ben")

15:39 hiredman: it's polymorphism

15:39 rhickey: stuartsierra: should switch get to nth

15:39 hiredman: not OO

15:39 stuartsierra: rhickey I thought I did

15:40 oh, only in the tests

15:40 alexyk: right, just mention of OO was a flashback. I read through CL CLOS once and forgot it, will see about defmulti

15:42 my repl is finally back, lesson: don't entrust your repl to tools

15:42 hand-made vintage repl is in your full control

15:44 lisppaste8: stuartsierra annotated #93626 "typed tuple comparison with arrays" at http://paste.lisp.org/display/93626#2

15:44 stuartsierra: tuple performance does not quite match arrays, but gets very close

15:44 cemerick: that's pretty remarkable

15:45 If the same margin applies between aset and (assoc tuple n blah), then *whoa*

15:45 rhickey: stuartsierra: you've got to tweak valAt

15:46 stuartsierra: rhickey: how so?

15:46 rhickey: calling interleave?

15:46 chouser: that's at compile time

15:46 rhickey: ah

15:47 stuartsierra: It generates a case expression like (case n 0 e0, 1 e1, 2 e2, ...)

15:47 rhickey: well, then you'll need case help - what are the times with condp

15:48 stuartsierra: Last week with 2-tuples, it was slightly faster with condp

15:48 rhickey: right, and will be until case gets an all-integers specialization

15:48 Raynes: Haha. People actually do the too-hot tutorial stuff. :>

15:48 rhickey: for small n condp still might be faster

15:49 stuartsierra: That's what I thought. But it was easier to write with case.

15:49 rhickey: right, but this one fn is at the bottom of everything, make as fast as possible

15:49 stuartsierra: true

15:49 I'll try it

15:50 rhickey: now that I'm out of fn metadata nightmare I can look at case

15:50 (meta map)

15:50 ,(meta map)

15:50 clojurebot: nil

15:50 rhickey: hrm

15:50 chouser: clojurebot gets new versions of clojure fairly rarely

15:51 he's on some pre-HEAD version of the "new" branch right now I think.

15:51 hiredman: no

15:51 some lein repl version

15:51 chouser: oh

15:51 hiredman: hmmm

15:51 unfortunate sideeffect of leinizing

15:52 rhickey: cemerick: tuples should end up faster than arrays

15:52 hiredman: mmmm

15:53 now we just need a means of stack allocating

15:53 cemerick: rhickey: object creation is really that fast?

15:54 rhickey: yes, and an array is an object, and array access is bounds checked

15:55 chouser: heh. meta fns just broke what I'm doing.

15:55 arohner: ,(clojure-version)

15:55 clojurebot: "1.1.0-master-SNAPSHOT"

15:55 chouser: I should have learned by now not to build code on top of Compiler internals...

15:55 rhickey: chouser: what broke?

15:56 stuartsierra: rhickey: plain cond is very slightly faster, still not quite the equal of arrays

15:57 chouser: no multimethod for dispatch value Compiler$MetaExpr

15:57 lisppaste8: stuartsierra annotated #93626 "Ever so slightly faster with cond" at http://paste.lisp.org/display/93626#3

16:00 stuartsierra: But array performance is more consistent; tuples are harder to benchmark.

16:00 rhickey: chouser: how are you getting that?

16:01 chouser: running my own multimethod recursively on the results of Compiler/analyze

16:01 rhickey: don't worry about it. It's all my own thing.

16:03 technomancy: lein repl is wonky with clojure versions

16:04 I should have it print out a warning when it launches

16:04 or just fix it, I guess

16:08 wlr: chouser: re your lint name q, howze 'bout "clintj" pronounced "clinch". (Sorry, couldn't resist :)

16:11 rhickey: urk - stuart's code is using a macro as a fn

16:12 chouser: how?

16:12 clojurebot: with style and grace

16:12 kotarak: ,#'and

16:12 clojurebot: #'clojure.core/and

16:12 kotarak: ,@#'and

16:12 rhickey: 2-arg version calls 3 arg version as if it was a fn

16:12 clojurebot: #<core$and__4467 clojure.core$and__4467@395626>

16:13 chouser: ohhhh... :-/

16:13 wilig: technomancy: Did the read-line fix work for ya?

16:13 rhickey: that will now fail, will be a common error I thimk

16:15 Hali_303: what are some mature frameworks for persistence?

16:15 technomancy: wilig: yeah, it looks great

16:15 Hali_303: (I mean high level, not SQL interface)

16:16 wilig: technomancy: Oh good, I'm glad it worked outside of my little environment.

16:16 technomancy: still doesn't let you call clojure.main/repl from slime-repl, but it's a good move forward

16:18 wilig: technomancy: what should that do?

16:20 cemerick: it looks like one cannot use var references in clojure.test/are ...

16:21 bah, nevermind

16:22 technomancy: wilig: (require 'clojure.main) (clojure.main/repl) ;; <= should allow the new repl to take over the slime-repl buffer until it exits

16:22 wilig: ah

16:22 technomancy: wilig: I think it comes down to the simple fact that (read) from slime-repl doesn't work

16:23 since it needs a pushback reader

16:23 that might not actually be too tricky to fix now that I think about it

16:24 maybe just proxying clojure.lang.PushbackReader instead of java.io.BufferedReader would work

16:24 wilig: hmm, I agree. changing the proxy to a pushback reader shouldn't be too hard. if I understanding the problem correctly.

16:24 exactly

16:26 hiredman: clojure's is a linenumberingpushbackreader

16:26 pushbackreader is in java.io

16:27 technomancy: oh right

16:34 wilig: technomancy: you gonna have a go, or should I crack it back open?

16:35 alexyk: is there any tracing for the dreaded java.lang.NullPointerException (NO_SOURCE_FILE:0)?

16:36 technomancy: wilig: I'll have a go possibly tonight, but if you beat me to it I'd be happy. =)

16:36 alexyk: technomancy: please please add host to lein swank! I need to bind to outfacing IP

16:37 tcrayford: al3xyk can't you just use an ssh tunnel?

16:38 chouser: could make a lein plugin for it even

16:38 cemerick: alexyk: ctrl-J prints the stack trace from the last exception in enclojure *shrug*

16:39 * cemerick runs away from the emacsen :-P

16:39 alexyk: tcrayford: my tunneling is effed up with administrative error or some such

16:39 hiredman:

16:39 alexyk: cemerick: plain command line repl, how about that?

16:39 chouser: (.printStackTrace *e)

16:39 cemerick: alexyk: (.printStackTrace *e)

16:40 chouser: :-)

16:40 hyp3rvigi1ant: alexyk: when i was working on those patches, i noticed that swank seems to bind to 0.0.0.0 by default, which I think should allow connections from anywhere on any interface (though I haven't made sure of that yet)...i continued writing the patch to give users the option to specify the host in case they don't want it to be accessible on certain ips/interfaces

16:40 cemerick: chouser: that's 3/3, all less than a second before me! Well done. :-P

16:40 chouser: heh

16:40 I feel so useful

16:41 cemerick: now if I could just get my wife to be as clairvoyant ;-)

16:41 technomancy: alexyk: uh... I'll get to it eventually

16:41 if you really want it soon you could implement it yourself. =)

16:41 alexyk: chouser: thx! fast and correct every time!

16:41 chouser: now if I could just be as clairvoyant with my wife ;-)

16:42 alexyk: so long as the wives are not clairvoyant...

16:42 cemerick: alexyk: amen to that

16:43 alexyk: now I appreciate a bit why Scala etc. run away from nulls as heck, and go to such lengths with Option types. Null is nasty.

16:43 cemerick: are there *any* publicly-known women clojure programmers out there?

16:43 alexyk: You spend a few days to craft a lovely functional program, and get a null.

16:43 cemerick: Clair Voyant is as close to the scent of a woman as you get here.

16:43 hiredman: ~women

16:43 clojurebot: women are just jealous, since lisp has nice curves. -- Chousuke

16:44 cemerick: Yeah. Unfortunate.

16:44 * rhickey thinks the null problem is way overblown

16:44 alexyk: think of Lady Ada Lovelace and her lovely language Ada 2005

16:44 * cemerick didn't know there was a null problem

16:44 rhickey: there you go

16:45 wilig: technomancy: Well the simple change didn't work. No error returned, just nil.

16:45 alexyk: rhickey: I really love Clojure, but I come from OCaml where Option types make it go away, I', all soft and bamm! A null per 200 lines of dense clojure. What to do?

16:45 cemerick: if we could get a -?>> to go with -?>, I'd really be all set

16:45 alexyk: what's -?> ; ?

16:46 cemerick: -?> is like ->, but short-circuits on nulls, returning null

16:46 it's in clojure.contrib.core

16:46 alexyk: see? you said "null". :)

16:46 hiredman: alexyk: stop producing nils

16:46 cemerick: ,#'clojure.contrib.core/-?>

16:46 clojurebot: java.lang.Exception: Unable to resolve var: clojure.contrib.core/-?> in this context

16:47 alexyk: hiredman: now that's managerial! (getting back to debugging nulls)

16:47 hiredman: alexyk: how is that managerial?

16:47 * stuartsierra has a null problem sometimes

16:47 cemerick: hiredman: they're a fact of life given seq, but I'm still not clear on what the problem is

16:47 alexyk: hiredman: a good phrase to tell an underproducing programmer

16:47 hiredman: alexyk: well, start producing more

16:48 alexyk: :)

16:48 a null ate my program

16:48 Raynes: A null killed my father and raped my mother.

16:48 stuartsierra: You are likely to be eaten by a null.

16:49 rhickey: stuartsierra: you were calling a macro as a fn in your def-tuple-type (2 arg called 3 arg) - that's a no-no and new master breaks it

16:50 should be ([NAME N] `(def-tuple-type ~NAME ~N 'java.lang.Object))

16:50 hiredman: nil is a legitimate value, clojure is a dynamic language

16:50 what is the problem?

16:50 stuartsierra: rhickey: yes, I see, will fix

16:50 chouser: it's kinda crazy that it worked at all. depends on the fact that def-tuple-type isn't marked as a macro yet when that line is compiled?

16:51 rhickey: if there was a man who promised to keep you free from headaches, but only by continuously kicking you in the shin, would you want him to?

16:51 chouser: yeah

16:52 alexyk: rhickey: on a day with a null, I might welcome it; but generally no. The question is, how can null be trapped easily and isolated.

16:52 hiredman: (when x (do stuff to x))

16:52 rhickey: alexyk: you could try preconditions

16:52 lisppaste8: stuartsierra annotated #93626 "fixed recursive macro self-call" at http://paste.lisp.org/display/93626#4

16:53 alexyk: rhickey: yep, thought of that. One kinda hopes stuff will work by itself :)

16:53 Raynes: ,(+ nil nil)

16:53 clojurebot: java.lang.NullPointerException

16:53 rhickey: stuartsierra: also, your array test is not fair as it doesn't set the array elements to 3 values as does the tuple

16:53 alexyk: Raynes: scary!

16:53 Raynes: Oh noes! I has a null problems!

16:53 stuartsierra: rhickey: true

16:54 alexyk: well, now go wrap each operand in an (or..)

16:54 I wonder if a macro can be written to magicaly wrap everything in a "must-be-not-null" check

16:54 then it will cry out with specifics

16:55 Raynes: I had a NullPointerException yesterday. It was really null.

16:55 rhickey: stuartsierra: when you do that, 3-tuples of doubles beat arrays of doubles, but arrays of objects beat all

16:55 stuartsierra: rhickey: Calling aset-double kills performance.

16:55 rhickey: aset-double is not fast, aset is, with hints, hang on a sec

16:56 alexyk: ,(inc nil)

16:56 clojurebot: java.lang.NullPointerException

16:56 lisppaste8: rhickey annotated #93626 "tuples vs arrays" at http://paste.lisp.org/display/93626#5

16:56 hiredman: alexyk: what's the problem?

16:57 Chousuke: ,(inc "foo") makes as much sense as (inc nil)

16:57 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

16:57 Chousuke: and it's just as likely

16:57 alexyk: hiredman: nothin', just besting Raynes' shortest null-inducement

16:57 rhickey: stuartsierra: ^^that code is fast for arrays, but double array still requires unboxing

16:57 stuartsierra: ok

16:58 A while ago I thought about implementing tuples as Object arrays.

16:59 Chousuke: As far as I can tell, even if you had types that can't be null, you could still pass nil to functions because Clojure is dynamic. And if you had no nil, you'd instead have n different objects doing what nil does, each making as much sense as nil to functions that don't expect them.

17:01 alexyk: ,(let [m {:a 1} {a :a} m] a)

17:01 clojurebot: 1

17:02 alexyk: ,(let [m {:a 1} {:keys [a]} m] a)

17:02 clojurebot: 1

17:02 alexyk: does the latter mean that :keys prepends : to its list?

17:02 meaning varname a maps to key :a?

17:02 stuartsierra: yes

17:02 hiredman: gah

17:03 "prepending :" is some kind of text operation on characters

17:03 it certianly does not do that

17:03 alexyk: I know, I know. I mean naming convention here

17:03 well somewhere it maps a to :a

17:03 it prepends : in the eyes of the higher powers

17:03 hiredman: no

17:04 a is a symbol and :a is a keyword, :a is not a a with a : prepended

17:04 chouser: heh

17:05 alexyk: I meant names

17:05 apaprently a naming mapping is implied

17:05 chouser: yes, a name mapping is implied

17:05 alexyk: and names are text thingies!

17:05 chouser: there are :syms and :strs as well

17:06 hiredman: names are not text thingies

17:06 chouser: (name 'symbol)

17:07 ,(name 'symbol)

17:07 clojurebot: "symbol"

17:07 alexyk: hiredman: then what are they?

17:07 hiredman: alexyk: they are an abstract concept

17:07 alexyk: hiredman: which can be expressed as text thingies :)

17:07 hiredman: http://en.wikipedia.org/wiki/Lambda_calculus#.CE.B1-conversion

17:08 alexyk: an electronic computer is a machine for manipulating bytes, i.e. text

17:08 Chousuke: the :keys [a] means the map has a keyword as a key that has the same name as the symbol 'a :)

17:08 hiredman: then please write asm

17:09 Chousuke: ,(= (name :a) (name 'a))

17:09 clojurebot: true

17:09 Chousuke: same name, very different entities.

17:09 alexyk: ,(type (name 'a))

17:09 clojurebot: java.lang.String

17:09 alexyk: case closed

17:09 hiredman: no

17:09 tcrayford: that's just because name returns a string

17:09 ,(type 'a)

17:09 clojurebot: clojure.lang.Symbol

17:10 tcrayford: ,(type :foo)

17:10 clojurebot: clojure.lang.Keyword

17:10 hiredman: the name function is not the same thing as a name

17:10 Chousuke: I think you're arguing useless semantics here though.

17:11 hiredman: Chousuke: since alexyk is always in here asking for help and complaing about NPE's I think a revision of his mental model via an education in semantics might be useful

17:11 Raynes: alexyk: coolest npe http://gist.github.com/281362

17:11 alexyk: ok sorry, I was bitten by a null. I'm not asking for help per se, I love to know the right idioms. :) Now I have to track the null.

17:12 Chousuke: Well, there's certainly no prepending of : or anything,

17:12 hiredman: Chousuke: exactly

17:12 Chousuke: alexyk: you said a naming mapping is implied. I think it's rather explicit, as the syntax exists just for that.

17:12 alexyk: ok

17:13 Chousuke: but really, be wary of treating clojure code as text. it's just misleading and someone might feel the need to correct you :)

17:14 hiredman: <--

17:14 Chousuke: it has a textual representation yes, but it's still important to treat it as data.

17:14 * chouser is apparently too pragmatic for such conversations.

17:15 chouser: Clojure programs have non-textual in-memory representations, but sometimes it's important to treat them as text.

17:15 hiredman: to program in language X it is important to have a good mental model of X

17:16 Hali_303: does anyone use clj-record or clojureql in production? which is better choice for a green field project?

17:17 * qbg recalls Series Expansion from c.l.l

17:17 Chousuke: the code=data thing kind of changes the terminology a lot though

17:18 hiredman: it's even a code=date thing, it is confusing a concrete manipulation with semantic intent

17:18 it's not even

17:19 Chousuke: instead of "let" having syntax consisting of an open bracket and a list of bindings, a closing bracket and a body of expressions, it instead "takes a vector of binding forms" and an arbitrary number of expressions.

17:19 hiredman: if I have a function F that produces :a when applied to 'a the intended meaning is a mapping of symbols to keywords

17:20 confusing that a possible concrete method for creating that mapping is bad

17:20 that with

17:20 Chousuke: yeah. though I think this was blown out of proportion a bit :P

17:21 hiredman: is F a mapping between values or a procedure for pretending :

17:21 chouser: the name of a symbol is a string

17:21 hiredman: prepending

17:28 alexyk: I have two files: a big one with (ns ...) on top, and a fun I factored out and killed null in. I pasted the big file into repl, then was fixing the factored-out fun and did (load-file "it.clj") until it works. Now If instead of pasting I do (load-file :bigfile.clj") the ns doesn't change and small fun cannot find stuff from it. Pasting just the ns header works. How can I change the bigfile so its ns header is injected into repl as if pasted?

17:30 tcrayford: use :reload

17:30 maybe?

17:30 * tcrayford doesn't know if load-file caches stuff

17:30 qbg: When you load the file, the namespace will be updated, but your ns won't change

17:30 Why not just switch to that namespace?

17:31 tcrayford: via (in-ns 'new-ns)

17:31 alexyk: qbg: right... How do I switch to it from repl?

17:31 ah ok

17:31 qbg: (in-ns 'your-namespace)

17:31 alexyk: lovely

17:31 and beautifully, on a defn from a file, a line is printed where null occurs. That solves the Clojure Null problem. :)

17:35 rikthevik: let's say i have a map (structure) and i do a map (function) on it. what's the best way to assemble that list of vectors back into a map (structure)?

17:35 hiredman: (into {} ...)

17:35 (apply conj {} ...)

17:37 rikthevik: ah, beautiful. i usually have a good idea of what i want to do, but i have trouble figuring out the exact function i need. thank you

17:40 ts00000: anyone clueful with compojure that can show me how a javascript should be declared in (html)?

17:42 arohner: ts00000: you just make your string an attribute in a script element

17:42 ts00000: you can also use scriptjure, but that compiles down to a string, and you use it in the same place

17:42 ts00000: I tried [ :script "test.js" ] but I don't think that does the right thing

17:43 hiredman: ts00000: um

17:43 arohner: if you want to include a js file, you can use the include-js function provided by compojure

17:43 hiredman: ts00000: how do you include javascript in html? (hint: it is an exact map to compojure's [:tag] style)

17:43 tcrayford: aye

17:44 ts00000: hiredman: what I want is to do a script src

17:44 but I think arohner might have it

17:45 arohner: which would be [:script {:type "text/javascript" :src "foo.js"}]

17:45 if you wanted to do it "by hand"

17:45 ts00000: thanks arohner, I was trying something wrong and forgot about the curlies

17:45 still learning syntax

17:46 programming clojure goes through it so fast it's hard to keep track of :-)

17:47 so I can just use include-js inside the html/

17:47 ?

17:48 tcrayford: (html (include-js "foo.js")) works fine

17:48 ts00000: finally just found a good example

17:48 thanks folks

17:48 tcrayford: user=> (html (include-js "foo"))

17:48 "<script src=\"foo\" type=\"text/javascript\"></script>"

17:48

17:49 ts00000: http://www.pgcon.org/2009/schedule/attachments/96_visualizing-postgres-2009-05-21.pdf has way more examples than i'd seen so far

18:02 the-kenny: I love the xkcd comic in the pdf

18:02 tcrayford: is there an easy way to get clojure regex to match newlines?

18:03 hiredman: ,(re-find #"\n" "\n")

18:03 clojurebot: "\n"

18:03 tcrayford: say I have a string "foo\nbar", and I want something like #"^foo.*" to match it

18:03 the-kenny: tcrayford: Take a look at RegexPattern javadocs

18:03 hiredman: oh

18:03 you have to use a flag

18:03 ?s maybe?

18:03 tcrayford: does that mean dropping down to java?

18:03 hiredman: no

18:03 tcrayford: or just at the start of the pattern

18:04 hiredman: ,(re-find #"(?s)*" "\n")

18:04 clojurebot: Dangling meta character '*' near index 4 (?s)* ^

18:04 hiredman: ,(re-find #"(?s).*" "\n")

18:04 clojurebot: "\n"

18:04 ts00000: ?s is the flag

18:04 like

18:04 hiredman: ,(re-find #"(?s)foo.*" "foo\nbar")

18:04 clojurebot: "foo\nbar"

18:04 ts00000: "(?s).+?(?:\n\n|$)"

18:04 hiredman: ,(re-find #"(?s)foo." "foo\nbar")

18:04 clojurebot: "foo\n"

18:04 hiredman: ,(re-find #"(?si)foo." "FOO\nbar")

18:04 clojurebot: "FOO\n"

18:11 dabd: methods are supposed to be documented with metadata #^{:doc "...." ?

18:12 it would be nice if the defmethod macro also supported documentation strings

18:14 hiredman: dabd: where do you put the docs?

18:14 tcrayford: cheers for that hiredman, problem solved

18:14 jcromartie: what are the implications of putting lots of jars on your classpath?

18:14 dabd: hiredman: well I put the multimethod doc string in defmulti

18:14 jcromartie: does it really matter if you don't use the libs/classes?

18:14 dabd: hiredman: but it would be nice to be able to document also the methods

18:15 arohner: jcromartie: not really

18:15 ts00000: how can you get find-doc and repl-utils/source to return private methods?

18:15 or can you?

18:15 hiredman: dabd: the docstring is not just suspended in space, it is hung on the var

18:15 where would you have it for defmethods?

18:15 how would you look it up?

18:15 jcromartie: how about (doc multimethod type)

18:16 hiredman: jcromartie: that does not solve the "were to put it problem"

18:16 * tcrayford keeps on defining the following macros in all of his tests

18:16 tcrayford: (defmacro is=

18:16 ([expr val] `(is= ~expr ~val ""))

18:16 ([expr val msg] `(is (= ~expr ~val))))

18:16 dabd: hiredman: I see

18:16 tcrayford: wondering if its worth adding that to clojure.test

18:16 dabd: hiredman: is there any way to add documentation specific to a method?

18:17 hiredman: dabd: if the behaviour of the multimethod is so out of line with the documentation from the defmulti you might consider making it a seperate function

18:18 you can always make comments

18:18 jcromartie: I think if you have to document each defmulti you should probably break it up.

18:19 err

18:19 defmethod

18:19 dabd: hiredman: the specific case is a multimethod that performs queries either in SPARL or SQL so the result set is different in each case and I wanted to document that. However code comments are only useful for developers and they cannot be inspected with the REPL or programmatically

18:19 jcromartie: I'd just document the two result sets in the defmulti

18:20 but if your return values are different between two defmethods for the same defmulti then it doesn't really seem like a good use for multimethods

18:20 or at least if you can't use the return value in the same way

18:21 dabd: jcromartie: the return value is a seq over the result set. So I use it as a sequence abstraction

18:39 hiredman: clojurebot: git 277f0235c1387ddd6247a72857597814a3e10bc3

18:39 clojurebot: add &form and &env implicit args to macros

18:39 hiredman: neat

18:40 jcromartie: are there any problems using symlinks to jars?

18:41 wilig: anyone know how to call a super method from a proxy?

18:41 jcromartie: like if I have a directory full of symlinks to the jars I want to use, and I specify them in the classpath with something like "$HOME/.clj/jars/*" I can't seem to use or require any of the libs

18:43 oh, hmm

18:46 hiredman: wilig: proxy-super

18:46 jcromartie: maybe I should be using hard links

18:47 hiredman: jcromartie: * when expanded by the shell does not work in the classpath

18:47 jcromartie: I know

18:47 I think the problem is with my links

18:47 they carry the exact path source file path that I specified... not an absolute path to the source file

18:47 hiredman: jcromartie: it also only works for java 6+

18:47 jcromartie: so they are only relative

18:48 yah I'm on 6

18:48 it works with hard links or real jras

18:48 jars

18:48 but my symlinks have the wrong source file

18:48 hiredman: well, I've never had problems with symlinks

18:48 jcromartie: if I do ln -s ./foo/bar bat

18:48 then bat is a symlink to *exactly* ./foo/bar

18:49 meaning it will still be ./foo/bar wherever I access it from

18:49 so the full path must be specified

18:55 I guess hard links are probably better for this than symlinks.

18:55 krumholt_: i want to traverse and find the first element to fullfill some condition how would i do that?

18:55 jcromartie: I dunno... you all probably just copy the freaking jars :)

18:56 krumholt_: first, filter

18:56 or some

18:56 krumholt_: jcromartie, ah ofcourse thanks

18:57 jcromartie: ,(some even? [1 3 5 6 7])

18:57 clojurebot: true

18:57 hiredman: ,((comp first filter) even? [1 3 5 6 7])

18:57 clojurebot: 6

18:57 jcromartie: ,(first (filter even? [1 3 5 6]))

18:57 clojurebot: 6

18:57 jcromartie: ooh, fancy with the comp

18:58 but you made it bigger :)

19:05 some is fun for maps and sets

19:05 ,(some {:foo 1 :bar 2} [:bat :baz :foo])

19:05 clojurebot: 1

19:17 zmyrgel: how can I make hash map out of two lists?

19:18 I'm trying to make hash map of hex chars, like :11 points to b

19:18 Chousuke: zipmap might help

19:18 map keys don't have to be keywords either

19:19 zmyrgel: zipmap was just the thing

19:21 I'm trying to learn clojure by converting one of my java projects to it

19:24 this would be easier if I hadn't forgotten my copy of halloway's book at my parents house

19:24 Chousuke: zmyrgel: A good idea, but it's also a double-edged sword. You may end up writing Java in Clojure if you're not careful :)

19:24 zmyrgel: true that

19:25 but I guess it takes time to learn the 'flow' of different language

19:25 Chousuke: though I suppose that's a good experience as well.

19:25 yeah

19:25 especially since Clojure outright abandons most concepts familiar to Java programmers :P

19:26 zmyrgel: true that

19:27 Raynes: Bleh. More code to change.

19:27 zmyrgel: I could do my bachelor's thesis about clojure if I can't ooze myself into any real job

19:27 Raynes: I was doing (apply hash-map (interleave blah blah)). :|

19:27 Chousuke: ~def zipmap

19:28 hmm

19:28 off sync it seems

19:52 janjan: Is there a max-seq or something like that? so I can do (max-seq [1 2 3]) as (max [1 2 3]) doesn't work

19:53 jcromartie: do you just want the maximum value in a seq?

19:53 janjan: ,(max [1 2 3])

19:53 clojurebot: [1 2 3]

19:53 janjan: jup

19:53 jcromartie: ,(apply max [1 2 3])

19:53 clojurebot: 3

19:53 jcromartie: ,(apply max (range 1 20))

19:53 clojurebot: 19

19:54 janjan: hmm, guess I'm still thinking too much in Python

19:54 thx

19:54 jcromartie: there are other ways that are perhaps more traditional

19:55 ,(reduce max [3 4 2 6 7 3])

19:55 clojurebot: 7

19:55 janjan: I'd say the apply one is more traditional than using reduce :)

19:56 jcromartie: really? I see reduce more than apply

19:56 apply seems to be more of a lisp thing

19:56 janjan: yea, but reducing with max is not something I'd find intuitive

19:56 jcromartie: I suppose not

19:57 but reduce is usually in the "intro to FP" curriculum if you know what I mean

19:58 janjan: I know it, but i'm used to use it with the traditional operators like + and *, but it works equally well with max I guess

19:59 though I usually program Python, and there you mostly don't use any of apply, reduce, map, etc.

20:02 jcromartie: it works great with all sorts of wacky things in clojure

20:03 you could use a map or set as a predicate for reduce

20:03 or any number of things

20:03 anything callable

20:03 konr`: I wish I could use github's search engine to find interesting examples

20:04 seths: ,(map (partial nth (seq "abc")) [0 2])

20:04 clojurebot: (\a \c)

20:04 konr`: but "(apply " returns all sorts of things

20:04 including "this applies to ..."

20:09 jcromartie: Google code search... now if only it had some interesting Clojure code :P

20:12 konr`: It would be cool to be able to search for code using queries like "(reduce $FN ...) where $FN != +"

20:17 janjan: Funny, in another (older) part of my code I had had the same problem of 'how do I apply this func to that seq', the func being + in that case. I also didn't think of 'apply', but I did come up with reduce. But with the max case that didn't come up in my mind.

20:23 hiredman: I do believe max and + both internally use reduce for more than two args

20:23 rhickey_: waddya think - is Clojure the borg? http://vintage-digital.com/hefner/misc/lisp-programmers.jpg

20:25 jcromartie: aw man, that is a riot

20:25 I love Forth vs Factor

20:25 they're all brilliant

20:25 konr`: hahahaha

20:27 jcromartie: Clojure is *Captain Picard as a Borg*, that's gotta count for something

20:28 hiredman: I think it is import to keep in mind that is supposed to represent the view of a common lisp programmer

20:28 janjan: Apparently CLers are afraid of clojure 8-]

20:30 hiredman: I think it's http://www.loper-os.org/?p=42 in in picture form

20:31 rhickey_: hiredman: I thought that was the "zombie-reanimated corpse of a dream" guy

20:31 hiredman: yeah

20:31 * rhickey_ prefers Borg over zombie

20:31 hiredman: well, what else is a borg?

20:31 I guess you get the groovy head gear

20:31 rhickey_: it's very funny in any case

20:38 Raynes: The PHP and Haskell ones are hilarious.

20:45 wilig: hiredman: Thanks exactly what I was looking for.

20:46 Raynes: "You’re looking at it wrong. It’s not meant to be a serious Lisp. It’s only cosmetically descended from McCarthy’s original idea. It’s an attempt to terraform the wasteland of the JVM. It fails, of course, but it does make it at least somewhat less likely that geysers of molten arsenic will pour through your floor at 1AM." Eh.

20:48 hiredman: kind of poetic

20:51 the serious (common) lisp almost killed lisp completely

20:53 jcromartie: Raynes: is that from that Loper OS guy?

20:53 Raynes: jcromartie: No.

20:53 It was from a guy who was trying to defend Clojure, and ended up doing so with misinformation.

20:55 jcromartie: hah

21:15 chouser: I look forward to seeing how such arguments get adjusted once clojure starts maturing on other VMs.

21:20 jcromartie: Clojure on LLVM will be a great day.

21:20 But this guy has me thinking: how about building a "clojure machine?"

21:20 "clojure-all-the-way-down"

21:21 with the major caveat that Java is OK

21:21 and the OS that Java runs on

21:22 let's say Linux and a JVM and then everything else implemented in clojure

21:22 it's most just UI at that point

21:23 but you could start replacing the lower parts of an operating system with clojure code

21:23 hiredman: there are jvms that run without an os

21:23 jcromartie: well there we go

21:23 hiredman: ~google maxine java

21:23 clojurebot: First, out of 16000 results is:

21:23 Maxine VM

21:23 https://maxine.dev.java.net/

21:23 jcromartie: You could eventually build something like Genera but for Clojure.

21:23 hiredman: ~google guest os java

21:23 clojurebot: First, out of 493000 results is:

21:23 Virtualbox guest OS networking on WinXP host : Tao&#39;s Sun Blog

21:23 http://blogs.sun.com/tao/entry/virtualbox_guest_os_networking_on

21:23 hiredman: bah

21:24 jcromartie: I mean obviously you're never going to have something like a "Lisp machine" that has hardware built to run Lisp.

21:26 it's too bad practicality and productivity have to get in the way of lofty goals and idealistic outlooks

21:26 :)

21:26 (not really)

21:54 limux: in the lastest release lein.bat 1.1.0, it required leiningen-1.1.0-SNAPSHOT-standalone.jar, but there is not that file at all, except the leiningen-1.0.1-standalone.jar, why?

21:56 devlinsf: liebke: Hey, trying to get those fixes in chrono

21:57 defn`: Are there any HTML/CSS parsers for clojure?

21:57 alexyk: what's a good lazy way to write nondecreasing? predicate for a seq?

21:58 liebke: devlinsf: Great, I really like your api design (and your screencasts)

21:58 defn`: im looking for something like nokogiri

21:58 devlinsf: liebke: thanks. What build tool do you use?

21:58 liebke: maven

21:58 devlinsf: Ah

21:58 Okay, installing

21:59 liebke: sorry to do that to you :)

21:59 defn`: i guess the next logical question i have is, if there isnt a good XPath/CSS parser for clojure, what would you recommend in Java?

21:59 alexyk: nothing like maven to get your juices going at night!

21:59 devlinsf: liebke: Eh, I haven't used it yet. I'll write this one off as a "Learning Experience"

21:59 liebke: :)

21:59 alexyk: oh, the rage! oh, the evil monstrous energy!

22:00 liebke: devlinsf: oh, you're in for a good time :)

22:00 devlinsf: Great

22:00 liebke: devlinsf: the existing incanter.chrono pom.xml file should work for you, you might not have to do anything

22:00 devlinsf: With a little luck

22:03 * alexyk still wonders how to write a lazy (nondecreasing? [seq])

22:04 cemerick: alexyk: nondecreasing?

22:05 alexyk: cemerick: yeah!

22:05 lazy one

22:05 I have a reduce-driven one, but aint' lazy

22:05 devlinsf: alexyk: How about partition, map & some?

22:06 cemerick: alexyk: I'm not sure what you mean by 'nondecreasing'

22:06 devlinsf: [1 2 3]

22:06 alexyk: cemerick: ok, simply increasing? will do.

22:06 cemerick: (iterate inc 0)

22:07 alexyk: nondeacreasing? means for any subsequent x y, x <= y, increasing? means x < y

22:07 hiredman: he somehow wants a predicate to tell him that a seq only has values that increase in order, without actually looki ng at the seq

22:07 madness

22:07 alexyk: the predicate checks an existing seq lazily and at any moment says true or false

22:07 basically it bails once it feels violated

22:07 hiredman: that is not a predicate

22:07 alexyk: ,used and betrayed by the seq

22:07 clojurebot: java.lang.Exception: Unable to resolve symbol: used in this context

22:07 hiredman: that is map

22:08 ,(let [x [1 2 3 4 0]] (map > x (rest x)))

22:08 clojurebot: (false false false true)

22:08 hiredman: ,(let [x [1 2 3 4 0]] (map < x (rest x)))

22:08 clojurebot: (true true true false)

22:08 devlinsf: ,(every? #(apply < %) (partition 2 1 [1 2 3 4 3]))

22:08 clojurebot: false

22:08 devlinsf: There you go

22:08 defn`: anyone have a recommendation on a good xpath/css html parser for clojure? java libs suggestions welcome

22:09 cemerick: alexyk: there's take-while if you want to consume until a predicate fails, but you have to look at a seq in order determine anything about it.

22:09 devlinsf: every? is lazy, is it fails fast

22:10 alexyk: devlinsf: looks good, hope it's lazy...

22:10 devlinsf: Every is eager, but it fails quick

22:10 Add a call to Thread/sleep to see

22:10 rhickey_: devlinsf: I had a question about your latest video - why are all the multimethods variadic?

22:10 alexyk: devlinsf: easy to check, lemme load 100M twits

22:11 devlinsf: rhickey_: Ah. Check my work in incater

22:11 rhickey_: ?

22:11 devlinsf: http://groups.google.com/group/incanter/browse_thread/thread/4d678e226b3a1f0a

22:12 alexyk: hiredman: yours is good, but does all seq, while I need to fail asap

22:12 devlinsf: It lets you optionally pass stuff, like a keyword to the string parser

22:12 hiredman: alexyk: you cannot do that lazily

22:12 devlinsf: rhickey_ Granted, the multimethod could use some polish

22:13 hiredman: you want something to look at the whole seq, and yet some how not look at the seq

22:13 alexyk: hiredman: well I want to consume the seq lazily and stop doing it once I see it fails the test

22:13 rhickey_: I still don't understand - to-ms takes and uses only one arg

22:13 chouser: defn`: you're looking for a way to query/filter/lookup things in an html document?

22:13 devlinsf: rhickey_: I'm going to re-implement it as a protocol eventually, I'm too lazy to optimize now.

22:14 hiredman: ,(let [x [1 2 3 4 0]] (take-while true? (map < x (rest x))))

22:14 rhickey_: devlinsf: I just think it's confusing, a newcomer to multimethods would be baffled

22:14 clojurebot: (true true true)

22:14 defn`: chouser: filter out specific xpaths, depending on whether a regex matches the content therein

22:14 and compose a new html doc from that information

22:14 i was trying to use enlive, but i dont know if it's well suited to my needs

22:14 devlinsf: Eh, yeah, you might be right.

22:14 chouser: defn`: enlive and zip-filter are the two most clojury solutions I know of.

22:14 defn`: im playing with htmlparser right now, but was wondering if anyone had any other suggestions

22:15 kmurph79: why is there a dot after File in this ex: (.listFiles (File. "."))

22:15 devlinsf: rhickey_: I was going for power, not easy to understand

22:15 defn`: im not clear on how to get the HTML of the tagsoup that enlive creates

22:15 chouser: kmurph79: (Foo. x) is the same as (new Foo x)

22:15 kmurph79: chouser: thank you

22:16 defn`: im doing something like (at (html-resource (as-url "http://...")) [:div#blah :p :b])

22:16 rhickey_: devlinsf: I don't see the power, you don't ever use the rest args

22:16 defn`: this returns a big ole mess of tagsoup -- anyone know how to turn that back into HTML?

22:16 alexyk: hiredman: nice, thx!

22:17 devlinsf: rhickey_: I have another version where the :default uses (into {} params)

22:17 keyword input

22:17 chouser: defn`: I think there's an "emit" fn there somewhere.

22:18 defn`: chouser: ill keep playing -- thanks though

22:18 chouser: you might be able to use clojure.xml/emit -- sorry, I'm not sure.

22:18 rhickey_: devlinsf: also to-ms-dispatch, very strange

22:18 devlinsf: Yeah.

22:18 It's an early mm

22:19 Hmmm... maybe I shoulda polished it a little more

22:19 rhickey_: devlinsf: I thought the example was good, but those details make it very confusing

22:19 especially, people often make mistakes with custom dispatch functions, essentially doing some of the dispatch there, but rendering the multimethod 'closed'

22:20 devlinsf: True. I;m not quite sure how to dispatch on an abstract class

22:20 ohpauleez: is stuart halloway in here, I forget what he uses for his IRC handle

22:21 devlinsf: Hence I'm looking forward to the protocol version

22:21 rhickey_: devlinsf: you can use class as your dispatch and the abstract class or interface as the dispatch value - it just works

22:21 devlinsf: Oh

22:21 Well, that should clean some stuff up.

22:21 rhickey_: because multimethods use isa matching

22:21 devlinsf: not equality?

22:21 rhickey_: right

22:21 devlinsf: Good to no

22:21 know

22:22 Sounds like I have correction #2 next week

22:22 rhickey_: devlinsf: the video series is a great idea

22:23 devlinsf: Glad to help

22:24 alexyk: hiredman: take-while piles on "true"s, I only need one

22:25 hiredman: alexyk: uh

22:25 alexyk: every? on top?

22:25 hiredman: no

22:26 you need to figure out what you actually want so that you able to clearly explain it. by that time you should be able to write it

22:31 chouser: ,(every? true? (apply map > ((juxt rest seq) [1 3 4 6 7])))

22:31 clojurebot: true

22:33 alexyk: nice

22:34 now for strings, is there anything better than replacing < by (< (.compareTo x y) 0)?

22:45 chouser: (< (compare x y) 0)

22:46 not much better. :-P

22:48 alexyk: chouser: but generic for any types, right?

22:49 chouser: also, devlinsf has every? <seq>, and you have every? true? <seq> -- same?

22:52 chouser: 'every?' takes two args

22:57 alexyk: ah right

23:16 defn`: hmm, how do i convert from hex to a string

23:17 I have the groupings ((\6 \4) (\7 \D) ...)

Logging service provided by n01se.net