#clojure log - Mar 21 2009

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

0:00 slashus2: p_l: Try to compile openjdk on there :-)

0:04 p_l: slashus2: well, MVS3.8 is not going to be POSIX-compatible :D

0:04 slashus2: :-(

0:05 pstickne: What better way(s) are there of doing: (reduce #(str %1 "->" %2) ["hello" "world"])

0:05 Raynes: multimethods are hawt.

0:06 I wish Clojure had pattern matching.

0:06 slashus2: Raynes: Implement it.

0:06 pstickne: Well, it kind of does with multimethods ...

0:06 they are like untyped active patterns that can be broken up among sites

0:06 Raynes: pstickne: Kind of overkill for pattern matching. But it definitely works.

0:06 slashus2: I should /totally/ do that.

0:06 * Raynes puts it on his todo list.

0:06 slashus2: pstickne: You could use clojure.contrib.str-utils/str-join

0:07 pstickne: and it supports the neat (let [[a b c] (foo)] ...) style matching

0:07 slashus2: ~str-join

0:07 clojurebot: Excuse me?

0:07 pstickne: (or, decomposition, rather)

0:07 slashus2: ,(doc clojure.contrib.str-utils/str-join)

0:07 clojurebot: java.lang.Exception: Unable to resolve var: clojure.contrib.str-utils/str-join in this context

0:07 Raynes: I keep forgetting that I can implement my own features in Clojure. :|

0:07 slashus2: ,(apply str (interleave " " ["hello" "world"]))

0:07 clojurebot: " hello"

0:08 slashus2: :-|

0:08 Raynes: ,(apply str (interpose " " ["Hello" "world!"]))

0:08 slashus2: ,(apply str (interpose " " ["hello" "world"]))

0:08 clojurebot: "Hello world!"

0:08 Raynes: Owned.

0:08 clojurebot: "hello world"

0:08 stuhood: yea, i think you want interpose

0:08 slashus2: Raynes: Only barely.

0:08 Raynes: ;)

0:08 stuhood: ,(apply str (interleave " " ["hello" "there" "world"]))

0:09 clojurebot: " hello"

0:09 slashus2: I accidentally typed interleave instead of interpose.

0:09 Raynes: slashus2: And I was even unplugging my Ipod when I did that.

0:09 \o/

0:14 slashus2: (eval (symbol "(+ 1 2)")) this doesn't seem to work :-(

0:21 Victorr: try (eval (read-string "(+ 1 2)"))

0:21 ,(eval (read-string "(+ 1 2)"))

0:21 clojurebot: DENIED

0:21 Victorr: clojurebot, you are a bore

0:22 slashus2: Victorr: Thank you!

0:22 Victorr: mp

0:22 slashus2: That only reads one object.

0:23 Victorr: Is there something that can read all objects?

0:24 Victorr: sure, just prepend "(list " to your string, and append ")", that ought to do the trick

0:24 what exactly are you trying to do?

0:24 slashus2: Victorr: I was trying to hack up a plugin system. Read in the code from a bunch of files, and evaluate it.

0:25 Victorr: isn't that what load-file does?

0:25 slashus2: :-|

0:26 I think so.

0:26 I wonder what the best way to do it with eval would be.

0:36 Victorr: good night!

1:46 Raynes: ,(time (loop [x 5] (when (zero? x) 0) (println x) (recur (dec x))))

1:46 clojurebot: Execution Timed Out

1:48 harpastum: woah

1:48 just ran that

1:49 Raynes: It never completed for me.

1:49 I don't get why.

1:49 I got impatient waiting and closed the REPL.

1:49 cmvkk: it recurs forever.

1:49 harpastum: (when (zero? x) 0)?

1:49 Raynes: That's what I'm trying to figure out :\

1:49 harpastum: what does that mean?

1:49 Raynes: I have apparently misused when.

1:49 cmvkk: yeah, when returns zero when x is 0, or nil otherwise.

1:50 but THEN, the println and recur statements run, no matter what.

1:50 they're not inside the when statement, notice.

1:50 harpastum: they're inside the loop though

1:50 cmvkk: yeah.

1:50 Raynes: Oh, I forgot that when wasn't if.

1:50 >_>

1:50 harpastum: so it just runs that statement

1:50 and that doesn't do anything

1:50 and moves on

1:51 cmvkk: ,(time (loop [x 5] (if (zero? x) 0 (do (println x) (recur (dec x)))))

1:51 clojurebot: EOF while reading

1:51 cmvkk: ,(time (loop [x 5] (if (zero? x) 0 (do (println x) (recur (dec x))))))

1:51 clojurebot: 0

1:51 5 4 3 2 1 "Elapsed time: 0.739 msecs"

1:51 harpastum: haha

1:51 there you go

1:51 Raynes: harpastum: 'when' runs every time, and when it reaches zero, it runs but still continues.

1:51 I know how to do it, I was just playing around with when :\

1:51 You guys underestimate me ;)

1:52 harpastum: i ran it in my repl

1:52 i managed to stop it by the time it was printing -250k

1:52 the original function

1:52 Raynes: Haha.

1:53 harpastum: i realize that it's probably just my laziness and the fact that I'm not totally used to LISP

1:54 but i really wish there was an editor that i could hit like option-) and it would add enough parens to get back to the beginning of the declaration

1:54 i guess it's also because i'm still using the repl in terminal

1:55 i really have to get around to installing that emacs plugin

1:55 ,(time (loop [x 5] (if (zero? x) 0 (do (println x) (recur (dec x))))))

1:55 clojurebot: 0

1:55 5 4 3 2 1 "Elapsed time: 0.709 msecs"

1:56 Raynes: Man, I don't think there /is/ an elegant way to write a Towers of Hanoi solver without using recursion :\.

1:57 pstickne: All recursion can be...

1:57 Raynes: What?

1:57 pstickne: unrolled.

1:58 Raynes: There a way to do it using /just/ tail recursion, but I can't figure out how to do it in an elegant way.

1:59 pstickne: don't like the wiki?

2:00 Raynes: Hrm?

2:00 pstickne: http://www.kernelthread.com/projects/hanoi/ :-)

2:01 Raynes: There is no Clojure example there.

2:01 pstickne: add one :p

2:01 Raynes: I added mine at rosetta code.

2:02 pstickne: hmm, I read the CL example wrong :p

2:02 Raynes: http://www.kernelthread.com/projects/hanoi/html/gcl.html This is the kind of stuff I want to avoid.

2:02 pstickne: which part?

2:02 Raynes: Calling itself twice is what blows the stack, but normally it isn't very noticeable, but in Clojure and the JVM's stack, it can't even handle 10,000.

2:03 http://www.kernelthread.com/projects/hanoi/html/gcl.html My example.

2:03 pstickne: so move it onto the heap with an unroll? (I now of of no non-dividing solution)

2:03 wikipedia gave the rules for a non-recursive solution

2:04 Raynes: How do you do an unroll? O.o

2:04 pstickne: check out wikipedia already :p

2:04 there are 5 posted solution groups

2:04 * Raynes wikipedias

2:08 p_l: nice verb

2:09 Raynes: p_l: I can verb with the best of them.

2:09 * Raynes gets a pepsi to keep his motor running until 3AM

2:09 Raynes: I HAVE GOT TO FINISH THIS DAMNED BOOK!

2:09 durka42: why 3am?

2:09 heh

2:10 * durka42 is staying up for an early train

2:10 Raynes: briancarper: Hi there.

2:10 * p_l just didn't notice the time and now it's too late for sleep

2:11 Raynes: briancarper: I'm surprised you were able to realize that my Clojure example wasn't a palindrome, nice eye you got there.

2:11 briancarper: Hi, yeah I wrote my own, then I put it through Ruby 'blah blah blah'.reverse and cried when I saw the backwards parens.

2:12 * Raynes is going to write a small notepad replacement for himself for absolutely no reason other than to practice his Swing abilities. My Windows Calculator replacement is NOT ENOUGH!

2:13 p_l: Raynes: then try to replace Win7 calculator :D

2:13 Raynes: p_l: My calculator is simpler than the Vista calculator. No one ever uses all that scientific shit anyways.

2:13 My calculator has 5 buttons and a text field \o/

2:15 Is there a firefox plugin for saving entire websites for quick access later?

2:15 I think there is

2:15 * Raynes Googles <---moar l33t verbing.

2:16 briancarper: Can't you File, Save as., and save everything?

2:17 Raynes: Will take too long. In hindsight it will probably take longer for me to find and install the plugin, but oh well.

2:17 p_l: Scrapbook

2:19 Raynes: p_l: My hero.

2:20 * p_l is a big fan of scrapbook, though lately haven't used it as much (faster internet access)

2:36 Raynes: Good night computer.

3:34 Lau_of_DK: Top of the morning gents

3:38 blbrown: Lau_of_DK, I have 3 more hours but that works

3:41 cgrand: morning Lau!

3:42 Lau_of_DK: Morning Mr. Grand :)

3:48 blbrown: Lau_of_DK, did you eat breakfast? I think I want a big breakfast today.

3:48 Lau_of_DK: Yes I did :)

4:05 Raynes: I just finished Programming Clojure

4:05 And right in time for bed!

4:05 I feel so accomplished. <3

4:19 Good night my fellow Clojurists!

4:19 p_l: night

11:05 jcrites: "Better static safety for higher-order code" claimed by esoteric language designer Slava Pestov

11:05 I read this and laughed because

11:05 does it mean Slava is a designer of esoteric languages?

11:05 or that Slava is an esoteric designer of languages? :P

11:05 or both :)

11:05 a. Intended for or understood by only a particular group: an esoteric cult. See synonyms at mysterious.

11:06 is Slava intended for or understood by only a particular group? heh

11:07 oh my

11:08 wrong channel, sorry :)

12:13 cconstantine: Does anyone know the bigO of dissoc?

12:25 Cark: constantine : depends on the kind of map

12:25 i beleive sorted map is log n and hashmap is log32 n

12:26 though i didn't go and check the code

12:52 cconstantine: Cark: ok. Just wanted to make sure dissoc of a hashmap wasn't something crazy like O(N)

12:59 Cark: i'm positive about that

13:24 Raynes: Whoa, look at all the people that posted in my group thread while I slept.

13:26 * Raynes smiles at his successful attempt at making March 20th a holiday for Rich.

13:42 briancarper: Are there any examples of people writing their own Java collection code and tying it to Clojure's seq interfaces?

13:44 slashus2: briancarper: What is wrong with the java collection code?

13:44 marklar: paste

13:44 clojurebot: paste

13:44 clojurebot: lisppaste8, url

13:44 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

13:44 kotarak: briancarper: lazymap kind of implements IPersistentCollection and can be used with Clojure's seq interface. It's using gen-class, though. Not Java.

13:45 briancarper: slashus2: e.g. using LinkedHashMap so I can have ordered maps.

13:45 kotarak: briancarper: there's also array-map, for ordered maps.

13:45 slashus2: ,(doc sorted-hashmap)

13:45 clojurebot: java.lang.Exception: Unable to resolve var: sorted-hashmap in this context

13:45 slashus2: woops

13:45 kotarak: ,(doc array-map)

13:45 clojurebot: "([] [& keyvals]); Constructs an array-map."

13:46 slashus2: ,(doc sorted-map)

13:46 clojurebot: "([& keyvals]); keyval => key val Returns a new sorted map with supplied mappings."

13:46 briancarper: Cool, I'll look at array-map.

13:46 Sorted maps aren't what I want though, I want to maintain insertion order.

13:47 slashus2: array map is what you want then.

13:49 briancarper: Thanks. Now if only there was a literal syntax for them. :(

13:49 slashus2: briancarper: Smaller map literals are array maps

13:49 kotarak: briancarper: I think for (hash-map ...) < 10 entries are array maps

13:49 slashus2: ,(class {:a "5"})

13:49 clojurebot: clojure.lang.PersistentArrayMap

13:52 dnolen: briancarper: structs are positional and stay positional from what I understand.

13:53 ,(do

13:53 (defstruct my-struct :first :second :third)

13:53 (prn (assoc (struct my-struct 1 2 3) :fourth 4)))

13:53 clojurebot: EOF while reading

13:53 dnolen: oops

13:53 ,(do (defstruct my-struct :first :second :third) (prn (assoc (struct my-struct 1 2 3) :fourth 4)))

13:53 clojurebot: DENIED

13:54 briancarper: dnolen: Oh, I didn't know that.

13:54 dnolen: heh, you can't defstruct with clojure bot

13:54 anyways it should work.

13:54 slashus2: Oh, didn't think of structs

13:55 dnolen: briancarper: yeah I was pondering this a while go, maps don't keep order, but I realized that structs do.

13:55 dreish: (Except when you add arbitrary keys that aren't part of the struct definition.)

13:55 briancarper: dreish: Yeah looks like arbitrary keys will appear all over the place, but struct keys are ordered.

13:55 dreish: Right.

14:13 lisppaste8: dnolen pasted "struct-assoc" at http://paste.lisp.org/display/77390

14:14 dnolen: dreish, briancarper: you can work around this with some cleverness. note that struct-assoc is about 5X slower than assoc

14:14 but that isn't so bad considering that you care about position.

14:16 briancarper: Oh, that's interesting. It makes a new anonymous struct every time?

14:18 dnolen: yes, basically you're getting hit on modification speed (maybe memory as well? structs use more than maps?), but you get positionality.

14:19 briancarper: Thanks, it looks useful. I usually don't care about speed or memory.

14:19 dnolen: cool, glad could be of help.

14:26 dreish: Interesting. I'd probably hide this behind a layer of abstraction in case I wanted to use a different implementation later, though.

15:51 hiredman: ,(doc sorted-map)

15:51 clojurebot: "([& keyvals]); keyval => key val Returns a new sorted map with supplied mappings."

15:51 hiredman: hmmm

15:51 ah

15:51 ,(doc sorted-map-by)

15:51 clojurebot: "([comparator & keyvals]); keyval => key val Returns a new sorted map with supplied mappings, using the supplied comparator."

15:52 hiredman: I think, using the right comparator, you could use that to keep insertition order

15:52 there may even by some code for it on lisppaste

16:00 cconstantine: Yay! I think I fixed the slow in my prime generator... now it's only 5 times slower than Chouser's instead of 400 thousand times slower :)

16:05 pstickne: cconstantine: a small improvement ;)

16:05 cconstantine: hehe

16:06 pstickne: cconstantine: using the same kind of generator?

16:06 cconstantine: and mine prime generator has the benefit of producing as many primes as you want :)

16:06 pstickne: I've only made a PRNG using the Super-7 LSFR (?)

16:07 cconstantine: nope, you have to give his an upper limit. (first mine) is a prime, and (rest mine) is a generator for the next prime :)

16:07 pstickne: oh, prime :p

16:07 I was thinking...

16:07 * pstickne smacks self

16:07 pstickne: cconstantine: what sizes of primes?

16:07 cconstantine: how much memory and time do you have?

16:07 pstickne: :)

16:07 cconstantine: it's a lazy sequence

16:07 pstickne: But it's really prime vs. probably-prime?

16:08 cconstantine: really prime

16:08 pstickne: (and prime in sequence it sounds like?)

16:08 cconstantine: seive method without the array

16:08 pstickne: cool :)

16:08 cconstantine: yeah :)

16:08 now if I can just make it faster....

16:09 pstickne: ASM ;-)

16:09 cconstantine: and paralelized... across a cluster, and then I can take over the world! muahahahah

16:09 bah

16:09 I do ASM for a living, clojure is for fun

16:09 pstickne: I've never learned what the consequences of accidently getting a non-prime number where in cryptography...

16:09 cconstantine: sorry :(

16:09 *were

16:09 cconstantine: ppc asm, and python, and c++ :(

16:10 generating a non-prime in crypto is bad.. very very bad

16:10 pstickne: eww :p

16:10 lisppaste8: slashus2 pasted "prime generator" at http://paste.lisp.org/display/77393

16:10 pstickne: cconstantine: right, so if you have a probably-prime, and a million people a second generate it...

16:11 slashus2: This is probably not the best approach.

16:11 pstickne: (e.g. is there some final OMG DONT WANT check?)

16:11 cconstantine: slashus2: where's prime?

16:11 slashus2: oh sorry :-|

16:11 cconstantine: pstickne: you could try to divide it by all the previous known primes...

16:12 lisppaste8: slashus2 annotated #77393 "prime?" at http://paste.lisp.org/display/77393#1

16:12 cconstantine: slashus2: that's *a* way of doing it, but it's O(n * sqrt(n)) I beleive.... mine is O(n log n)

16:13 slashus2: you should read http://bigdingus.com/2008/07/01/finding-primes-with-erlang-and-clojure

16:13 slashus2: I guess the sieve is the best way of doing it?

16:13 cconstantine: thats the first way I did it, and it was shockingly slow

16:13 shockingly slow compared to my friend's c++ seive implementation

16:14 pstickne: what is this probably-prime you're talking about?

16:15 pstickne: http://en.wikipedia.org/wiki/Probable_prime

16:16 cconstantine: oh! I can optimize it by incrememting by 2 instead of 1 :)

16:16 pstickne: cconstantine: and discarding all / 5

16:16 cconstantine: pstickne: I do that anyway through the 5 counter

16:16 pstickne: anyway, they are useful: http://en.wikipedia.org/wiki/RSA

16:17 cconstantine: pstickne: ah, ok :)

16:17 pstickne: cconstantine: but I dropped that class (as it was too much "let's code up an RSA implementation" vs. theory)

16:17 the people in the course /still/ don't know the ramifications of not choosing a prime number :)

16:18 cconstantine: pstickne: bah, that's no good

16:18 pstickne: I had so much fun in my crypto class I got a job in my prof's startup :)

16:18 sorry, security class, not crypto class

16:19 pstickne: cconstantine: I cringe at the thought of working for any professors startup (there are two in the comp-sci on this call campus)

16:19 *small

16:19 cconstantine: why?

16:19 pstickne: Well, since we have separation of Church and State...

16:19 anyway, it just smells like BadPolitics to me

16:20 cconstantine: conflict of interest?

16:20 pstickne: somewhat

16:20 but it's all through and through

16:20 cconstantine: ah. he wasn't involved in the hiring decision, and I applied after I graduated

16:21 pstickne: for this semester I had to do an "alternative project" for the final capstone software engineering course because I didn't want to blanket waive all my "IP" (a term which was not well defined in the waiver!) -- I am an undergrad so...

16:21 cconstantine: he wanted you to waive all your IP for a class? that's wierd

16:21 pstickne: but it's okay, because this other project is like 10x cooler and I don't have to deal with the bunk of the other group (or the professor; we are the black sheep :p)

16:22 cconstantine: hehe

16:23 pstickne: cconstantine: yeah, I guess it's "standard practice" -- I don't mind waiving rights to specified deliverables, but it was just "all IP" ^^

16:23 cconstantine: pstickne: well, I guess my school (purdue) has some level of rights to any work I did on purdue machines... but I don't remember signing anything

16:24 pstickne: (not that I think I'd come up with something cool -- I just don't like the thought :)

16:24 cconstantine: yeah

16:25 pstickne: on the other hand, colleges make oodles of money off of patents (which are another item of disgust, but ... I digress)

16:25 cconstantine: so, I'm testing the speed of a "test by divide by all previous primes" prime generator at 100000 primes about 20 minutes ago... and it's still going :)

16:25 hehe

16:26 eh, the initial tech our company is based on was written by a grad student... I think we had to buy it off purdue... but compared to how much we bring in now it's a pittance.

16:26 * pstickne slaps the prudue official on that decision

16:26 cconstantine: I never did grad school... and nothing I did as an undergrad is really worth anything

16:27 pstickne: I guess it's working out okay for you know though :-)

16:27 cconstantine: eh, it was still unproven (technically, and busness-wise) when they sold it

16:27 it's really only worth anything because of the work done by the company

16:27 pstickne: you mean nobody will want my turtle->3bytecode compiler in clojure? :(

16:28 cconstantine: wait... you ahve one! oh wow I've needed one of those for like forever!

16:28 pstickne: :p

16:28 cconstantine: :)

16:30 I'm still learning clojure

16:30 I'm doing project euler to learn it

16:32 pstickne: I should do project euler in any language :p

16:32 cconstantine: so, I'm thinking about how I can multi-thread this prime generator... how easy would it be to have a lazy-seq that uses a separate thread to compute (first (rest gen))?

16:32 pstickne: it's good stuff

16:34 effectivly use a producer/consumer pattern for lazy sequences

16:35 a half-dozen of my friends are doing project euler... only 2 of us are using a functional language (the other guy is using erlang... maybe haskel)

16:36 pstickne: I would not like to do it in a language that at least isn't functional-like :)

16:36 cconstantine: eh, one guys is learning a bunch about boost and c++

16:36 which is good...

16:36 well... not c++ so much as c++'s stl

16:38 do you have any classes on or in functional/lisp languages

16:45 hmmm... how bad would it be to produce 10s of thousands of threads?

16:47 gnuvince_: Probably not good

16:47 Cark: give it a try and report back after your reboot !

16:47 cconstantine: hehe... ok

16:48 I was afraid of that

16:48 Cark: wouldn't be that dramatic i think

16:48 cconstantine: I'm thinking 10s of thousands of producers and one or two consumers... so they should be mostly stalled

16:49 Cark: using agents you don't need to be concerned about that

16:49 cconstantine: so I need to read up on agents

16:49 Cark: they live in a thread pool

16:50 cconstantine: ahhhh

16:50 Cark: and are only executed when there are pending messages

16:50 cconstantine: so I give it a set of tasks to do, and it does them all in N threads

16:50 Cark: right

16:51 so you could have 10s of thousands agents without killing your memory

16:53 cconstantine: ah, fantastic

16:53 all agents share a thread pool?

16:54 Retonator: hey guys i am trying to understand sequences could any one explain what happens here (i understand the expansion and the values) not exactly what goes on.

16:54 (def fibs (lazy-cat [0 1] (map + fibs (rest fibs))), what happens if i do lets say (take 4 fibs)

16:56 jonathanturner: newbie question - how do I add 1 to every element in a list?

16:56 cmvkk: jonathanturner: (map inc my-list)

16:56 ,(map inc [1 2 3])

16:56 clojurebot: (2 3 4)

16:56 cconstantine: I believe [0 1] is (first fibs), and (rest fibs) is the (map....) thing, but that s-expr isn't evaluated until someone runs (rest fibs)

16:56 jonathanturner: cmvkk: thanks, that works. Is there a way to use + also?

16:57 cmvkk: (map #(+ % 1) my-list)

16:57 for example

16:57 jonathanturner: is that a curry?

16:57 err, partial function... whichever they're called in clojure

16:57 cmvkk: it's a function literal, equal to (fn [x] (+ x 1))

16:57 Retonator: ok cmvkk actually first fibs return [0]

16:57 cmvkk: but i guess it's the same idea

16:57 cconstantine: #(..) s an anonyous function

16:58 jonathanturner: cool, thanks, that helps

16:58 Retonator: you have partials btw jonathan

16:58 cmvkk: i guess you could also do (map + my-list (repeat 1))

16:58 Retonator: ,(doc partial)

16:58 clojurebot: "([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args."

17:00 cmvkk: i've always thought that fibs function was too 'clever' and hard to read.

17:00 it looks nice, but...

17:01 what's going on is that you're mapping the fibs function so far, with one that's one element ahead of itself.

17:01 Chouse1: it's also not terribly efficient

17:01 Retonator: very nice but i want to get my mind around i think i know what it does but not right how ;)

17:01 cmvkk: using +. so [0 1] is fibs. so (first fibs) is 0, and (first (rest fibs) is 1.

17:02 then you're adding (second fibs) and (second (rest fibs)) which is 1 and 1, and so on.

17:02 Retonator: but in rest fibs then first fibs wil be the newly added item by the + ?

17:03 pstickne: what is the \"nul" character?

17:03 cmvkk: yes.

17:03 something like that...

17:04 Retonator: i think i understand it the map + actually gives back the next item in the sequence which you get back in rest fibs call and it will be the first argument for the next call

17:04 a bit cryptic but i guess i get it ;_

17:04 cmvkk: yeah that's basically the jist of it.

17:05 jonathanturner: oh, I see it in the reference now. #() is listed as a reader macro, where there's also the (partial ) for partials

17:05 Chouse1: pstickne: (char 0) I guess

17:05 pstickne: Chouse1: thanks

17:05 (I really miss semi-formal language definitions :-/)

17:06 Chouse1: Clojure's got a very formal language definition.

17:06 Retonator: ,(char 0)

17:06 clojurebot: \

17:06 Chouse1: so formal it's verified by the compiler, javac

17:06 pstickne: hmm :(

17:06 Chouse1: :-)

17:06 pstickne: (str "a" (char 0) "b") :-/

17:07 Chouse1: I think that's the printing code

17:07 pstickne: yeah, length is 3.

17:07 but why (pr-str (char 0)) ? :(

17:08 Chouse1: but I'd be a bit worried about nulls in a string anyway -- you're sure you don't want byte buffer of some sort?

17:08 pstickne: err, (pr-str (str (char 0))

17:08 Chouse1: ohh, heh

17:08 for uhm, an "eof" marker fnparse :p

17:09 Retonator: Chouse1: What would be an efficienter way of implementing fibs and why is the lazy-seq not very efficient (just curious)

17:10 pstickne: Retonator: high-order functions on the stack! :p

17:12 Retonator: yeah okay so it is a stack problem is it possible to define fibs in a tail-recursive way to avoid the stack?

17:13 pstickne: Retonator: http://www.google.com/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fwww.cs.toronto.edu%2F~ajuma%2F326f08%2F11Scheme4.pdf&ei=llfFSfv8J6CSsQPs-Jk7&usg=AFQjCNHpWLy9qHglhbnMF1n-2yZ4cpfCuA&sig2=CCZ3lefpE6M1ZI9peLOVBg

17:13 doh

17:13 sorry

17:13 www.cs.toronto.edu/~ajuma/326f08/11Scheme4.pdf

17:13 that was the personal google junk

17:14 Retonator: thanks pstickne

17:14 Chouser_: Retonator: http://groups.google.com/group/clojure/tree/browse_frm/thread/3edf6e82617e18e0#doc_3cd0cb80a93aae4a

17:14 That's the thread where cgrand schooled me on this particular issue.

17:15 Retonator: thanks Chouser i will read up on the thread thank you guys very helpfull :D

17:16 Chouser_: pstickne: a literal null char: \o0

17:16 or: \u0000

17:16 cconstantine: Could someone help me make use of agents to have the (rest) of my lazy-seq computed in a thread? I'll be paste-bin'ing the simple counting lazy-seq I want to work with.

17:18 lisppaste8: cconstantine pasted "counter" at http://paste.lisp.org/display/77397

17:18 pstickne: Chouser_: for some reason it refuses to show up when printing, even with pr*

17:18 Chouser_: I'd expect pr to put back in the character escapes?

17:19 or...

17:19 hiredman: ,(prn \o0)

17:19 clojurebot: \

17:20 Chouser_: yeah, it's trying to print "\" and then the actual null char.

17:20 the printer could probably use a patch.

17:22 Raynes: This is comical. Everyone waited until March 21 to post in my March 20 thread. :>

17:27 cconstantine: Chouser_: I got my prime number generator to be within 5x the speed of yours instead of 100000x the speed of yours :)

17:28 kotarak: Is there a function returning the class denoted by a symbol or returning nil if there is no such class? Everything throws an exception, I'm too stupid to catch...

17:33 cmvkk: where are you getting symbols of class names?

17:34 Chouser_: kotarak: you tried 'resolve'?

17:34 it does vars too, though

17:34 ,(resolve 'String)

17:34 clojurebot: java.lang.String

17:34 kotarak: Chouser_: I tried, ns-resolve. But I found out it works at the Repl. My jvm instance could use a restart it seems.

17:37 Chouser_: hm.

17:38 kotarak: Yep. Code was not reloaded correctly.

17:38 Not it seems to work.

17:38 Now

17:38 Chouser_: ,(resolve 'map)

17:38 clojurebot: #'clojure.core/map

17:38 Chouser_: I guess you can check if the returned thing is a class or not, if you care.

17:39 kotarak: (Although I'd still like a function returning nil if nothing is found)

17:40 Hooray. Omni completion is working almost completely now. Only fully qualified classes are still missing. :D

17:42 AWizzArd: kotarak: sounds great!

17:43 btw, is it an inconsistency that SOME does not end with a questionmark? (such as every? for example)

17:44 Chouser_: no, because some returns the value returned by the predicate, not a simple truth value

17:44 kotarak: AWizzArd: Clojure is awesome. The rough prototype was working in almost no time. The rest is just polishing and some corner cases.

17:45 Chouser_: ,(some seq [nil [] () {} [1 2 3]])

17:45 clojurebot: (1 2 3)

17:45 cmvkk: Chouser_ re: that thread you posted a minute ago, i don't know why you need an atom to write reduction without blowing the stack.

17:46 AWizzArd: Chouser_: okay, this sounds plausible

17:48 hiredman: ,(some seq [[1 2 3 4] [1 2 3]])

17:48 clojurebot: (1 2 3 4)

17:48 hiredman: ah

17:48 it returns the first of course

17:51 Chouser_: cmvkk: cgrand's explanation was insufficient?

17:51 cmvkk: well i get that the version you had previously was O(n^2), but you don't need mutation to make it O(n) is what I mean...

17:51 maybe i'm misunderstanding what the point of all that was?

17:52 pstickne: I and getting grief when trying to use ^ at the end of symbols.

17:52 What magic is happening? :(

17:52 Chouser_: oh, no, earlier in the thread I had a couple implementations of reduction without using mutation.

17:53 cmvkk: so what was it that mutation solved? just making it faster?

17:53 a faster O(n)?

17:54 Chouser_: I believe the version that blew the stack has a property I called "cute" :-)

17:54 cmvkk: heh

17:54 so then when he says "I searched for a way to define

17:54 recursively such lists but the only way I found involves using mutation.

17:54 Now with an atom it must be cleaner."

17:55 Chouser_: right, my earlier definitions used a separate function which recursed.

17:55 this requires more code

17:56 kotarak: pstickne: ^ is not allowed in symbol names

17:56 pstickne: kotarak: :(

17:56 cmvkk: so it's not that there's no way to recursively define a list like that without using mutation.

17:56 i guess i was confused by that sentence.

17:56 Chouser_: several problems have these recursive lazy seq solutions, but the naive implementation blows the stack

17:56 hiredman: ,(symbol "^")

17:56 clojurebot: ^

17:56 kotarak: pstickne: here is more info http://clojure.org/reader

17:56 pstickne: I wish more symbols were valid -- what is a good way to do "prime"

17:56 like a, a', a'', etc?

17:56 hiredman: pstickne: I have been using -

17:56 pstickne: meh :p

17:57 hiredman: a-, a--, a---

17:57 *shrug*

17:57 ,a^

17:57 clojurebot: java.lang.Exception: Unable to resolve symbol: a in this context

17:57 Chouser_: so cgrand wrote rec-seq and rec-cat to allow solutions nearly as cute, but more efficient.

17:57 pstickne: maybe I'll go find some nice unicode...

17:57 what happens to the ^?

17:57 kotarak: ^ retrieves meta data => reader macro

17:57 hiredman: yeah

17:57 cmvkk: Chouser_ hmm. I was just thinking about this the other day:

17:58 hiredman: ,(symbol "a^")

17:58 clojurebot: a^

17:58 cmvkk: I had coded up a macro form called lazy-loop, that worked like loop/recur but with 'give', whose first argument was a return value, and it all evaluated to a lazy-seq

17:58 is that what rec-seq is like?

17:58 Chouser_: ,(read-string (pr-str (symbol "a^")))

17:58 clojurebot: a

17:59 Chouser_: cmvkk: interesting!

17:59 'give' has to be in tail position?

17:59 cmvkk: i.e. (lazy-loop [i 0] (give i (inc i))) would be equal to (iterate inc i)

18:00 give would just be a macro that expands to (cons ~(first args) (fn-name ~@(rest args)))

18:00 hiredman: hah, cute

18:00 cmvkk: or something like that. the version i have written up is a little more complicated because it does more.

18:00 Chouser_: quite interesting.

18:00 cmvkk: it seems like it would be a useful form. it could do stuff for can't, right?

18:01 Chouser_: I've converted a few loop/recur's to lazy-seq-producers, and I don't remember it being a straightforward process.

18:01 cmvkk: lazy-loop would have to expand into something like (let [fn-name (fn fn-name [args] body)] (fn-name inits))

18:01 Chouser_: My flight should be boarding soon, so I may disappear with out further notice at any moment.

18:01 cmvkk: where the inital bindings are split into pairs for args and inits.

18:02 the only issue is that fn-name has to be the same for every expansion.

18:02 Chouser_: yes, lazy-loop is quite different from for

18:04 loop/recur (and therefore lazy-loop I assume) is good for looping when there's no seq controlling the process. 'for' is not.

18:04 cmvkk: right.

18:05 Chouser_: there are only a couple ways I can think of to make a seq from a non-seq: lazy-seq with recursion, iterate, repeat

18:06 cmvkk: well those are the only ways, right?

18:06 Chouser_: that I can think of, yes. :-)

18:06 cmvkk: repeatedly is another built-in that does it I guess

18:07 Chouser_: oh, indeed. nearly as boring as repeat

18:07 iterate can be made to do impressive things if you're determined to use it.

18:07 Don't know why you would be, though.

18:08 I'd be curious to see how different a lazy-loop/give form is from an equivalent recursive fn with lazy-seq

18:08 cmvkk: well the former would just expand into the latter.

18:09 Chouser_: yes, but I mean the user's hand-written form of each.

18:10 toodles!

18:10 cmvkk: hmm

18:12 Raynes: I'll miss him dearly.

18:12 * Raynes cries on cmvkk's shoulder.

18:18 lisppaste8: cmvkk pasted "lazy-loop" at http://paste.lisp.org/display/77400

19:05 cconstantine: if you do a send-off to an agent, does a deref of the returned agent want till the function passed to send-off returns?

19:05 hiredman: nope

19:06 cconstantine: if I want to ensure the the func has been called I have to wrapp the returned agent in a await?

19:20 dnolen: so does anybody know why definline is still considered "experimental" ?

19:23 pstickne: I wish arity errors contained the actual/expected :(

19:24 hiredman: yes

19:24 dnolen: hiredman: you know?

19:24 hiredman: dnolen: no

19:28 pstickne: silly me. doto is not prog1

19:39 hjlee: hiredman: do you remember yesterday's conversation with me?

19:40 [(first (rsubseq sc < key)) (first (subseq sc > key))]

19:40 hiredman: ,(doc subseq)

19:40 clojurebot: "([sc test key] [sc start-test start-key end-test end-key]); sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true"

19:40 hjlee: subseq and rsubseq are in log(n).

19:41 * hiredman scrolls back for a while

19:49 hiredman: 2009:Mar:20:15:33:15 hjlee : ah.. but I want it in constant time. (so many keys, so many operations)

19:50 log(n) is hardly constant now is it?

19:58 hjlee: yes, so i take back constant to log(n) some second later.

20:02 hiredman: well, then you have found what you are looking for, mazel tov, we should all be so lucky

20:36 Raynes: kib2 was in #concatenative. Traitor.

20:48 hjlee`: ,(doc subseq)

20:48 clojurebot: "([sc test key] [sc start-test start-key end-test end-key]); sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true"

20:49 hjlee`: ,(doc subseq)

20:49 clojurebot: "([sc test key] [sc start-test start-key end-test end-key]); sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true"

20:58 hjlee: clojurebot: hi

20:58 clojurebot: rhickey is a T-1000 sent from the future

20:58 hjlee: clojurebot: really?

20:58 clojurebot: Gabh mo leithsc�al?

20:59 hjlee: clojurebot: who made you?

20:59 clojurebot: Huh?

21:00 p_l: who taught clojurebot gaelic (or welsh or whatever exactly it is)?

21:10 hjlee: what is your irc client?

21:11 p_l: mine? irssi

21:11 Raynes: rhickey: http://clojure.org/libraries Under Clojure+Processing "A wrapper for the Processing (processig.org)..." Processing is typo'd here.

21:14 rhickey: Raynes: fixed -thanks

21:15 Raynes: No problem.

21:16 dreish: What's the shortest way to eliminate reflection in (.foo (h :somekey)) ?

21:17 hjlee: i'm clojure and irc newbie, and trying irc clients.

21:17 danlarkin: dreish: typehint (h :somekey)

21:17 dreish: I don't seem to have a typehint function.

21:18 Obviously I could do it with a let, pulling the expression apart, but is there a way to do it inline?

21:18 danlarkin: it's not a function... it's attaching special metadata to what you want to hint

21:18 so (.foo #^java.util.Date (h :somekey))

21:18 for instance

21:19 dreish: I tried that, and it didn't appear to actually do anything.

21:19 danlarkin: it'll get rid of the reflection

21:19 if that's where it's coming from

21:19 Raynes: duck1123: I was wondering whether or not you were a Clojurist. I wasn't sure how you found my twitter :p

21:21 dreish: danlarkin: So it does. I misled myself by trying to apply a wrong type hint to the result of +.

21:21 + obviously didn't need it in that case.

21:22 (This is all because I was too lazy to look up the name of *warn-on-reflection*.)

21:33 hjlee: ,(doc list)

21:33 clojurebot: "([& items]); Creates a new list containing the items."

21:55 hjlee: clojurebot: there?

21:55 clojurebot: Huh?

21:56 hiredman: clojurebot: translate to kr are you korean?

21:56 bah

21:56 clojurebot: translate to ko are you korean?

21:56 clojurebot: ??????

21:58 pstickne: clojurebot: translate to ru this is fun!

21:58 clojurebot: ??? ??????!

21:58 pstickne: heh

21:58 Russian always looks so funny to me!

21:58 hjlee: k....

21:59 pstickne: clojurebot: translate to en hello!

21:59 clojurebot: hello!

21:59 hjlee: hiredman: how do you know about clojurebot features?

21:59 pstickne: *whew* basic test passes :p

21:59 hiredman: I wrote them

22:00 pstickne: (hjlee: that means he forgot all the really cool ones)

22:01 hjlee: wow,

22:01 hiredman: clojurebot: where are you?

22:01 clojurebot: http://github.com/hiredman/clojurebot/tree/master

22:04 Raynes: hjlee: Welcome to #Clojure may I take your order? I'd like to recommend our special - A hot bowl of parentheses and a side of Macros with Multimethods for desert.

22:06 hjlee: anyway I'm korean. first translation awed me.

22:07 pstickne: hjlee: how did it translate? :p

22:08 hjlee: it translates something like : korea?

22:08 p_l: clojurebot: translate to pl This is fun!

22:08 clojurebot: To jest zabawa!

22:08 Raynes: clojurebot: translate to ko Clojure rocks!

22:08 clojurebot: Clojure ??!

22:08 * p_l can find several wrong things with that translation and it would still be correct... gotta love complicated languages

22:09 Raynes: Can it to lojban? hiredman make it to lojban :).

22:11 hjlee: lol, rocks translated to a noun.

22:11 hiredman: dnolen: ping?

22:13 hjlee: it uses google's translate service

22:13 p_l: which means a statistical engine, not one that understands what the hell it is translating :)

22:14 hiredman: p_l: sounds like google all right

22:14 p_l: hiredman: doesn't mean such approach doesn't work

22:15 hiredman: sometimes

22:15 I wish it did esperanto

22:38 p_l: ~and suddenly...

22:38 clojurebot: CLABANGO!

22:47 pstickne: oh, because those are clear

22:47 slashus2: .?.

22:47 hehe

22:50 pstickne: if I ever design a language, every symbol operator would have to be associated with a named function :p

22:50 hiredman: they are named

22:50 the name is .?.

22:51 pstickne: no, no, a what-is-that-thing-supposed-to-do-name

22:51 so .?. would be valid as long as it was "associated" with a long name

22:52 hiredman: a long name? like .....?......?

22:52 pstickne: something useful, hopefully

22:52 e.g. /: might be called fold-left

22:53 (or the correct name, even)

22:53 hiredman: so, basically you are moving backwards to only allow a subset of ascii?

22:53 pstickne: no.

22:53 symbol names are great. but they should be tied to something with a "speakable" name.

22:53 slashus2: self-documenting function names is what pstickne is trying to get at.

22:54 pstickne: while + is "speakable", .?. "period question-mark period" does not justice

22:54 so I would allow .?. if-and-only-if there is a named function that is associated with it (e.g. they would be interchangeable)

22:54 *no

22:59 cconstantine: I made a function that returns a lazy-sequence much like 'range' does, but it doesn't have an upper-bound ( http://paste.lisp.org/display/77397 ) I did some timing with it and found that it is 8 to 10 times slower than 'range'

23:00 the only difference I can find is that for numbers that fit within MAX_INT, a java native class Range is used instead of a clojure-implemented iseq.

23:01 Any number I create, either as a '1' or (int 1) is a java.lang.Integer instead of a primative int... and I think this is the source of the slow-ness. Is there anyway to get a real primative or is this just a limitation of clojure?

23:01 pstickne: cconstantine: sounds like side-effect Java is kicking the poo out of Clojure :-)

23:01 (plus, working directly with a native type)

23:02 cconstantine: I would hate to blame the autoboxing right away, though (but from what I understand, this is the only support Clojure has)

23:03 cconstantine: I'd hate to blame it too... but man

23:03 zpinter: would somebody please point me to the best way to apply a function to all the values of a hashmap and return a new hashmap of the result?

23:03 pstickne: cconstantine: what if you write a side-effect class in clojure

23:04 cconstantine: pstickne: umm, no?

23:04 zpinter: i'd like to convert a key value map where all the values are strings to a key value map where all values are integers

23:04 pstickne: cconstantine: well, you want to compare speed, so use a Java member :)

23:04 cconstantine: of a class, or write a Java version that only uses Integer

23:05 cconstantine: then you can see what part is to blame better

23:05 zpinter: the closest i can come up with so far is this: (map (fn [[k v]] [k (Integer. v)]) myhash) but it returns an array of arrays instead of a hash

23:05 cmvkk: yes.

23:05 try wrapping that with (into {} ...)

23:06 pstickne: apply and hash-map should also do the trick...

23:06 cconstantine: pstickne: well.. I think if I can make use of Range when within MAX_INT I could speed up my counter

23:14 zpinter: cmvkk, pstickne... got it with: (apply merge (map (fn [[k v]] {k (Integer. v)}) myhash))

23:15 cconstantine: odd, so if I create a clojure.lang.Range myself I'm still almost 8x slower than 'range'

23:19 ok, I'm at a loss... a raw clojure.lang.Range is slower than my 'counter' for numbers up to 10 million

23:19 Raynes: That's a lot of numbers.

23:20 pstickne: he's a counter!

23:20 :-)

23:20 * Raynes staps pstickne with a new Object()

23:20 cconstantine: well.... I'm anoyed at the required 'end' on range

23:21 * pstickne throws up catch (Throwable x) {}

23:21 cmvkk: you can just make it MAX_VALUE or whatever.

23:21 Integer/MAX_VALUE i mean

23:21 cconstantine: it seems like lazy-sequences are a better than looping in clojure

23:22 pstickne: with loop/recur?

23:22 Raynes: Why not just do (iterate inc 1)?

23:23 cconstantine: Raynes: That's also really slow compared to range

23:23 cmvkk: (take end (iterate inc 0)) is what range uses, whenever end isn't an acceptable integer.

23:23 cconstantine: exactly

23:24 cmvkk: so you want something that's infinitely long, right? you can't implement that with clojure.lang.Range, right?

23:25 cconstantine: cmvkk: Shouldn't there be a way to use clojure.lang.Range for numbers up to MAX_VALUE?

23:25 cmvkk: (new clojure.lang.Range 0 Integer/MAX_VALUE) ?

23:25 cconstantine: cmvkk: is unfortunately fairly slow

23:26 cmvkk: can't be slower than range...since that's how range is implemented.

23:26 cconstantine: You'd think ;)

23:27 cmvkk: well, range returns a clojure.lang.Range with the arguments you give it...so if you do that, compared to range, you're going to get exactly the same type of object.

23:27 you're not even doing anything different.

23:27 lisppaste8: cconstantine pasted "Counter experiment" at http://paste.lisp.org/display/77411

23:27 Raynes: You can't go faster than light speed.

23:28 cconstantine: cmvkk: I know :) I got the clojure.lang.Range from the clojure implementation of range

23:28 Raynes: What about Ludicrous speed? :P

23:29 slashus2: You definitely can't go faster than Ludicrous speed.

23:29 Dark helmet about died going that fast.

23:29 * cconstantine is glad *someone* got that :)

23:30 Raynes: cconstantine: I would have gotten too tired waiting for those to complete.

23:30 cmvkk: cconstantine: is it a take issue?

23:30 your middle test, the one with range, is the only one that isn't wrapped in a take argument.

23:30 cconstantine: cmvkk: I'll try that

23:30 cmvkk: or a take function, i mean

23:31 cconstantine: that was it

23:32 which suggests with my numbers that my counter is 2/3 as fast as range.. which isn't nearly as disgustingly slow.

23:32 well.... 5/7 as fast

23:33 Thanks :)

23:38 cmvkk: excellent. i forgot about reflection until now,

23:38 i had rewritten my framework to use lazy-seqs instead of closures and atoms, and was dissapointed to find that it was 4 to 5x slower.

23:39 but i tested for reflection, and realized i had just written one of the functions wrong, without type hints. now i think it might actually be faster than the old version.

23:39 i like it when that happens.

Logging service provided by n01se.net