#clojure log - Mar 19 2009

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

0:07 Raynes: http://www.qconlondon.com/london-2009/file?path=/photos/speakers/Rich_Hickey.png Rich needs to grow a beard :(

0:11 pstickne: What are you doing in #Scala you traitor :|

0:19 pstickne: Raynes: :-)

0:25 replaca: Chouser: are you still online?

0:26 Raynes: He has shifted into sleep mode. He is idle I'm afraid. You would have to hack into his brain and garbage collect his sleep bytes.

0:27 durka42: be careful, he might throw an InterruptedException at you

0:27 those have undefined behavior, and are hard to catch

0:27 replaca: Raynes: thx. I thought he might have wake-on-LAN set :-)

0:27 Raynes: ;)

0:28 replaca: At this hour, #clojure is full of folks who are either (a) up too late or (b) from California and therefore just plain weird

0:28 (I'm in the latter category)

0:29 durka42: i am in the former

0:29 replaca: I'll be there later tonight, I'm sure

0:30 Raynes: It is only 11:29 :(

0:31 replaca: Raynes: are you Chouser's neighbor (CDT)?

0:31 Raynes: Yup.

0:31 Alabama.

0:32 replaca: Ahh, one of my work buddies is from Alabama. He's happy to be out here, but his family can't understand how he spent $1M for a 2 bedroom condo

0:42 pstickne: is there a way to treat *(* or similar as a symbol?

0:45 durka42: ,(symbol "*(*")

0:45 clojurebot: *(*

0:45 durka42: trying to break people's syntax highlighting? :p

0:46 pstickne: err, without making it more complicated :p

0:46 replaca: pstickne: basically, no

0:46 pstickne: I'm playing with fnparse now, and it's be nice to be able to "make it look more like EBNF")

0:46 fair enough

0:47 replaca: pstickne: you can do what durka42 did, but you can't run it through the standard reader

0:47 so I don't think you'll get what you want

0:47 durka42: nope, you have to do really ugly things like (eval `(def ~(symbol "*(*") 42))

0:47 (don't do that)

0:47 replaca: you can always write your own reader for grammars, though :-)

0:47 pstickne: nah... :)

0:48 replaca: not sure you really want to go there, though there may be times

0:48 pstickne: I'm already lost enought as it is

0:48 replaca: when something like that makes sense

0:48 durka42: (var-get (resolve (symbol "*(*"))) ; not worth it

0:48 * pstickne feels scared without his inferred static typing

0:49 replaca: like trapeze without a net!

0:52 Raynes: Like a trapeze without a net or a rope because you get the power to fly only you have to keep eating magical flying beans to stay in the air and if you aren't careful you could forget to eat one and fall to your death.

0:55 durka42: it's better than the alternative, which is carrying all these construction materials so you can build scaffolding to work around the inability to fly

0:56 replaca: I think these metaphors might be teetering a little bit

0:56 * Raynes plays a game of tetris written in Factor

0:56 durka42: a stack-based game in a stack-based language

0:57 Raynes: That language is awesome. I just can't bring myself to learn it when I'm told that the easiest way to learn it is "Read libraries". :\

0:57 durka42: heh

0:57 pstickne: well, that's a bummer, I can't copy this epsilon from the PDF :(

1:00 Raynes: pstickne: They make you read PDF's because then you have to type out examples yourself.

1:01 durka42: you can, however, treat it as a symbol :)

1:01 ,(let [? 2 ? 3] (+ ? ?))

1:01 clojurebot: 5

1:03 Raynes: ...

1:03 o_o

1:03 pstickne: Raynes: I'm not interested in copying over the EBNF by hand :)

1:04 hiredman: that? amazing�

1:04 pstickne: maybe I could find nice unicode characters for ... ;-)

1:04 hiredman: ...

1:04 ?

1:04 pstickne: (which would mean I would need to learn how to use unicode input)

1:05 hiredman: I have irssi setup to change "..." into the unicode ...

1:05 ?

1:06 pstickne: I could use a snowman for a ';'! :-)

1:06 durka42: ,?

1:06 clojurebot: java.lang.Exception: Unable to resolve symbol: ? in this context

1:06 pstickne: and there might be subscripted numbers for expr1... exprn :)

1:06 * pstickne things this is getting out of hand

1:07 hiredman: ??

1:07 durka42: well you will just have to write an OCR engine/EBNF parser combo

1:07 pstickne: hiredman: those "flop" when they are highlighted here...

1:07 hiredman: wall�e

1:07 flop?

1:08 pstickne: hiredman: they "change places" -- a glitch in xchat or something

1:08 hiredman: �benchmark

1:14 pstickne: oh, lame

1:15 now I get an EOF while reading but emacs tells me everything is ok :(

1:15 oh, I lie

1:15 durka42: that means paren mismatch

1:17 pstickne: :p

1:17 is there a way to forward-declare functions?

1:17 durka42: (doc declare)

1:17 clojurebot: defs the supplied var names with no bindings, useful for making forward declarations.; arglists ([& names])

1:17 pstickne: thanks!

1:20 erm. it seems like they aren't really bound?

1:20 (declare a) (def b a) ;; kaboom!

1:21 durka42: (declare a) a will now resolve to a var, but has nothing bound to it

1:21 what are you trying to do?

1:22 pstickne: Write something using fnparse. I would like to write it like it looks in EBNF, where a production comes before the productions it uses

1:22 (def prog (conc stmt)) (def stmt ...) etc.

1:22 durka42: the point of declare is so you can write (defn f [x] (/ (g x) 2)) and write g later

1:23 hmm

1:23 maybe you have to use something other than def...

1:23 * durka42 does not know fnparse

1:24 pstickne: ohh, I need a good read on the differences between all the def* forms :(

1:25 replaca: pstickne: I think you may be out of luck. I just skimmed fnprse the other day and it looked like the macros realy want to use the data you give them

1:26 pstickne: man, I didn't even know it used macros ^^

1:26 sneaky lisp

1:27 replaca: now I've lost it. Where is fnparse?

1:28 hiredman: ~fnparse

1:28 clojurebot: No entiendo

1:28 pstickne: I found it in a link out of the 'libraries' section of clojure.org

1:28 replaca: ahh, github

1:28 hiredman: ugh I think my ~ is acting weird

1:28 clojurebot: fnparse

1:28 clojurebot: Huh?

1:28 pstickne: hiredman: too squigly?

1:28 hiredman: maybe not

1:28 ~parse

1:28 hmm

1:31 replaca: pstickne: I eat my words, it's all just func calls, but the values are all intepreted as you go

1:31 hiredman: ~parse

1:31 clojurebot: parser is http://github.com/joshua-choi/fnparse/tree/master

1:32 replaca: hiredman: boy, clojurebot is helpful. I'd already found it and read most of the source :-)

1:32 pstickne: oh, fnparse does the forward-declare by using #'production

1:33 hiredman: replaca: there was a bug in it's lookup code

1:33 pstickne: (declare prod) (rule (alt ... #'prod)) ;eg

1:33 replaca: hiredman: just givin ya a hard time!

1:33 pstickne: hiredman: a ... bug?

1:34 hiredman: yeah, it was swallowing the response

1:34 replaca: pstickne: oh, and then it interprets the var later? Interesting. I must read code more closely

1:34 pstickne: replaca: I dunno :)

1:35 replaca: I'm looking forward to spending a *lot* more time reading clojure code

1:35 I haven't done nearly enough (got to write enough that I learn from reading, but I think I'm at that point now)

1:38 cmvkk: are lazy-seqs 'thread safe'? actually what i mean is, is there a 'guarantee' that a lazy-seq will only be called once for each element in the sequence? what if two threads call seq on the same object at the same time?

1:39 i want to know if it's okay to have side-effecting code in a lazy-seq. (other problems with that concept notwithstanding)

1:39 replaca: cmvkk: well they're thread safe but not in the way you're thinking

1:39 cmvkk: well yes. i know they're thread safe in some sense, as i hope every clojure-native construct is

1:40 replaca: if I give the same lazy-seq to two threads and as for (first ls) I'll get the *same* value in both threads

1:40 that's the functional thing

1:40 hiredman: ,(doc lazy-seq)

1:40 clojurebot: "([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls. Any closed over locals will be cleared prior to the tail call of body."

1:41 replaca: so in fact, in that sense, you're guaranteed to get the object twice

1:41 hiredman: ? says once

1:41 cmvkk: hmm...i read that too, and it did seem to indicate that to me, but i wonder if that's what it really means?

1:41 or rather, i wonder if it was written with this scenario in mind.

1:41 hiredman: it depends on which once that is

1:41 replaca: yeah, but not on different threads because each thread will actually have it's own lazy-seq, once it modifies it, I think

1:42 but I might be wrong

1:42 cmvkk: if you put a lazy-seq in a var, and then call (take 10 foo) on it twice, then code inside will only run the first time. that's what i take the doc to mean.

1:42 replaca, not if that lazy-seq is in a ref!

1:42 actually...

1:42 replaca: cmvkk: yes, that's right

1:43 cmvkk: i assume if you put a lazy-seq in a ref, then have three separate threads call (take 20 foo) on it or whatever, that the code will only run once as long as those calls aren't concurrent.

1:43 hiredman: that sounds like a bad assumption

1:44 cmvkk: i mean, as long as you do them 5 seconds apart or whatever, so that they definitely don't overlap.

1:44 replaca: yeah, interesting.

1:44 hiredman: assuming things aren concurrent is a bad idea

1:44 replaca: I think I need to read even more code :-)

1:44 cmvkk: oh yeah hiredman, i'm not assuming that at all.

1:44 that's why i'm asking this...because in my case, i don't know if the calls won't be concurrent or not.

1:45 hiredman: ~bat signal

1:45 clojurebot: /summon Chouser

1:45 cmvkk: heh

1:45 hiredman: ~bat signal

1:45 clojurebot: /summon rhickey

1:46 cmvkk: this is such a weird question, i might just have to look at the java code myself

1:48 hiredman: so you have side-effects in a lazy-seq and you want to make sure they only happen once?

1:48 stuhood: (doc cache-seq)

1:48 clojurebot: Gabh mo leithsc�al?

1:48 hiredman: ,(doc seque)

1:48 clojurebot: "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer."

1:48 cmvkk: in theory, the lazy-seq body would be making changes to atoms and stuff.

1:49 hiredman: ~def lazy-seq

1:49 cmvkk: in practice, there might be other problems with this idea other than just concurrency...

1:50 in general: what i want is an object that works like a stream, but that can have as many consumers as possible, and interim values would be cached.

1:50 as needed*

1:51 several callers on a lazy-seq would produce that possibility, i think...since anything past the slowest caller could be garbage collected, and anything above the fastest caller wouldn't be generated yet.

1:51 hiredman: erm

1:52 something about that doesn sound right

1:52 cmvkk: heh

1:52 hiredman: I suggest a LinkedBlockingQueue

1:53 cmvkk: I in fact am already using those, thanks to you from earlier.

1:53 hiredman: hah

1:53 cmvkk: but they can't have multiple consumers I don't think

1:53 hiredman: oh

1:53 uh

1:53 replaca: cmvkk: Looking at the source, it doesn't seem to do anything to protect you

1:53 hiredman: ~jdoc java.util.concurrent.LinkedBlockingQueue

1:54 cmvkk: replaca, i think yo're probably right, although i can't tell

1:54 mostly because i don't know what the 'synchronized' keyword means in front of a java method

1:55 stuhood: it means that if one thread is inside a synchronized method, no other thread may enter a synchronized method for the same object

1:56 cmvkk: stuhood, aha thanks. do other threads block until the method is finished?

1:56 stuhood: yes

1:56 cmvkk: that indicates to me that in fact seqs ARE thread safe in the way that i mentioned: two threads couldn't call seq on the same lazy-seq at the same time.

1:57 because seq is a synchronized method.

1:57 replaca: oh yeah, I forgot about java synchronized, read right over it and looked for a lock :-(

1:57 hiredman: cmvkk: all threads would block on the slowest item in the lazy-seq

1:58 cmvkk: hiredman, what do you mean?

1:58 stuhood: if each thread was generating the items in the lazy seq independently, they'd all be racing eachother

1:58 replaca: hiredman: I don't think so, because different threads would be at different points which would be represnted by different java instances

1:59 hiredman: replaca: to get to a point in a lazy seq you have to pass through the previous points

2:00 replaca: right, so if the lazy seq were the bottleneck, all the threads would "catch up"

2:00 stuhood: yea

2:00 replaca: but if something else were the bottleneck they'd live happily and (more or less) independently

2:01 hiredman: you might want a sequeue, to keep the lazy-seq calculating ahead of teh consumers

2:01 replaca: with the first thread to get to any point doing the actual work

2:02 cmvkk: hiredman, that's true...although in practice, i'm probably going to have dozens of these seqs, and not that many separate threads.

2:02 the thread-safe issue here is just in the off chance that a seq has two different callers in two different threads (i don't actually think this is very likely to happen)

2:02 but i'd like to make sure that the program doesn't die weirdly if it does.

2:04 anyway, thanks for your help guys...i think i'm a bit closer to figuring out how i want to do this.

2:09 pstickne: well, what a pesky bug

2:09 fnparse wasn't working correctly because I was using 'ident' as a def name

2:10 I have no idea what was really happening -- just that it never worked :(

2:14 replaca: pstickne: ugh. that's lousy.

2:16 hiredman: that? why you use require :as instead of use

2:16 that's

2:16 ' then s results in ? I have to press ' then space then s to get 's

2:17 pstickne: hiredman: I only use fnparse and fnparse only uses except only throw-arg :(

2:18 oh, and I use seq-utils, but only flatten

2:18 hiredman: ugh, this is driving me nuts, " then u becomes � I have to type " then space then u to get "u

2:19 use or (use ...)

2:20 replaca: using a euro-keyboard?

2:20 hiredman: nope

2:20 is that "euro-keyboard" behaviour?

2:20 replaca: your irc client doing something funny?

2:20 cmvkk: you're just using a weird charset. i've seen that behavior on webpages before

2:20 replaca: Yeah, in some configs

2:20 hiredman: hmmm

2:21 cmvkk: it's really obvious when 's gets changed, because it's so common

2:21 replaca: yeah, when you're typing in spanish, that's a feature not a bug

2:22 cause they don't really use apostrophes

2:22 but they use *tons* of accents

2:22 * hiredman munges with gnome's keyboard dingus

2:23 replaca: do you get the right chars over the numbers (!@#$%^&*...)?

2:28 cmvkk: what's your IRC client?

2:33 pstickne: oh, I'm dumb -- my problem with ident was I was re-declaring it later :(

3:36 Raynes: (apply str (reverse (reverse (reverse (reverse (reverse (reverse (reverse (reverse (reverse (reverse (reverse (reverse "Hello, World!"))))))))))))))) ; We can safely say that this poor string has been through hell!

7:34 rhickey: cgrand: looks like there's a typo in your patch: Unable to resolve symbol: righmost in this context

8:16 tbb: hi guys

8:16 is there anybody here familiar with compojure?

8:17 i'm having some trouble posting (POST) some xml and retrieving it again from the 'params' map

8:17 theres an & in the xml and it becomes a separate key in the map

8:30 maacl: tbb: where does it occur in the xml ? &amp is a entity reference in xml

8:32 tbb: hi maacl

8:32 xml is

8:32 "<action action_name='defn' application='clojurep' project=''><attribute name='function' data=''/><attribute name='arglists' data='([&amp; m])'/><attribute name='file' data=''/></action>"

8:32 post message becomes:

8:33 "action=<action action_name='defn' application='clojurep' project=''><attribute name='function' data=''/><attribute name='arglists' data='([&amp; m])'/><attribute name='file' data=''/></action>"

8:33 compojure map;

8:34 something like this:

8:34 {:action "<action action_name='defn' application='clojurep' project='nl.tbb.clojurep'><attribute name='function' data='testcljp'/><attribute name='arglists' data='([", :amp; x])'/><attribute name "'file' data='NO_SOURCE_FILE'/></action>"}

8:34 with an :action key and a :map key

8:34 i mean an :amp; key :)

8:36 i'm now trying to get the content directly from the request, that should be a solution

8:44 maacl: :tbb looks like an error - does it really change m to x ?

8:47 tbb: oh no, sorry, i pasted the wrong map

8:47 but the &amp; becoming a key is the problem

8:47 cgrand: rhickey: sorry :-( I shouldn't have rushed this patch before lunch (and copy/pasted the typo from the REPL).

8:49 rhickey: cgrand: is it ok wit hthe typo fixed? I fixed here but don't have test cases

8:49 ready to check in

8:49 maacl: hm, wonder what compojure uses to parse the xml

8:53 tbb: i guess the xml syntax is messing up the getParameters function of jetty

8:54 i'm going the (.getReader request) way :)

8:54 thanks though :)

8:59 cgrand: rhickey: it's ok

8:59 jsankey: rhickey: is there an existing test suite for zip? as mentioned on the group i'd be happy to contribute cases for this if you like.

9:00 rhickey: jsankey: I'm not sure if there are tests for zip in contrib yet

9:00 * cgrand appends writing tests for proxy and zip to his todo list

9:00 rhickey: you'll need a CA to contribute tests

9:01 jsankey: rhickey: i've been poking around and don't see any yet

9:01 i see, a CA is no problem

9:02 the acceptability of my clojure code might be atm, though ;)

9:40 AWizzArd: rhickey: would it be difficult to add unchecked versions of <, >, <= and >=?

9:43 cgrand: rhickey: (pure curiosity) is it still necessary for the one-shot closures in LazySeqs to perform closed-over clearing or is this a remnant from when LazySeqs were functions?

9:44 Drakeson: is there an `indexed' function as in: (for [[x y] (indexed (range 5 10))] [x y]) ?

9:45 Chousuke: I think there is one in contrib

9:45 but I'm not sure. :/

9:45 AWizzArd: in clojure-contrib.seq-utils

9:46 (indexed (range 5 10)) ==> ([0 5] [1 6] [2 7] [3 8] [4 9])

9:46 Drakeson: AWizzArd: oh, thanks

9:51 rhickey: cgrand: Nope

9:51 AWizzArd: what's not to check? No overflow possible. Do you just want inlining?

9:54 AWizzArd: rhickey: yes, nothing to check, but it could generate bytecode that uses the primitive Java < and >?

9:56 rhickey: AWizzArd: that already happens

9:57 jsankey: rhickey: thanks for the super-fast patch to zip!

9:57 rhickey: jsankey: thanks to cgrand

9:57 jsankey: indeed

9:58 AWizzArd: good

9:58 jsankey: rhickey: another question: would you be interested in me setting up a ci server to build/test clojure and contrib on every change?

9:58 rhickey: AWizzArd: you only need unchecked- when you want bad/wrapping ops

9:59 jsankey: sounds neat

10:00 jsankey: fyi it would be using my company's commercial ci product, but there are no strings and i won't try to sell anyone anything :)

10:00 Chouser: isn't there one of those already?

10:01 http://groups.google.com/group/clojure/browse_thread/thread/5f5f63bb0ac6dbd/876a18070bc65f40

10:01 rhickey: http://tapestry.formos.com/bamboo/browse/CLJ

10:02 jsankey: fair enough, looks like it has been done

10:02 rhickey: says no tests found, though

10:02 so probably only verifying buildability

10:02 jsankey: i guess they don't know how to read the test results

10:03 Chouser: there was talk of one fro contrib as well, but I don't see it.

10:03 jsankey: well, the offer is there: i can set up one for clojure and contrib if you desire

10:04 with a bit of extra work i could add a plugin to read the test results (not sure what format they come in?)

10:04 Chousuke: I think it just prints stuff to stdout.

10:05 jsankey: ok - if it's matchable with regexes i might not even need a plugin

10:05 Chousuke: or does the contrib test suite support custom formatters?

10:05 Chouser: jsankey: test for clojure are in clojure.contrib.test-clojure

10:06 rhickey: cgrand: I take that back - clearing closed-overs is needed so they are not held while closure runs its tail call

10:06 jsankey: i'll give it a run and see what it shouts at me

10:06 Chouser: jsankey: that's the place to try what already exists, and also where to add tests for the zip change if you care to.

10:07 jsankey: if you do write something to go into contrib or clojure itself, please take a look at http://clojure.org/contributing

10:07 rhickey: hrm, shouldn't Clojure testing libs produce read-able data?

10:08 jsankey: Chouser: thanks, i have printed out a CA already

10:08 AWizzArd: btw, are the issues of clojure-contrib often checked?

10:08 cgrand: rhickey: ok thanks

10:08 Chouser: jsankey: and thanks for digging up the zip bug

10:08 jsankey: hey, np

10:09 Chousuke: ah, hm

10:10 Chouser: clojure.contrib.test-is/test-ns returns a map of the test counters

10:10 Chousuke: reading test-is documentation, it seems to support customised output by rebinding the "report" function

10:10 jsankey: it's pretty terse by default

10:11 Holcxjo: If (compare [1 2] [1 2]) works why doesn't (compare '(1 2) '(1 1)) work as well?

10:11 And if (compare [1 2] [1 2]) works, why doesn't (< [1 2] [1 2]) work?

10:11 Chouser: looks like you can do (test-ns (all-ns)) and get a seq of test result maps, one for each namespace.

10:12 rhickey: cmvkk: still here?

10:13 jsankey: Chouser: ah, ok. i should be able to pretty easily emit it as xml and then suck it into the ci server

10:17 Chouser: as of last night I have a function that finds the smallest set of methods from among all currently imported classes that match a given unhinted or partially-hinted method invocation form.

10:18 rhickey: Chouser: cool!

10:19 Chouser: yeah, I'm excited to use it. too bad there's so much more analyze and emit between now and getting to use it.

10:19 rhickey: apropos this thread: http://groups.google.com/group/clojure/browse_frm/thread/2590ee3c75c04e91/6d34e274fe0c5e5d

10:19 ?

10:19 Chouser: yes, at least as I understand that thread, which of course could be faulty.

10:20 so (.compareTo x y) where neither are hinted finds a dozen or more methods. But hint either x or y as Enum, and only one method matches -- no runtime reflection needed.

10:20 rhickey: very neat - I'm imagining that is would be efficient enough to generate multiple paths when the number of possibilities is less than maybe 4

10:21 Chouser: ok, I was thinking there might be a threshhold like that.

10:21 *warn-on-reflection* can report how many are found if it's more than 1

10:22 rhickey: could be even more if classes are final

10:23 Chouser: if we want to emit the minimum number of 'instance?' checks at runtime to correctly choose among the matching methods, a bit more clever logic will be needed.

10:31 dnolen: and idea: what about allowing people to provide a function in the metadata of a map to be run if a key is not found? this would work around some of the current limitations that you cannot add metadata to functions themselves.

10:33 rhickey: dnolen: I don't see how the two are related

10:33 AWizzArd: So, is there some preparation for type-inference and/or optional static type checking (such as Gradual Typing)?

10:34 rhickey: AWizzArd: we're skipping right to automated program correctness checking - will make sure the program does what the customer wants and will make money

10:34 ;)

10:34 Chousuke: oh, that would be fun, wouldn't it.

10:35 rhickey: why fool around, I say

10:35 AWizzArd: sure, we will get there one day

10:35 Chousuke: (assert (makes-money? code))

10:35 rhickey: there you go

10:35 the fact that that is funny implies something

10:37 Chouser: it implies that programmers have a reason to exist

10:37 vdrab: makes-money can be a lazy stream

10:37 Chousuke: then you should name it "income" :/

10:38 rhickey: Chouser: ha! I guess so

10:39 vdrab: I think makes-money is a delay, or a future, in any case it's blocking

10:39 Chouser: I had prof in college that would frequently address the fear that eventually computers would program themselves. Perhaps others had such a fear, but I've never bought it.

10:40 duck1123: when makes-money doesn't return anything, it stops everything

10:41 vdrab: rhickey: it implements the interface "conj" for "conjure"

10:41 * rhickey is still waiting for (makes-money clojure) to return

10:41 p_l: Chouser: the problem is not whether they will learn to program themselves, but whether they won't turn universe into Office Paperclip

10:42 Chousuke: Chouser: perhaps computers can program themselves, the self-programming algorithm require maintenance.

10:42 algorithms*

10:42 also, +but

10:42 vdrab: rhickey: maybe you should have used agents

10:43 Chouser: Chousuke: yes, that was my prof's assertion as well.

10:44 p_l: Chouser: except that there's nothing that stops them from self-maintenance

10:44 Chousuke: though it might be that we invent a true AI at some point.

10:45 and if it were smarter than us, then it could program itself to be even smarter :P

10:46 p_l: and if we did it wrong, it might model the universe based on MS Bob

10:46 Chousuke: then it'd just give up and destroy itself.

10:46 Chouser: rhickey: how is (makes-happy clojure) doing though?

10:47 rhickey: Chouser: pretty well

10:47 p_l: Chousuke: No, it would optimize forever to get to that goal

10:48 duck1123: http://www.xkcd.com/534/

10:49 rhickey: working on my slides for ILC - any requests?

10:49 jsankey: ok, i have a start: http://pulse.zutubi.com/browse/

10:50 it builds clojure and clojure.contrib

10:50 both are triggered on code changes, the latter also on successful builds of the former

10:50 the contrib project uses the latest jar from the main project

10:51 the tests are run in contrib, but i need to do more work to get them to turn up in the ui

10:51 dnolen: rhickey: actually you're right. sorry, I'm trying to figure out a way return a fn where elsewhere I want to know something about this fn (but can't because I need metadata about it). Keeping a reference to this fn is not viable because it is temporary and there will be a lot of them.

10:51 is there a good way to fake metadata on fns that I'm just not considering?

10:51 AWizzArd: So, is there no serious interest in (completely optional but fully functional) static/gradual typing?

10:52 jsankey: if you like, you can hit the login link in the top right corner, and the signup link to get an account

10:53 with an account you can subscribe to email notifications

10:53 Chouser: dnolen: I think there are a couple somewhat hacky options.

10:53 dnolen: Chouser: I'm all ears if it can be done without creating a Java class ;)

10:54 Chouser: dnolen: you could have the function take an unusual number of args to return the "metadata"

10:54 stuhood: rhickey: request: don't make them feel too ashamed of their implementations =)

10:54 Chouser: dnolen: (fn ([x] ..normal code..) ([_ _ _ _ _ _] {:some :metadata}))

10:54 dnolen: Chouser: unfortunately this is for the cl-cont port, so using the number of args isn't doable :(

10:55 Chouser: what's cl-cont?

10:55 dnolen: delimited continuations for common lisp, I'm porting it Clojure.

10:55 rhickey: didn't we recently talk about proxy AFn - then you can pass metadata to ctor

10:56 dnolen: rhickey: ooh, is this a thread I missed on the list?

10:57 AWizzArd: rhickey: btw, I think the money-making part with Clojure is just a question for time. I think first Clojure users will profit, and with some delay, you.

11:01 rhickey: dnolen: was here on IRC but I can't find it

11:02 dnolen: rhickey: thx for looking, will give a shot at figuring it from the docs, don't mean to distract from slide work.

11:03 cgrand: dnolen: http://clojure-log.n01se.net/date/2009-02-20.html#11:18a

11:04 rhickey: user=> (def f (proxy [clojure.lang.AFn] [{:my :meta}] (invoke [] 42)))

11:04 #'user/f

11:04 user=> (f)

11:04 42

11:04 user=> ^f

11:04 {:my :meta}

11:04 dnolen: fantastic thanks!

11:07 Chouser: (def f (clojure.lang.Var/create (fn ([x] (inc x)) ([x y] (+ x y)))))

11:07 (f 4) ==> 5

11:07 (f 10 5) ==> 15

11:07 (alter-meta! f assoc :foo :bar) ==> {:foo :bar, :ns nil, :name nil}

11:08 rhickey: Chouser: hrm - breaks fns as values, since vars aren't values

11:08 Chouser: I just hope I'm not idicted for var-abuse

11:08 rhickey: guilty!

11:08 I'd rather see with-meta throw than see that

11:09 is after-the-fact with-meta needed for most fns when people say they want fn metadata? if not, supporting meta on construction is pretty easy

11:10 Chouser: I see, because I'm mutating to get new metadata, or to change the fn inside. :-/

11:13 brianh2: rhickey: hopefully the (makes-money clojure) has at least supplied you with enough caffeine (or stimulant of choice) to see this thing through...???

11:19 rhickey: Chouser: have you got a DOT file for your Clojure chart?

11:19 Chouser: yes, but I think they're all missing future.

11:20 rhickey: it might help me with my slides

11:20 rather than recreate in OmniGraffle

11:20 Chouser: http://github.com/Chouser/clojure-classes/blob/d79f20fbd3b5bddbee0520afb7b3871953e949c8/graph.dot

11:21 that's the dot file, but I can run a new one to make sure it's up to date

11:21 you'll be adjusting it in omnigraffle?

11:22 rhickey: probably just using subsets of it - it's huge

11:23 Chouser: yeah

11:24 let me run you a new one with future and with LazySeq not extending AFn

11:25 rhickey: ok

11:25 OmniGraffle pulls it in fine - cool

11:27 Chouser: updated .dot: http://github.com/Chouser/clojure-classes/blob/master/graph.dot

11:28 rhickey: ooh, and it lets me do ancestors/descendants selection

11:28 Chouser: thanks!

11:29 Chouser: you're quite welcome.

11:47 karmazilla: little experiment with code readability: http://github.com/karmazilla/literate-clojure neat or horrible?

11:53 rsynnott: karmazilla: whatver about the syntax itself (I don't really see the point), you spelled 'literally' wrong :)

11:53 karmazilla: toss! I knew I should have looked it up

11:55 Chouser: I haven't found the arguments for using things before they're defined to be particularly compelling, so I'm not your target audience.

11:57 karmazilla: Uncle Bob notes in passing in Clean Code that Logo uses TO to define functions and that it has an interesting effect on how functions are defined and named, and I wanted to explore that a bit

11:58 but the example may be too contrived to judge

12:11 replaca: karmazilla: I would claim that this isn't really "literate programming" in the accepted definition of creating something that can be part of a document as well as being a program.

12:13 karmazilla: I know I'm taking a pretty big liberty in using that word :)

12:14 duck1123: should I be copying clojure-slim.jar into my project as well?

12:15 I've been spending the day setting up an ant script to compile and set up everything I need

12:15 karmazilla: It picked it on a whim thinking that the webbing might be introduced later if I cared

12:19 rhickey: Chouser: question on the chart - would it be possible to get one without the [legends] and with those classes in (IMeta, Counted etc) the mix?

12:20 Chouser: yes

12:20 rhickey: thanks, since I'm subsetting I can handle those

12:21 Chouser: ok. no [badges] at all?

12:21 rhickey: right

12:23 lisppaste8: Chouser pasted "graph-nobadge.dot" at http://paste.lisp.org/display/77275

12:25 Chouser: I can leave out predicates or add in ctor fns too, if you want.

12:29 rhickey: thanks - that one crashes OmniGraffle: *** -[NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: badges)

12:30 could be on their side

12:30 Chouser: oh. well...

12:34 lisppaste8: Chouser pasted "graph-nobadge2.dot" at http://paste.lisp.org/display/77276

12:35 rhickey: Chouser: fantastic - thanks again!

12:41 Chouser: can a Java class have to methods that differ only in their return value?

12:41 two

12:41 jsankey: Chouser: return type? no.

12:41 Chouser: sorry "type", yes. ok.

12:49 but a derived class can override a method that is the same in every way except a derived return type.

12:50 pjstadig: a subclass can change the return type of a method as long as the new return type is a subclass of the old return type

12:52 Chouser: yes, ok. but .getMethods will show both

12:56 karmazilla: will it only show one if the return type were the same?

12:58 Chouser: yes, apparently. Or if the derived class specifies a superclass return type.

12:59 jsankey: covariant returns are only supported in java 5 onwards (if it matters)

13:00 Chouser: clojure only supports 5 onward, so I don't need to look up "covariant" again.

13:00 * Chouser sighs and does it anyway

13:00 jsankey: and afaik you can't do contravariant (return a supertype) at all

13:02 rhickey: jsankey: contravariance is usually only for args

13:02 jsankey: yes, indeed

13:03 covariant returns, contravariant args, but not the other way around

13:08 marklar: I'm trying to port a java game to Clojure, and am running into a problem with a class that handles the drawing surface. In Java, the constructor registers the class to handle the callbacks for the drawing surface. I'm at a loss since there is no 'this' to reference in the :init function. How could I handle this?

13:09 Chouser: marklar: issue and patch for :post-init here: http://code.google.com/p/clojure/issues/detail?id=45

13:09 marklar: Chouser: ah, thanks

13:10 that looks perfect, thanks again

13:10 Chouser: but without that you could still provide a function that everyone promises to use to construct your class

13:11 that fn would do the (new MyClass) and then do any post-init work

13:12 marklar: Chouser: I think I will look at the patch, since there are several different classes that will run into this problem

13:12 Chouser: It's also possible that rather than gen-class and (new MyClass) you might be able to get away with just proxy, which doesn't require an AOT step.

13:12 marklar: Its android, so AOT only afaik

13:12 Chouser: oh ok

13:12 marklar: Chouser: Thanks again!

13:12 Chouser: np

13:20 triddell: marklar: just curious, how is clojure working/performing for you on Android? I'm thinking about diving into Android myself and was wondering whether I should use clojure or just stick to java.

13:21 marklar: is the fork of clojure still required? is was when I first looked into it.

13:23 Raynes: As far as I know Clojure is fine on Android, I hear a lot of people talking about it.

13:24 Chouser: I assume you still have to comment out 'bean'?

13:26 triddell: There is a fork at: http://github.com/remvee/clojure/tree/master which seems to stay current with the necessary android mods

13:30 Raynes: What is so hip about Android ._. I want it.

14:16 Lau_of_DK: Hey guys

14:16 durka42: hi lau

14:16 blbrown_lt: what is up homie

14:20 ozzilee: I'm having trouble trying to get a Compojure app to run on Tomcat. I think I've got Tomcat set up correctly (5.5, on Debian), I deployed the war, but trying to pull up the app I only get a 404.

14:21 I copied the instructions at wikibooks exactly: http://en.wikibooks.org/wiki/Compojure/Getting_Started

14:21 Anybody else get that example to run?

14:21 Lau_of_DK: ozzilee, The hardest thing I've found about compojure, is that no-one ever answer my questions regarding it. I suggest your scour the wik/group :)

14:22 ozzilee: Lau_of_DK: Heh, bugger. I'll commence searching...

14:22 Chouser: asking on the compojure google group may be your best bet

14:23 Lau_of_DK: oh right, why didnt I think of that...

14:23 ozzilee: Yeah, I'll give that a shot if I can't find anything.

14:30 danlarkin: see... if you were using madison you'd have me to answer your questions!

14:32 Lau_of_DK: danlarkin, how DO you get Madison Square Clabango up and running om a Tomcat 5.5 ?

14:32 danlarkin: ummmm proxy it to jetty

14:33 stuhood: lol

14:33 rsynnott: what is clabango, exactly?

14:34 Chouser: ~eveyone wanted another web framework, and suddenly

14:34 clojurebot: CLABANGO!

14:34 Chouser: ~clabango

14:34 clojurebot: http://www.clabango.com/

14:35 rsynnott: I saw that site

14:36 it's rather unhelpful :)

14:36 but yes, web framework

14:36 yay!

14:36 can never have too many

14:36 Chouser: http://github.com/danlarkin/madison/tree/master

14:37 danlarkin: progress coming, I promise! been busy IRL lately

14:38 rsynnott: hmm, is it run inside a web server, or does it run its own?

14:38 * rsynnott is currently playing with using clojure as a backend for the jetty comet stuff

14:39 danlarkin: madison? it uses ring, which uses jetty

14:39 Lau_of_DK: clojurebot clabango is http://github.com/danlarkin/madison/tree/master

14:40 clojurebot: clabango is http://github.com/danlarkin/madison/tree/master

14:40 clojurebot: Roger.

14:40 Lau_of_DK: noob

14:40 ...

14:40 danlarkin: but I think the idea for ring is that it should support other containers.. or whatever they're called

14:40 rsynnott: ah, NOW you're in trouble

14:41 ah, cool

14:42 why's it called madison and/or clabango?

14:42 (the art of library naming was one I never aquired)

14:42 Lau_of_DK: hehe

14:42 Allow me to explain

14:43 Danlarkin had this cool project going, but he didnt have a name, it was a port of Django so I suggested Clabango - Dan wasnt happy, so he postponed the upload for something like 2 months, because he didnt have a name for it

14:43 So I started telling everybody that it was called Clabango, and that it was coming right up (you know, just to put the pressure on him)

14:43 Then he finally names it Madison - uploads it, and hides for a few days

14:44 danlarkin: hahah

14:44 Lau_of_DK: During those few days, I constantly refer to the project as Madison Square Clabango

14:44 And its really catchy, so people pick it up and start thinking that its the name for the project.

14:44 So thats the story of Clabango... :)

14:44 * danlarkin claps

14:45 rsynnott: ah :)

14:46 kotarak: ~and suddenly...

14:46 clojurebot: CLABANGO!

14:46 rsynnott: what, precisely, are us cl people supposed to call our potential django clone, then?

14:46 :)

14:46 Lau_of_DK: ... Madison Square Clabango ofc

14:46 p_l: rsynnott: COMMON-LISP-BANGO

14:47 rsynnott: COCOJAMBO sounds nice too ;-)

14:47 Lau_of_DK: COCACABANGO

14:48 p_l: another nice name would GTFO to comply with LOL/LMAO/ROFL/WTF/FTW combo

14:48 *would be

14:48 Lau_of_DK: But dan, consider this, night after night, we sit here joking about Clabango - GRAB THE NAME!!

14:48 danlarkin: haha

14:48 but it's not a good name!

14:48 Lau_of_DK: Its the BEST name

14:49 triddell: danlarkin: to complete the story... why Madison?

14:50 rsynnott: no, COCACABANGO would be a terrifying ObjC django clone

14:50 stuhood: hahaha

14:50 p_l: rsynnott: ... I think I just hit the nail on how full package of Lisp-on-lines and related stuff should be called. ``/b/''

14:50 danlarkin: why madison? I suppose it just sounded nice to me

14:51 triddell: COCACABANGO needs a Barry Manilow theme song

14:51 rsynnott: fortunately, nobody has ever used lisp-on-lines

14:51 Lau_of_DK: What is lisp-on-lines?

14:51 rsynnott: is was created just to annoy the the reddit people

14:51 well, exactly

14:51 pseudo-ruby-on-rails library for common lisp, never used for anything

14:51 triddell: danlarkin: ok, cool... didn't know if you were from there... had a child named that, etc.

14:52 Lau_of_DK: ~sofiaba?

14:52 clojurebot: sofiaba is http://wiki.github.com/Lau-of-DK/sofiaba

14:52 Lau_of_DK: triddell, Thats named after a child :)

14:52 p_l: rsynnott: well, wasn't it actually in production for few years, except never released? :D

14:52 kotarak: "Oh Mandy, you gave without taking..."

14:53 triddell: Lau_of_DK: saw that one day here... very nice

14:53 Lau_of_DK: are you an Ubuntu user?

14:53 Lau_of_DK: yea

14:54 Not by free choice, its company policy, and Arch lacked the drivers for my new laptop :(

14:55 triddell: check this out: http://riddell.us/tutorial/slime_swank/slime_swank.html ... two other tutorials are linked to in the top section... I thought I might also add a tutorial for Git/Egg in the future.

14:55 p_l: Lau_of_DK: anyway, the author had a lot of fun with names. Lisp-on-Lines, Relational-Objects-For-Lisp, I don't remember what MAO standed for, Working-Test-Framework, FTW was the name for proposed package manager for cl libraries...

14:55 Lau_of_DK: ah ok

14:55 triddell, Git/Egg is phat

14:57 triddell: Lau_of_DK: yep, I'm liking it as well... any other emacs goodies you use frequently? I used muse to author those tutorials and I've also checked out the emacs-android stuff which I might write up

14:58 Lau_of_DK: triddell, Org-Mode, Egg, Clojure-mode, jfly-2, dabbrev-expand and yasnippit2 will get you along ways :)

14:59 triddell: Lau_of_DK: I've done a bit with org-mode... thx for the tips on the others

15:00 Lau_of_DK: no probs :)

15:14 jhawk28: Clabango is a catchy name, but not sure I could sell it as a serious framework to my management

15:14 Chouser: MSC (TM)

15:14 jhawk28: MSC maybe

15:14 sort of like Apache POI

15:15 and HSSF

15:15 cmvkk: do closures close over locals that they don't refer to?

15:16 rhickey: cmvkk: no

15:16 cmvkk: thanks.

15:17 replaca: Lau_of_DK: Egg is superior to magit? I've been holding off really learning an emacs interface to git, but I need to pick one and learn it.

15:17 rhickey: cmvkk: to your question last night about lazy-seqs and threads - they are completely safe for simultaneous access from multiple threads, all of which will see the same thing, and the generating fns will be called only once per node

15:18 cmvkk: thanks. that should be very helpful

15:18 Lau_of_DK: replaca, Yes, Egg is a fork of magit, and on top of that fork Bololisk has built a very nice UI - so the UI is the major difference

15:18 Sidenote: He's very quick to get back to you if you mail him with questions/suggestions

15:19 replaca: Lau_of_DK: Thanks! Is the UI conatined in the egg package itself or separate?

15:25 pjstadig: danlarkin: if you're not using the clabango name because you want the website, i'll give it to you

15:25 it's really too cool of a name to lay unused

15:25 danlarkin: why not make clabango the flagship app using madison

15:26 pjstadig: i'll have to do something with the site (and name if you don't)

15:26 maybe i'll come up with an idea and it'll be the name of my startup

15:26 jhawk28: does it have an admin interface yet?

15:27 danlarkin: jhawk28: no

15:38 Chouser: (.foo x) when x is unhinted could be meant to refer to either an instance field or an instance method

15:39 rhickey: public instance fields are pretty rare

15:39 Chouser: currently it's always analyzed as a InstanceFieldExpr, but at runtime will use reflection and may discover it's a method, and call that.

15:41 with this new analysis code, it can discover at compile time that the only member named foo in any imported class is a field

15:41 danlarkin: oooooo

15:42 Chouser: danlarkin: don't get too excited, there's a long way to go before this can be used. :-)

15:42 anyway, to allow this, I've got all instance-like exprs running through the same code path

15:43 rhickey: you'll never be able to elide the slow path in case the type you've inferred isn't what you got

15:44 Raynes: rhickey: You should grow a beard. :)

15:44 Chouser: but that means that (. x (foo)) may be analyzed as an instance field. Is that unacceptible?

15:44 durka42: what if i haven't imported (class x)?

15:44 rhickey: Raynes: unlikely

15:45 Raynes: History says you'll be totally successful if you do, but you're doing a damn good job at that already :D

15:45 rhickey: Chouser: hmm, that's the one way to force the issue when you've got both and want the method

15:46 Chouser: rhickey: hm, good point about keeping the slow path. Does that mean I still need to note exact (as opposed to unambiguous) matched methods?

15:46 rhickey: but if public fields are rare, public field and method of same name are rarer

15:46 not sure what you mean exact vs unambiguous

15:47 Chouser: just had an idea for threading a must-be-method indicator through -- might not be as bad as I was thinking.

15:47 dnolen: curious in the future will Clojure support Common Lisp control structures like go, tagbody, block, return-from etc?

15:48 in fact is there any way to exit a fn early?

15:48 Chouser: exact meaning I don't need a slow path emitted, vs. unambiguously finding a single auto-hinted solution that matches but still requires a slow-path just in case.

15:48 dnolen: throw or something built on throw

15:49 rhickey: Chouser: how could you not emit a slow path - duck typing is still possible

15:49 dnolen: Chouser: throw is slow tho right? so not something you generally want to use?

15:49 Chouser: rhickey: (.length #^String s) <-- exact match, so no slow path needed?

15:50 WizardofWestmarc: man, be away for a few days and find out DanLarkin released his framework and I missed it >(

15:50 rhickey: dnolen: no way to exit early, structured programming only, and yes, exceptions for normal flow control considered bad

15:50 Chouser: oh, that's hinted, so not inferred at all

15:50 Chouser: vs. (.readLine x) where java.io.BufferedReader has the only match, but still need slow path.

15:51 dnolen: rhickey: thx, a lot of things I don't have to worry about then.

15:51 rhickey: Chouser: I was only talking about cases where you are guessing the type based on imports

15:52 Chouser: You seem to be skipping ahead a bit if you are up to this already - one thing to think about is something I had early on, which was inference flowing both ways - not only what types could be generated by the caller, but what were desired by the receiver

15:53 Chouser: (.compareTo x #^Enum y) will guess exactly one fast-path but require a slow path as well. (.compareTo #^Enum x y) doesn't require slow path? Or do I need (.compareTo #^Enum x #^Enum y) to avoid slow path.

15:54 rhickey: slow path is strictly about guessing type of 'this'

15:54 If you are told, no guess

15:55 Chouser: yeah, I may be getting ahead of myself, but I needed getMatchingParams and realized there were plans to change related behavior so off I went...

15:56 rhickey: it will be hard to validate the new compiler if it has new semantics as well, maybe better to wait until after parity with current is achieved and we switch over

15:58 Chouser: that's what user codebase is for!

15:58 rhickey: I have ideas about emitting a specifically-typed invoke in addition to the object one, metadata will let the compiler see it and use if it has matching args. This will allow for fast fns taking primitives

15:59 (defn #^float foo [#^float x #^float y] ...) yields float invoke(float,float) as well as Object invoke(Object, Object)

16:00 Chouser: does that have implications for re-def'ing foo?

16:00 rhickey: yes

16:00 so would changing arity though

16:01 pjstadig: Chouser: what are you working on?

16:01 Raynes: He's working on the Chouserbot of death.

16:02 Chouser: pjstadig: playing at rewriting Compiler.java in clojure.

16:02 pjstadig: ah

16:02 i thought that might be it

16:02 sweet!

16:02 Chouser: it's a fantastic learning exercise, and it eventually gets used for something, all the better. :-)

16:03 s/and/and if/

16:07 tossing this guessing code and replacing it with a more rote translation of the .java is unappealing.

16:10 StartsWithK: what would be a best way to do a deep merge on maps? {:a {:b 1}} {:a {:c 2}} -> {:a {:b 1 :c2}}

16:12 WizardofWestmarc: StartsWithK: merge-with not do what you need?

16:12 haven't tried it for deep ones so not sure

16:12 StartsWithK: WizardofWestmarc: no, if :a exists in bot maps it will use only value of second map

16:13 so you'll get {:a {:c 2}}

16:13 WizardofWestmarc: ah ha

16:13 right

16:13 cmvkk: (merge-with merge ...) would do it for one layer i think

16:13 for two layers: merge-with merge-with merge

16:13 maybe?

16:14 ,(merge-with merge {:a {:b 1}} {:a {:c 2}})

16:14 clojurebot: java.lang.NoClassDefFoundError: clojure/core$merge_with__3866$merge_entry__3868

16:14 StartsWithK: for two layes i do destructuring on keys (works ok for know keys) and then merge submaps

16:14 cmvkk: what's wrong with clojurebot?

16:14 StartsWithK: cmvkk: thanks, that works for one level

16:15 i don't need deeper than that

16:15 but it would be nice if something like that would exist

16:15 cconstantine: Is there a method like (some) that returns the position in the sequence instead of the element?

16:16 StartsWithK: cconstantine: (first (filter ...))

16:16 cmvkk: that won't return the position though

16:16 cconstantine: StartsWithK: will the (rest (first (filter ...))) have the filter applied?

16:17 StartsWithK: cconstantine: only to coll given to filter

16:18 * WizardofWestmarc waits for clojurebox to dl so he has it on his new work laptop.

16:18 cmvkk: (rest (first (filter ...))) is probably not what you want.

16:18 WizardofWestmarc: can't believe I forgot to install clojure until now

16:19 cconstantine: I don't want the filter after I've found the location that matches my constraints

16:19 cmvkk: are you saying you want the index of the first item that matches your predicate?

16:19 cconstantine: (first (filter ...)) appears to be the same as (some ...)

16:20 cmvkk: I want the sequence object that contains the element that matched my predicate

16:20 the sequence object who's (first ...) matched the predicate

16:20 Chouser: (defn deepmerge [f & ms] (apply (fn m [& ms] (apply merge-with (if (every? map? ms) m f) ms)) ms))

16:20 Victorr: hi, is there a Clojure irc bot yet?

16:20 Chouser: ,(println "nope")

16:20 clojurebot: nope

16:20 pjstadig: clojurebot: introduce yourself

16:20 clojurebot: Huh?

16:20 pjstadig: bah

16:21 Victorr: ,help

16:21 clojurebot: java.lang.Exception: Unable to resolve symbol: help in this context

16:21 Victorr: :-)

16:21 ,(help)

16:21 clojurebot: java.lang.Exception: Unable to resolve symbol: help in this context

16:21 kotarak: ,(doc doc)

16:21 clojurebot: "([name]); Prints documentation for a var or special form given its name"

16:21 cconstantine: Chouser: was that for me?

16:21 cmvkk: oh i see constantine, you want to drop elements from a seq until you get to one that matches your predicate.

16:22 cconstantine: cmvkk: yes :)

16:22 kotarak: (drop-while (comp pred) the-seq)

16:22 StartsWithK: Chouser: dosn't work for all combinations

16:22 (deepmerge {:a {:b {:c 1 :d 2} :e 3} :f 4} {:a {:b {:z 3 :c 2}}})

16:22 Chouser: cconstantine: no, that was for StartsWithK

16:22 cconstantine: this is for you:

16:22 cmvkk: wow

16:22 Chouser: (some #(and (= (first %) 'd) %) (iterate next '(a b c d e f)))

16:22 StartsWithK: {:a {:b {:z 3, :c 2}}}, no :d

16:22 cmvkk: kotarak, i was about to say i didn't think there was a builtin that could do that...

16:23 there's builtins for everything

16:23 Chouser: kotarak: nice

16:23 kotarak: uh? Or was it complement?

16:23 (doc complement)

16:24 clojurebot: Takes a fn f and returns a fn that takes the same arguments as f, has the same effects, if any, and returns the opposite truth value.; arglists ([f])

16:24 cconstantine: Chouser: so that wrapps my sequence in another one and the 'element' returned is the location in sequence I want?

16:24 kotarak: (drop-while (complement pred) the-seq), then

16:24 Chouser: cconstantine: yeah, but listen to kotarak. his is better.

16:25 cmvkk: ,(drop-while (complement number?) [:a :b 1 2 3])

16:25 cconstantine: Chouser: hehe, ok :)

16:25 clojurebot: java.lang.NoClassDefFoundError: clojure/core$drop_while__3810$step__3812

16:25 * kotarak bows, but that thinks that Chouser is the guru here. Not kotarak. :)

16:25 cmvkk: clojurebot is choking on all of my input today

16:25 * kotarak spotted a broken clojure.jar.

16:26 cconstantine: kotarak: so, is (complement pred) called when iterating through the result of that drop-while?

16:26 cmvkk: (complement pred) is called on each element of the input seq.

16:27 kotarak: cconstantine: (complement pred) returns a function, which is - well - the complement of the pred. This functions is applied to the elements of the sequence.

16:27 cconstantine: I think I just need to test this with a (println)

16:27 kotarak: cconstantine: *meeep* !!! PROBLEM AHEAD !!!. drop-while is lazy. So take care to use dorun or doall to force the sequence.

16:27 cconstantine: or, rephrased: is 'pred' called after drop-while finds the first element to return?

16:28 kotarak: cconstantine: pred is called to find the first element to return.

16:28 cconstantine: kotarak: ah, but the sequence is infinite :)

16:28 cmvkk: better make sure something in it matches your predicate, then...

16:29 cconstantine: cmvkk: I've been playing that kinda game all day :)

16:29 kotarak: cconstantine: well if there is no element satisfying pred..... good luck. :)

16:29 cconstantine: I like living on the edge

16:29 kotarak: cconstantine: cmvkk's example above will return (1 2 3)

16:29 cconstantine: and, when I'm done here I should have a fast prime number generator :)

16:30 kotarak: number? will be called on :a, :b and 1.

16:30 cconstantine: yeah

16:30 Chouser: StartsWithK: (defn deepmerge [f & ms] (apply (fn m [& ms] (if (every? map? ms) (apply merge-with m ms) (apply f ms))) ms))

16:30 (deepmerge + {:a {:b {:c 1 :d 2} :e 3} :f 4} {:a {:b {:z 3 :c 2}}})

16:31 StartsWithK: Chouser: thanks, works, and now.. put in core.clj :)

16:32 * Chouser is happily unable to put things in core.clj

16:32 StartsWithK: maybe seq-utils in contrib?

16:32 i think that one will be needed by someone

16:32 Chouser: more of a map util, isn't it?

16:33 hey look at that -- a map-utils

16:33 StartsWithK: yes, is there such a thing as a map-utils

16:34 for now i didn't need to use contrib after lib was integrated with core

16:35 map-utils :) hehe, you have it all

16:39 what is a criteria for entering contrib?

16:39 write access to repo?

16:39 or lib needs peer review

16:39 kotarak: It should at least be discussed on the list.

16:41 StartsWithK: well, this is personal interest, i have a cell implementation, how did dataflow get in contrib

16:41 kotarak: I think, it had Rich's blessing.

16:41 StartsWithK: i think that was datalog

16:41 Chouser: if you don't have write access to contrib, bring it up on the google group, ask for it to be included in contrib.

16:43 if someone with write access wants it, they'll ask you to make an issue, so then make sure your CA is in and create a contrib issua and attach your code. whoever asked for it should then move it into contrib.

16:43 StartsWithK: i see

16:43 Chouser: or perhaps rhickey will give you write access and then you can do it yourself.

16:44 kotarak: There is a growth of math stuff lately. Maybe this could be more organised? clojure.contrib.math clojure.contrib.complex clojure.contrib.probabilities.dist ....

16:44 StartsWithK: i didn't ask this for libs in general, but as i started new code for neman.cells, i looked what can other three implementations do

16:44 to see what others are doing

16:45 and, dataflow, like neman.cells can't be used for anything at this stage

16:45 so, if i for instance request inclusion of neman.cells in contrib, how will they be judged

16:46 Chouser: There's no set policy on that kind of question, as far as I know. These things just have to be worked out as we proceed.

16:47 StartsWithK: maybe for larger libs (that are not directly aproved by rich) something like boost peer review should be done

16:48 2-3 people to use it in the wild for at least day or two

16:49 Chouser: I assume more formal structure will have to be introduced eventually, but when and what it should look like I have no ida.

16:50 StartsWithK: hmm.. i know, to early for formalisation

16:50 kotarak: Chouser: If clojure.contrib keeps to be advertised as idiomatic Clojure, it should have some form of quality assurance, I think.

16:51 But don't ask me when, how, what, ....

16:51 Chouser: :-)

16:51 StartsWithK: when i first presented neman.cells here, few people asked to be moved to contrib, i sad it needs more work (and it realy needs more work)

16:52 kotarak: And it should have some form of control what goes in. I would hope for some community approval process. But the reactions on the contrib->core survey takes away all illusions....

16:52 StartsWithK: but even then it had more than datalfow, so you see why im confused how something like that entered

16:52 kotarak: StartsWithK: which module is dataflow in?

16:53 StartsWithK: kotarak: ns clojure.contrib.dataflow

16:53 kotarak: Ok. May copy is outdated it seems.

16:54 StartsWithK: im looking with googles svn browser

16:54 Chouser: StartsWithK: there have now been a small handful (2? 3?) cases where a contrib lib and a non-contrib lib could be said to be competitors. Presumably this will happen more in the future, and it does seem desirable to have a good process for resolving that.

16:54 kotarak: One time someone said, he uploaded "an experiment" to contrib....(IIRC) I think that should not be the way to go.

16:55 Chouser: resolving either by including all such competitors that want to be in contrib, merging their features, or something.

16:55 StartsWithK: Chouser: right, don't get me wrong, i don't care if i 'win', thers not much to win, but this in a way looks like artifular monopolly

17:00 Chouser: yes, the appearance of fairness is important

17:00 er, I mean, fairness is important.

17:00 danlarkin: but not fairness itself :)

17:00 walters: heh

17:01 StartsWithK: :)

17:08 Mec: is there a simple way to flatten a list of maps into 1 map?

17:09 StartsWithK: Mec: merge, merge-with, or deepmerge

17:09 Chouser: heh

17:09 StartsWithK: is deepmerge in map-utils :)

17:09 Mec: thanks

17:10 WizardofWestmarc: need to double check but reduce merge-with should work

17:11 Mec: i dont see a deepmerge but merge will work

17:11 apply merge unless merge is a macro

17:11 StartsWithK: <Chouser> StartsWithK: (defn deepmerge [f & ms] (apply (fn m [& ms] (if (every? map? ms) (apply merge-with m ms) (apply f ms))) ms))

17:12 <Chouser> (deepmerge + {:a {:b {:c 1 :d 2} :e 3} :f 4} {:a {:b {:z 3 :c 2}}})

17:12 just created :)

17:13 Chouser: it's called deep-merge-with in contrib.map-utils

17:15 Mec: if a function takes & args, then shouldnt passing a list and passing a bunch of args work the same?

17:15 StartsWithK: no

17:15 Mec: something's not clicking right

17:15 StartsWithK: (apply f '(1 2 3)) if f takes & args

17:16 Mec: ,((fn [& args] args) 1 2 3)

17:16 clojurebot: (1 2 3)

17:16 Mec: ,((fn [& args] args) '(1 2 3))

17:16 clojurebot: ((1 2 3))

17:16 StartsWithK: & args will make args a sequence, so (f '(1 2 3)) will get one argument ((1 2 3)), sequence with one element that is a list sent

17:16 Mec: ah

17:26 Raynes: ((fn [x & args] (reduce + (conj args x))) 3 1 2 3 4)

17:26 ,((fn [x & args] (reduce + (conj args x))) 3 1 2 3 4)

17:26 clojurebot: 13

17:26 Raynes: Always forget that darn comma. :\

17:31 tbb: hi guys

17:32 what would be the preferred way of splitting a namespace into multiple files (:load-resources, load-file, etc.)?

17:38 Lau_of_DK: tbb, I guess that depends on what you prefer - I use (:load "debug") for instance - but not because of careful consideration - it just works :)

17:39 erohtar: is there any way to know what version of clojure is needed for the latest clojure-contrib

17:41 tbb: lau_of_DK, that works great, i was actually looking for something like that :)

17:41 Lau_of_DK: cool

17:41 tbb: fits my asdf way of thinking i guess :)

17:42 kotarak: Lau_of_DK: (:load "foo") is the Right Way. ;)

17:45 WizardofWestmarc: ...I just looked to see what you guys had put on Clabango.com

17:45 Lau_of_DK: haha :)

17:45 Good ol' pjstadig

17:46 erohtar: chouser: u there?

17:46 WizardofWestmarc: here I figured it'd be pointing at http://github.com/danlarkin/madison/tree/master

17:46 Lau_of_DK: ~clabango?

17:46 clojurebot: clabango is http://github.com/danlarkin/madison/tree/master

17:46 WizardofWestmarc: hah

17:47 tonight I may have to download and play with it

17:47 Chouser: erohtar: a bit

17:47 erohtar: chouser: ok - i will try to be brief - how do you keep up with versions of clojure vs clojure-contrib ?

17:48 Chouser: I almost always have the latest clojure and contrib.

17:49 on the rare occasion that clojure has breaking changes, I may hold back updating it and contrib until the things I need from contrib are up to date with clojure, then update both

17:49 erohtar: chouser: is there a quick way to test their compatibility? some tests or something?

17:49 hiredman: clojurebot: latest?

17:49 clojurebot: latest is 1335

17:49 hiredman: hmmm

17:50 Chouser: erohtar: well, there's clojure.contrib.test-contrib, but I can't say I rely on that.

17:50 breaking changes in either clojure or contrib are pretty rare, so most likely if your clojure is up to date you'll be ok.

17:51 if you try to update contrib without clojure, you may have a feature mismatch, so I keep clojure very up to date and contrib nearly so.

17:52 digash: i am off to see Rich at http://semweb.meetup.com/25/calendar/9016252/

17:53 Chouser: cool

17:53 hiredman: :D

17:53 digash: clojure with semantic web, sexpy combination.

17:56 WizardofWestmarc: oh man semantic web and clojure? I REALLY hope that's getting taped, at least audio

18:04 erohtar: im getting this strange error - unable to resolve symbol: frest

18:04 chouser: im getting this strange error - unable to resolve symbol: frest

18:06 Chousuke: it has been renamed

18:06 (doc fnext)

18:06 clojurebot: Same as (first (next x)); arglists ([x])

18:09 Raynes: ,(next [1 2 3])

18:09 clojurebot: (2 3)

18:10 Raynes: Next replaced rest? O.o

18:10 I guess I missed that part of the memo.

18:10 (doc rest)

18:10 clojurebot: Returns a possibly empty seq of the items after the first. Calls seq on its argument.; arglists ([coll])

18:10 kotarak: Raynes: http://clojure.org/lazy

18:11 Raynes: I know about the switch to fully lazy sequences.

18:11 kotarak: Ranyes: rest may now return (), next will still return nil

18:11 Raynes: I noticed.

18:11 :p

18:12 kotarak: Ok. Then I don't understand your remark. Sorry.

18:12 Raynes: No, I mean, I just noticed.

18:12 I was messing with it in my REPL.

18:12 I got confused about which he said was which when I read it.

18:14 danlarkin: WizardofWestmarc: I'm heading out for a bit but I'll be back later on if you have questions about madison

18:14 WizardofWestmarc: danlarkin: \m/

18:14 it'll be a while as I have to get off work first

18:15 the downside to MST, most of the country gets off work before I do ;-)

18:16 danlarkin: it's okay, you get to sleep later :)

18:16 WizardofWestmarc: true

18:16 except for those dirty California hippies <_<

18:17 * bitbckt adjusts his flip-flops

18:29 stuhood: ,(let [intrange (range 0 10000)] (doseq [anint intrange] (+ anint anint)))

18:29 clojurebot: nil

18:29 stuhood: that will "hold onto the head", right?

18:30 because the let is still holding the original seq?

18:30 kotarak: stuhood: I would think so.

18:30 stuhood: ugh... it bit me =(

18:30 kotarak: thanks

18:35 so is the only solution to define the sequence within the doseq?

18:35 or use (recur) instead?

18:38 kiris: is Clojure interpeted by Java or does it compile directly to the JVM (I'm pretty sure it's the latter)

18:38 stuhood: kiris: compiled to JVM bytecode

18:38 kiris: so there's no intermediate Java layer?

18:39 kotarak: no

18:39 kiris: I didn't think so

18:39 slashus2: stuhood: In that code, do you need to hold on to the original sequence?

18:40 stuhood: slashus2: no, i don't

18:41 slashus2: so i suppose i could just define the sequence in the doseq... but i find that binding a few locals cuts down on nesting and makes things easier to read

18:41 slashus2: (doseq [anint (range 0 10000)] (+ anint anint))

18:41 like that?

18:41 stuhood: yea... that would work

18:42 slashus2: Don't really need the zero there.

18:42 stuhood: except that the (range) example is much shorter than the real code

18:43 kotarak: stuhood: you can make a function returning the seq. (let [intseq #(range 10000)] (doseq [anint (intseq)] ...))

18:43 stuhood: hmm, yea... that's an interesting approach

18:44 the bug will still catch people at least once or twice

18:44 slashus2: What is causing the bug?

18:45 kotarak: stuhood: yeah, laziness has its issues, but I don't want to miss it anymore.

18:45 slashus2: It's not really a bug. More a gotcha.

18:45 stuhood: slashus2: the fact that (let) holds onto the head when it is no longer needed

18:47 for instance, if (let) was implemented as a macro, you'd want it to inline the definition of the sequence if it was only being used once

18:55 WizardofWestmarc: later guys

18:56 erohtar: what is the replacement of rrest in the latest clojure?

18:57 kotarak: (doc rnext)

18:57 clojurebot: It's greek to me.

18:57 kotarak: hmmm

18:57 erohtar: ,(doc rnext)

18:57 clojurebot: java.lang.Exception: Unable to resolve var: rnext in this context

18:57 kotarak: (doc nth-next)

18:57 clojurebot: excusez-moi

18:57 kotarak: (doc nthnext)

18:57 clojurebot: Returns the nth next of coll, (seq coll) when n is 0.; arglists ([coll n])

18:58 kotarak: ,(nthnext 2 '(1 2 3))

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

18:58 spacema__: erohtar: man, you gotta start putting line breaks into capjure =]

18:58 kotarak: ,(nthnext '(1 2 3) 2)

18:58 clojurebot: (3)

18:58 kotarak: It's getting late... -.-

18:58 erohtar: yes - yes, i know: :) i will clean it up in the next couple few days and release it properly

19:00 spacema__: excellent, looking forward to it. I'm still trying to wrap my head around the code, particularly the encoding / decoding bits

19:30 duck1123: does anyone know what: java.lang.NoSuchMethodError: clojure.lang.MultiFn.<init>(Lclojure/lang/IFn;Ljava/lang/Object;Lclojure/lang/IRef;)V might mean?

19:31 the trace isn't giving me any files that I could look at

19:31 I just upgraded clojure, clojure-contrib, and compojure and I know a lot has changed since i last upgraded

19:56 Raynes: GridBagLayout is complicated. :|

19:58 I'll pay the first guy who writes a comprehensive Swing tutorial for Clojure.

19:58 I might even kiss him.

19:59 keithb: Raynes: GridBagLayout is despised and not used by most Swing experts I know of.

20:00 I've found it better to use various layouts in a nested fashion.

20:00 Raynes: keithb: Add another one to the list, 'cause I'm not using it.

20:00 keithb: Oh, ok.

20:00 blbrown: use SWT

20:00 Raynes: keithb: My calculator example uses GridLayout and BoxLayout. \o.

20:00 \o/*

20:00 blbrown: everytime I see swing examples, I go, use SWT

20:01 keithb: Raynes: BorderLayout is extremely helpful too.

20:01 Raynes: blbrown: You don't know the hell I've been through learning what Swing I know without knowing Java. I'm not doin' it again for SWT ._.

20:01 keithb: It's my knight in shining armor.

20:02 keithb: If anyone's interested, I did a Swing app in Java and ported it to JRuby and Clojure. Articles at my blog at http://krbtech.wordpress.com. There are nested layouts used there.

20:02 blbrown: Just saying, in a couple of years of swing hell, you will come back to SWT

20:03 Raynes: I'm interested! :D

20:03 * Raynes clicks

20:03 keithb: blbrown: I used Swing for several years. My feeling is, it has a steep learning curve, but once you've climbed it, it's more full featured than SWT.

20:03 Raynes: I'm going to write a little notepad replacement for myself using Swing soon. Just for fun. I can use all the examples I can get.

20:04 blbrown: keithb, where is that pluggable Swing web browser widget... oh yea, doesn't exist

20:04 keithb: Raynes: and others...I'm signing off, but if you want to get in touch in the future, I can be reached at kbennett at bbsinc dot biz.

20:04 Raynes: Kay.

20:05 keithb: blbrown: I'm not saying that Swing is always better than SWT, but my impression is that for serious desktop apps, Swing is better. I know about Eclipse, but NetBeans and Intellij Idea are Swing apps.

20:05 I just came from New York today -- yesterday I attended Sun Community One, and the New York Java SIG -- and there were presentations about JavaFX.

20:05 Interesting, but not yet very mature, and more a Flash type thing than a Swing type thing.

20:06 bye

20:06 blbrown: well javafx is a different story

20:14 gnuvince_: For those interested, I posted the details of my application's performance woes to the Google group.

20:18 blbrown: gnuvince_, did the hprof stuff help

20:19 gnuvince_: blbrown: well I found that clojure.lang.Var.deref seems to take a lot of time

20:20 blbrown: gnuvince_, awesome info. One more question, what args did you run hprof with, because I need to profile an app also

20:20 stuhood: almost everything is contained in a var, right? i think that makes sense

20:21 gnuvince_: blbrown: -Xrunhprof:cpu=times

20:21 stuhood: oooh: i see now. didn't realize the hprof output contained Var.deref multiple times

20:22 slashus2: gnuvince_: How expensive is one dereference in your experiments?

20:23 gnuvince_: slashus2: I have not tried it.

20:23 blbrown: also from a Java perspective, you want to increase the min-heap/max-heap. and avoid garbage collections.

20:24 normally Java is slow is when it is doing more garbage collections than it should, so you might want to look at memory usage as well

20:24 gnuvince_: And when it's within the greater context of the application, Var.deref still is way high up there, even with all the map assoc'ing going around

20:32 blbrown: gnuvince, are you running off of clojure from subversion (from the source) or the latest build

20:33 gnuvince_: Subversion

20:33 blbrown: yea, I was trying to run it

20:35 stuhood: gnuvince_: why not be lazy in null-string? i haven't been able to grok how big your buffers tend to be

20:37 gnuvince_: stuhood: The buffers are fixed at a certain length in the context of my application

20:37 (25, 32 and 40 bytes IIRC)

20:37 stuhood: gnuvince_: gotcha

20:38 gnuvince_: And they need to be read completely, otherwise you'll end up with incorrect data for the next fields.

20:38 stuhood: gnuvince_: so why not use the bulk get(byte[]) methods to get the length you are expecting?

20:39 gnuvince_: I could probably try that

20:40 But that'll probably not be a big fix to the problem since there are very few (maybe 4-5) strings read and tens of thousands of reads of bytes, words and dwords.

20:40 stuhood: gnuvince_: i trust rhickey's primitive support reasonably well, but using a list comprehension on a chars doesn't seem optimal

20:40 ahh

20:40 blbrown: gnuvince_, do you mind running hprof with the default settings, I was curious what the memory stats were

20:40 gnuvince_: just -Xrunhprof?

20:42 holy schmoly

20:42 53,000 lines, 34 MB

20:43 blbrown: can you post the bottom, the memory part

20:43 gnuvince_: You want the percentages?

20:43 blbrown: yea

20:43 gnuvince_: http://gist.github.com/82150

20:44 blbrown: and if you are really interested, if your process takes minutes, you can run jconsole to see memory and execution. http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html

20:45 you also have a memory problem. look at all of that data. 15 MBs for Cons, 8 for anonymous functions, on and on

20:47 hjlee: are there any method to convert character seq/collection to string?

20:47 gnuvince_: hmmm

20:47 hjlee: (apply str coll)

20:47 hiredman: (partial apply str)

20:48 gnuvince_: ,(apply str [\h \e \l \l \o])

20:48 clojurebot: "hello"

20:48 hjlee: thanks!

20:51 i'm reading sections in clojure home. after checking "interpose", i want to do something like:

20:51 (apply str (interpose \- "abcde"))

20:51 "a-b-c-d-e"

20:55 hiredman: ,(apply str (interpose \- "abcde"))

20:55 clojurebot: "a-b-c-d-e"

20:58 Chouser: gnuvince_: greatest-least is in, thanks.

20:58 gnuvince_: Chouser: thank you

20:59 Chouser: gnuvince_: are you using any of it at the moment?

20:59 gnuvince_: Not currently no

20:59 Chouser: ok

20:59 gnuvince_: If you want to hack it, feel free :)

21:01 stuhood: gnuvince_: another minor change: you coerce to int in (get-byte), but you should be able to coerce to byte, right?

21:01 same in get-short

21:01 gnuvince_: stuhood: Java's integer types are all signed. The format I analyze uses unsigned integers.

21:04 stuhood: gotcha

21:04 should only need twice as much space, so a short, but yea

21:04 mattrepl: how ugly is it to use a function for creating a backquoted structure instead of a macro? I have an instance where I'm passing in a sequence to a macro, but I need to have that sequence evaluated and not just the symbol in order to build up the expansion

21:05 Chousuke: mattrepl: hmh

21:06 mattrepl: using functions that return code in macros is just fine.

21:07 duck1123: I'm curious, what version of swank-clojure are people using? still the jochu version, or a fork?

21:08 gnuvince_: jochu's for me.

21:08 Chousuke: mattrepl: are you trying to make a macro that is called like (macro foo [a vector of things]) and generate the same piece of code for every item in the vector?

21:08 mattrepl: in such a case, a helper function is just the right thing :)

21:08 duck1123: it seems that the kreg version has a build.xml file, which I think might be better

21:09 mattrepl: Chousuke: exactly. I'm actually building up condp cases

21:09 Chousuke: you'll end up having something like ~@(map helper forms) in your macro then.

21:09 gnuvince_: stuhood: using shorts makes no apparent improvement, the speed remains the same.

21:10 stuhood: gnuvince_: yea, sorry... i'm failing to see the big picture: looking at micro optimizations instead =x

21:11 mattrepl: *nod* thanks!

21:11 gnuvince_: stuhood: well we're pretty much *in* micro-optimizations, but I still haven't put my finger on the one that's gonna make a difference

21:16 blbrown: gnuvince_, I am only going by my java experience, but you want to make sure that you aren't creating too many objects in loops, as well. More time to garbage collect

21:17 gnuvince_: blbrown: ok

21:17 blbrown: and maybe find a way to cache objects that you think you can.

21:21 stuhood: gnuvince_: read-field-aux creates a new var to represent your get-* functions, could that be made more efficient

21:23 Chousuke: you're also creating the byte array you parse 10000 times.

21:24 or actually since some of it's mutable, just the (map byte [whatever]) part

21:25 gnuvince_: Hmmm

21:25 Chousuke: though you don't seem to be mutating the byte array either.

21:25 stuhood: Chousuke: that part only take 242 ms on my machine

21:25 for all 10K iterations

21:25 gnuvince_: I could probably move that out to just be executed once

21:26 blbrown: is the compujure guy on freenode

21:27 gnuvince_: ~seen weavejester

21:27 clojurebot: no, I have not seen weavejester

21:27 gnuvince_: Apparently not

21:27 blbrown: OK

21:28 arohner_: blbrown: do you have a compojure question?

21:29 blbrown: just some general questions

21:29 arohner_: I might be able to answer them

21:29 gnuvince_: Moving the creation of the array doesn't seem to do much regarding memory usage and only marginally improves total performance

21:30 slashus2: hiredman: I think I found a way around the sandbox created in your bot.

21:30 durka42: uh oh

21:30 blbrown: hehe

21:31 Chousuke: hmm

21:32 slashus2: ,((fn [] (file-seq (File. "/opt/"))))

21:32 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: File

21:32 slashus2: ,((fn [] (file-seq (java.io.File. "/opt/"))))

21:32 clojurebot: java.lang.NoClassDefFoundError: clojure/core$file_seq__4543$fn__4545

21:32 blbrown: ,((fn [] (file-seq (java.io.File. "/opt/"))))

21:32 clojurebot: java.lang.NoClassDefFoundError: clojure/core$file_seq__4543$fn__4545

21:32 Chousuke: :p

21:32 slashus2: hmm

21:33 durka42: ,((fn [] 42)

21:33 slashus2: I guess you have to fully qualify file-seq?

21:33 clojurebot: EOF while reading

21:33 durka42: ,((fn [] 42))

21:33 clojurebot: 42

21:34 slashus2: ,((fn [] (clojure.core/file-seq (java.io.File. "/opt/"))))

21:34 clojurebot: java.lang.NoClassDefFoundError: clojure/core$file_seq__4543$fn__4545

21:34 hiredman: hold on

21:34 blbrown: funny, that all the vultures are ready to jump on clojurebot and hiredman gets em every time

21:34 slashus2: blbrown: I wasn't jumping on it, just trying to help.

21:35 hiredman: I seriously doubt anything using file-seq would get around teh sandbox

21:35 slashus2: I am using his sandbox on my bot, I was just playing around with it.

21:35 hiredman: Try to create a file object using the method I just tried.

21:36 hiredman: ,((fn [] (clojure.core/file-seq (java.io.File. "/opt/"))))

21:36 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission /opt read)

21:36 Chousuke: ,(let [a (agent 1 :validator #(do (System/exit 1) &%))] (send a inc))

21:36 clojurebot: java.lang.Exception: Unable to resolve symbol: & in this context

21:36 Chousuke: ,(let [a (agent 1 :validator #(do (System/exit 1) %&))] (send a inc))

21:36 clojurebot: java.lang.RuntimeException: java.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.1)

21:36 Chousuke: boo ;(

21:37 hiredman: clojurebot: latest contrib?

21:37 slashus2: Wonder why it works on my bot.

21:37 Chousuke: slashus2: maybe the sandbox on your bot is not effective

21:38 slashus2: did you enable the security manager?

21:38 slashus2: Chousuke:

21:38 yes

21:38 Chousuke: you sure? :)

21:38 slashus2: no

21:39 Chousuke: I think you need to pass an argument to java and a policy file for starters.

21:39 then you need to call the method to set the security manager.

21:39 hiredman: nah

21:39 Chousuke: and if your slime does not explode when you do that, it might be working.

21:40 hiredman: either you pass the argument to java, or you call the function to enable it

21:40 Chousuke: ah

21:40 slime does some really funky stuff if you enable the security manager without a policy file allowing clojure to do certain things :P

21:41 gnuvince_: Can you put a type hint in a let? (let [#^ByteBuffer buf (...)] ...)?

21:41 Chouser: yes

21:42 Chousuke: it throws an exception and then because slime tries to use clojure to process the exception it throws another exception... etc.

21:42 gnuvince_: Chouser: I must be doing something wrong then, cause it keeps telling me that I have reflexion on that line.

21:43 slashus2: Sorry for the false alarm. I think I am having troubles with the security policy and manager.

21:43 Chouser: if it says it's on that line, it's probably the init expression

21:43 the (...) part

21:44 gnuvince_: #^ByteBuffer -buf (.get buf arr)]

21:44 That's what I got

21:44 I should type-hint the array?

21:44 Chouser: it's the (.get buf arr) part, then.

21:44 make sure that buf and arr are hinted sufficiently.

21:45 gnuvince_: ah

21:45 #^bytes arr ... did the trick

21:45 slashus2: Seems to be working now.

21:45 hiredman: I gotta say I wasn't really alarmed :P

21:46 I have close to absolute faith in the IO part of the sandbox provided by the jvm

21:46 I believe there are some exploits, but I think you have to go to the bytecode level to exploit them

21:47 cp2: hiredman: there was an exploit

21:47 to do with applets/images

21:47 but that was an old version of java 5

21:47 long since patched

21:47 slashus2: ((fn [] (file-seq (File. "/")))) <--- This works for mine...

21:48 When other directories don.?

21:48 cp2: there was a jnlp exploit discovered in 07

21:48 slashus2: don't

21:48 hiredman: too bad the sandbox doesn't let you read system properties so you can't find out what java version I am using

21:48 cp2: heh

21:48 hiredman: , ((fn [] (file-seq (File. "/"))))

21:48 clojurebot: java.lang.IllegalArgumentException: Unable to resolve classname: File

21:48 hiredman: , ((fn [] (file-seq (java.io.File. "/"))))

21:48 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission / read)

21:48 slashus2: You know what it is...

21:48 I have a debug statement.

21:48 So it is accessing my hard drive.

21:49 *facepalm*

21:49 I was executing thunk

21:49 :-D

21:49 stuhood: ,(count *facepalm*)

21:49 clojurebot: java.lang.Exception: Unable to resolve symbol: *facepalm* in this context

21:51 slashus2: My excuse is that I am lacking sleep from recent tests.

21:51 exams*

21:55 I am experimenting with java's ScriptEngineManager trying to incorporate other languages into the bot. It appears that the sandbox method works for those scripts too.

21:57 Chouser: which languages?

21:59 slashus2: jython Jaskell?

21:59 hiredman: ~sandbox

21:59 clojurebot: sandbox is http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html

21:59 slashus2: https://scripting.dev.java.net/

21:59 hiredman: ^- this is where I cribbed the sandbox from

22:00 slashus2: hiredman: It is a good method.

22:00 maybe scheme?

22:00 hiredman: it is used in a scala bot, that I think also uses the scriptengine stuff for jruby, etc

22:00 abcl

22:00 :P

22:00 slashus2: maybe

22:01 I don't know if the Scripting manager supports it.

22:19 stuhood: gnuvince_: whats up with this line:

22:19 3 0 97 0 98 0 99 ; 3 Shorts

22:20 7 bytes?

22:21 gnuvince_: stuhood: I have a mecanism to have a variable number of bytes/shorts/ints

22:22 [:field-name [1 Byte] Short] ; read one byte which will be used as the length to read shorts

22:28 blbrown: hiredman, so sandboxing is a java protection mechanism, interesting

22:29 I just don't understand why people bash java, there seems to be useful stuff there sometimes

22:32 hiredman: well

22:33 the jvm and the library it comes with is great, the language is :(

22:35 blbrown: that is one part yes, but there is a whole world out there where a lot of interesting work has been done. Every time I go to other technologies (Haskell, Erlang, common lisp, etc, etc) I always end up coming back

22:36 but I haven't willingly written Java code since 8 years ago

22:37 hiredman: word

22:46 stuhood: g'night everyone

23:08 Mec: is there a better function than (rem x 1) to tell if x has a decimal?

23:09 cmvkk: i don't think so. integer? won't work, because it returns false for 1.0 etc

23:09 unless you want that behavior

23:10 Mec: nope

23:10 danlarkin: there couldn't really be a better function, by definition

23:10 Mec: i thought integer? would work but starting getting strange results until i realized it didnt like doubles

23:10 cmvkk: well it could be easier to write. since you have to test if that equals 0.

23:11 (defn whole? [n] (= (rem n 1) 0)) or something

23:11 Mec: zero? is faster than = 0

23:11 hiredman: interesting

23:11 ~def zero?

23:11 danlarkin: modulus is a processor instruction, so it'll be as fast as an operation could be

23:11 *should be*

23:12 cmvkk: wow, i didn't know zero? existed.

23:12 i think i'm just going to read through core.clj from start to finish.

23:12 Mec: yup its usefull because = does a lot of extra stuff

23:16 Raynes: ,(time (zero? 0))

23:16 clojurebot: true

23:16 "Elapsed time: 0.124 msecs"

23:16 Raynes: ,(time (= 0 0))

23:16 clojurebot: true

23:16 "Elapsed time: 0.102 msecs"

23:16 cmvkk: i find your benchmarks highly unscientific.

23:17 :)

23:17 Raynes: = 0 was faster in this case on my REPL as well.

23:17 durka42: ,(time (dotimes [i 1000] (zero? i)))

23:17 clojurebot: "Elapsed time: 0.797 msecs"

23:17 durka42: ,(time (dotimes [i 1000] (= 0 i)))

23:17 clojurebot: "Elapsed time: 1.905 msecs"

23:17 Raynes: I'm not saying it's slower...

23:17 I said it was slower in this case, to be a smartass.

23:17 jhawk28: hiredman: everytime I see something new with clojurebot, I saw, wow thats cool.

23:19 hiredman: me too

23:19 Raynes: me too

23:23 Mec: hmm i blew my heap space but it doesnt tell me where, any way to find out?

23:23 jhawk28: visualvm is the easiest

23:23 you can see what grows

23:24 as long as you are on Java 1.6

23:26 Mec: something like (reduce + (range 1000000000000)) shouldnt do it right?

23:26 hiredman: why wouldn't it?

23:26 Mec: its not actually making the whole range in memory, just 1 bit at a time and dumping the rest

23:27 hiredman: makes sense to me

23:28 cmvkk: if you did (reduce * (range 1000000000000000)) that might blow the heap

23:28 Mec: heh probably

23:28 wow just doing the reduce + is taking a very long time

23:28 cmvkk: i know i'm running it too heh

23:29 Mec: my memory is staying constant tho

23:29 jhawk28: using alot of cpu

23:30 cmvkk: as expected.

23:31 Mec: i've got 4 computers in my house, ill need to figure out a way to split a java program to run across them all :D

23:31 cmvkk: isn't that what terracotta will allow us? or something? i haven't been paying too close attention to all that.

23:31 jhawk28: yes, terracotta

23:31 Mec: no idea i havnt even looked into it yet

23:33 jhawk28: http://www.infoq.com/news/2009/01/clojure_production

23:33 eee: when will computers be able to figure out closed forms to things?

23:33 durka42: closed forms?

23:34 eee: 1 + 2 + 3 + 4

23:34 etc

23:34 Mec: i still dont follow

23:34 eee: that's the one problem with composing things via risc

23:34 * durka42 does not understand

23:34 eee: n(n+1)/2

23:34 (reduce + (range 1000000000000))

23:34 durka42: oh

23:35 eee: risc is evil that way

23:35 each little piece is too dumb

23:35 Mec: mathematica can figure a lot of stuff like that out

23:35 eee: that's cool

23:36 Mec: hmm i bet my memoize function that i passed 1000000 values is what blew my stack

23:38 i dont suppose there's a way to cache just the last value passed to a function, perhaps i can just rewrite memoize to do it

23:38 pstickne: why would that ... oh, nvm :)

23:38 Mec: ?

23:38 pstickne: ... touch the stack.

23:40 durka42: i thought you blew your heap

23:40 Mec: same diff

23:40 cmvkk: heh

23:40 pstickne: not quite :(

23:41 Mec: so a function within a function may or may not be continuously redefined, is there a way to figure out if it is or keep it from being?

23:41 pstickne: Mec: but if you already have a memoize function it should be trivial to implement it to just remember the last call and/or apply LRU or similiar.

23:42 durka42: pstickne: he's using clojure.core/memoize

23:42 pstickne: oh, I have no idea then :)

23:42 Chouser: continuously redefined?

23:42 Mec: its pretty straightforward, it just puts calls and returns into a map

23:42 durka42: luckily, core/memoize uses the obvious implementation, so it shouldn't be too hard to rewrite

23:43 Mec: hmm can the compiler tell if an inner function makes use of a closure and not redefine if it doesnt?

23:44 Chouser: what do you mean by redefine?

23:44 Mec: (fn adder [x] (fn [y] (+ x y))

23:44 durka42: as in, construct the AFn object again every time the function is called?

23:44 Chouser: that creates two classes at compile time

23:44 Mec: ya

23:44 cmvkk: the question is, if you call adder twice with the same value, will you get an identical object back

23:45 or rather, will it be the SAME object

23:45 Mec: the function adder needs its inner function remade every time its called, but (fn bleh [x] (fn [y] (inc y)) doesnt

23:45 Chouser: when you call adder, a new instance is created for the inner fn

23:45 pstickne: it sucks having to map thinking into Java :(

23:45 durka42: ,(let [adder (fn [x] #(+ x %))] (type (adder 3)))

23:45 clojurebot: sandbox$eval__1081$adder__1083$fn__1085

23:46 hiredman: man

23:46 Chouser: ,(let [f (fn [] (fn [y] (inc y)))] (identical? (f) (f)))

23:46 clojurebot: false

23:46 hiredman: how does amazon know to recomend me real world haskell? all I ever buy is science fiction

23:47 durka42: wait, is the class redefined too

23:47 cmvkk: well, that's how it knows.

23:47 durka42: ,(let [adder (fn [x] #(+ x %))] (type (adder 3)))

23:47 clojurebot: sandbox$eval__1100$adder__1102$fn__1104

23:47 durka42: the classname is being gensymmed a couple of times

23:47 Chouser: durka42: that'sonly because you're recompiling the whole thing

23:47 pstickne: hiredman: and what data-mining conglomerations are going on...? ;)

23:47 durka42: oh

23:47 Chouser: if you defn'ed adder and called it a couple times, you'd get the same class name

23:47 ,(let [f (fn [] (fn [y] (inc y)))] (identical? (class (f)) (class (f))))

23:47 clojurebot: true

23:48 Mec: ,(let [adder (fn [x] #(+ x %))] (do (println (type (adder 3))) (type (adder 3)))))

23:48 clojurebot: sandbox$eval__1119$adder__1121$fn__1123

23:48 sandbox$eval__1119$adder__1121$fn__1123

23:48 Mec: bah why overcomplicate, ill just make a helper function

23:49 eee: anyone going to lispcon?

23:49 Mec: any chance it's in chicago?

23:49 Chouser: eee: ilc? I am!

23:49 eee: cool

23:50 they gonna be selling clojure books there?

23:50 Chouser: no idea

23:50 the only clojure book I know of isn't out yet, so probably not.

23:51 eee: oh yeah. that's right

23:51 Chouser: ok, bedtime. later, folks.

23:51 Raynes: Night Chouser.

23:51 Chrissstofur :)

Logging service provided by n01se.net