#clojure log - Jul 03 2009

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

0:46 CoreyWhite: Does anyone know of a syntax highlighter with Clojure support? Or with generic Lisp support that would be fairly easy to adapt to Clojure? (For the web, preferably javascript/jQuery, although I could live with something server-side in PHP.)

0:47 I'm aware of the Clojure plugin for SyntaxHighlighter (here: http://travis-whitton.blogspot.com/2009/06/syntaxhighlighter-for-clojure.html), which is quite good . . . but unfortunately SyntaxHighlighter messes with my markup in very unpleasant ways.

0:53 gstamp: http://kai.myownsiteonline.com/clojure/html.clj.html

0:55 CoreyWhite: that seems pretty excellent! Is that your site?

1:04 gstamp: No not mine. There was a recent thread in the mailing list. I plucked the URL from that.

1:05 Thread was titled "Displaying Clojure code on a Website" if you'd like to look it up

1:12 Knekk: anyone here use vimclojure?

1:28 Chouser: gah. why can't I have a reader hook!?

3:00 mrpika: t

3:00 oops

3:06 Knekk: for a large(ish) multi-dimensional array of mutable data should I use vectors of refs? or Java arrays?

3:08 parthm: Knekk: If you want java interop + performance you can use java arrays

3:09 are there multiple threads in your program operating on the data?

3:09 Knekk: Would only need performance for the array. I can define the data itself without java interop

3:09 yeah, multiple threads will manipulate the data

3:10 parthm: refs of vectors can be a start. if you feel performance is bad you can switch to arrays

3:10 vectors have a lot of functions to work on them

3:11 Knekk: that's what I am seeing, yeah

3:11 parthm: for most cases vector performance is fine

3:11 Knekk: I am blowing the heap space trying to create the vectors. Need to get my head around the implications here

3:12 parthm: hmm ... do you need all the initialization up front or maybe it can be lazy

3:14 Knekk: even if it's lazy I'll be iterating across all the array elements a number of times to do transformation on the data pretty fast, so all elements will be accessed

3:16 * Knekk hugs VimClojure

3:19 parthm: I probably don't get the use case but even the computation should be delayed and only the relevant values should be generated/computed.

3:19 user=> (time (def y (map (partial + 1) (range 10000000))))

3:19 "Elapsed time: 0.904514 msecs"

3:19 #'user/y

3:19 user=> (take 5 y)

3:19 (1 2 3 4 5)

3:19 user=> (take 5 (drop 1000000 y))

3:19 (1000001 1000002 1000003 1000004 1000005)

3:19 user=>

3:20 sometime I have seen the stack blow when we hold on to the head somewhere.

3:21 Knekk: I am probably not using the proper methods then. I am a n00b. Using (apply vector (map (fn [_] (ref (struct my-struct))) (range large-number))

3:21 ))

3:22 to create one dimension of the array

3:23 Lau_of_DK: apply forces evaluation, thats not the same as parthm's example above

3:24 Knekk: I was basing mine on a different example, and that'd explain why I am blowing the heap

3:46 * Knekk hugs loop/recur

4:46 Knekk: ok, so now I have a better lazy approach to creating a multi-dimensional array of refs

4:52 night

5:22 laggy tonight

6:46 Chousuke: Chouser: are you handling the clojure-1.0 compatible contrib branch?

8:01 AWizzArd: Is there an efficient built-in function that removes an element from a vector at position n?

8:20 rhickey: AWizzArd: can't be

8:26 AWizzArd: rhickey: is it planned to add new immutable data structures to Clojure, such as doubly linked lists or skiplists?

8:27 rhickey: AWizzArd: finger trees would be welcome

8:27 http://en.wikipedia.org/wiki/Finger_tree

8:30 AWizzArd: Finger trees or skiplists ( http://en.wikipedia.org/wiki/Skiplist ) would have to be implemented in Java for performance reasons yes?

8:32 rhickey: no

8:34 any data structures need to be persistent

8:34 AWizzArd: yes

8:34 rhickey: so, doubly linked lists not possible

8:34 qra: hi clojure group, this is first time I entered this channel.

8:35 rhickey: qra: hi

8:36 AWizzArd: I see, didn't think about that yet. Anyway, what would you do if you wish to conj up a vector V of structs over which (V) you then run a unification and pattern matching algorithm that wants to remove at (possibly random) positions elements and add new ones?

8:37 rhickey: AWizzArd: what's the significance of the positions?

8:37 qra: how to force 'for' to run through all items in a lazy list?

8:38 durka421: qra: doall

8:38 or you may be looking for doseq instead of for

8:38 qra: ok

8:38 rhickey: qra: if your 'for' is only for side effects, use doseq instead, otherwise you can call doall on the result of for

8:39 or vec

8:41 AWizzArd: rhickey: if the positions won't be important then maybe a set would be right. But if the order must stay the same it is not so easy anymore.

8:43 rhickey: AWizzArd: for splicing we need finger trees

8:43 AWizzArd: I see

8:49 qra: (for [i last-list] (doall (println i)) wont work?

8:50 durka42: for produces a lazy seq, so you want to wrap doall around the entire thing

8:50 (doall (for ...))

8:51 qra: ok, but i cant understand what's going on

8:51 rhickey: qra: for is designed to return a sequence of values

8:51 but yoiu just want to perform a sequence of side effects, so use doseq

8:52 (doseq [i last-list] (println i))

8:52 qra: doseq throws some error it expects vector, but I have only lazy-list

8:53 rhickey: for produces the values lazily, so if you never use them, it never produces them

8:54 qra: try: (doseq [i (range 3)] (println i))

8:54 at the repl

8:55 qra: thank u, it works.

9:02 tashafa: hello all

9:02 danlarkin__: salut!

9:02 tashafa: whats up danlarkin

9:02 danlarkin__: it's finally sunny!

9:03 tashafa: not in mass :(

9:03 danlarkin__: maybe... just maybe it can last all day

9:03 tashafa: massachusetts

9:03 i dont think ive seen the sun in a month

9:04 danlarkin__: I was in Boston last weekend, and driving home was hilarious. I left boston in a hazy cloud cover and like 30 minutes west it turned into a beauuuutiful day

9:05 tashafa: thats new england weather for you

9:06 sgtarr_: england weather is worse.

9:06 tashafa: clojure ques.

9:06 sgtarr_: ques?

9:07 tashafa: it escapes me but how do you extend a java class again and override a method

9:07 ?

9:07 in clojure ofcourse

9:07 :)

9:08 sgtarr_: i can tell you how to do it in java.. :)

9:08 danlarkin__: proxy

9:09 unless proxy is gone now

9:09 it's been a few weeks since I've used clojure :(

9:09 tashafa: same here

9:09 sgtarr_: haha

9:09 clojure changes that quickly?

9:09 tashafa: i've been in python world

9:09 sgtarr_: the cutting edge!

9:09 tashafa: welcome back to civilization...

9:10 naw, I shouldn't talk like that about Python. I use it often and i've used it for many projects since approx 2002

9:10 But there are some things that bug me...

9:10 and java is just much better for Enterprise

9:10 tashafa: yup... procedural programming is just mind numbing

9:12 after messing with clojure that is

9:13 sgtarr_: yea

9:13 tashafa: how did you get involved with clojure?

9:14 interest in lisp from before?

9:14 tashafa: by way of paul graham

9:14 but common lisp was just hard to get started with

9:16 sgtarr_: yea

9:16 I was always fascinated by Lisp

9:16 and there is a finance company that I was familiar with that used Lisp exclusively, still do, but they used LispWorks afaik

9:17 tashafa: cool

9:21 sgtarr_: I remember that asteroid probe Deep Space 1 also ran Lisp

9:21 durka42: really?

9:22 sgtarr_: It still does actually, even though its ion thrusters have been off since 2001

9:22 Lisp up there in space, still running silently :)

9:22 durka42: the first google result for "deep space 1 lisp" is that rant about how JPL lost faith in lisp

9:23 sgtarr_: really? weird

9:23 check out http://en.wikipedia.org/wiki/Deep_Space_1#Remote_Agent

9:23 the RAX software was lisp

9:23 and the mission was a huge success

9:24 from your article:

9:24 "Based on this experience I think it's safe to say that if not for Lisp the Remote Agent would have failed."

9:25 "Debugging a program running on a $100M piece of hardware that is 100 million miles away is an interesting experience. Having a read-eval-print loop running on the spacecraft proved invaluable in finding and fixing the problem."

9:25 Nice. REPL 100 million miles away

9:38 tashafa: hmm

9:39 how do you call methods on the parnet class (super) in proxy?

9:43 proxy-super

9:45 Chousuke: hm, is that even possible?

9:51 AWizzArd: Is there (maybe in contrib) a foo for doing (foo [1 2 3 4 :x 5 6 7 8 :x 9 10 :x 11]) ==> ((1 2 3 4) (:x) (5 6 7 8) (:x) (9 10) (:x) (11)) ?

9:52 split-at, split-with, take-while, partition-by, group-by and others don't work

9:55 my foo call was not complete, it misses something like #(= % :x) or #(not= % :x)

10:02 tashafa: Chousuke: I have no idea

10:02 but shouldnt it be?

10:29 Chousuke: http://dishevelled.net/Tricky-uses-of-Clojure-gen-class-and-AOT-compilation.html

10:32 Chousuke: interesting

11:31 lisppaste8: AWizzArd pasted "How to group/split contents of a collection into groups?" at http://paste.lisp.org/display/82957

11:32 rzoom: is there a github issue?

11:33 rob@eniac:~$ git clone http://github.com/richhickey/clojure

11:33 Initialized empty Git repository in /home/rob/clojure/.git/

11:33 fatal: http://github.com/richhickey/clojure/info/refs not found: did you run git update-server-info on the server?

11:42 nevermind

11:43 in the future, use the github specified Clone URL, for .... you know ... cloning

11:43 e.g. git clone git://github.com/richhickey/clojure.git

11:52 cgrand: AWizzArd: (s/partition-by #{:x} [1 2 3 4 :x 5 6 7 8 :x 9 10 :x 11])

11:52 where s is seq-utils

11:53 AWizzArd: cgrand: ah good, that is much better

12:23 jackdempsey: rzoom: yea, .git on the end :)

12:49 lisppaste8: codyK pasted "already in zip libraries?" at http://paste.lisp.org/display/82962

13:38 Lau_of_DK: Good evening gents

13:39 dysinger: sup

13:50 jackdempsey: evenin

14:53 * Chouser just got this working: (git cherry-pick --no-commit ~(:sha1 patch))

15:31 jackdempsey: anyone familiar with compojure round these parts?

15:39 is there an idiomatic approach for getting the current time in clojure?

15:39 reading a variety of ways to ask java, and prety much all end with

15:39 "i hate the Calendar class" :-)

15:42 Lau_of_DK: I use Joda time for that stuff

15:42 And yea, Compojure is hot

15:42 *sizzle*

15:43 jackdempsey: k, saw Joda mentioned before as well, gotta check it out it seems

15:44 sigh

15:44 This page is unavailable at the moment. Please try again shortly. Sorry for the inconvenience.

15:44 oh the yak shaving :-)

15:46 technomancy: the JDK calendar is horrible, but if all you want is the current time, it's not bad

15:46 (java.util.Date.)

15:48 jackdempsey: hey technomancy , yeah, thanks man, i'm ultimately looking for just the current time in a unix style timestamp

15:48 i thought it'd be fun to rewrite this in clojure/compojure: http://github.com/jcapote/watercoolr/blob/125707e211b0a3cb6462ea405bb77aefb1618f8b/watercoolr.rb

15:48 good exercise to learn more, etc

15:48 lisppaste8: Lau_of_DK pasted "Macro this!" at http://paste.lisp.org/display/82973

15:48 Lau_of_DK: Boys - Can somebody shed some macrobiotic light on the question I asked in that lisp-paste ?

15:50 Chouser: macfoo always uses a function named 'foo' exactly twice?

15:52 Lau_of_DK: Yep

15:52 On the first assumption

15:52 But it will use it x number of times, depending on the length of your list, ie "mister" "#clojure" "bar" "baz" etc

15:53 @ Chouser

15:54 Chouser: Lau_of_DK: did you want to pass in the initial string too?

15:54 Lau_of_DK: That would be ideal

15:55 technomancy: jackdempsey: my first project was porting a web app to compojure too, but I found I learned more from writing Mire; I kind of fizzled out on the web app.

15:55 jackdempsey: heh gotcha

15:56 yeah its kinda painful so far

15:56 technomancy: web apps just have too much incidental stuff to worry about

15:56 jackdempsey: especially coming from rails

15:56 technomancy: might be better to tackle that domain once you've got a grasp on the core language

15:56 jackdempsey: ah

15:56 i see what you mean

15:56 not a bad point

15:56 Chouser: (defmacro macfoo [string & subs] `(-> ~string ~@(for [sub subs] `(foo ~sub))))

15:56 jackdempsey: my eyes are starting to glaze over

15:57 hmm

15:57 this isn't too bad tho

15:57 (/ (. System currentTimeMillis) 1000.0)

15:57 Lau_of_DK: Chouser: Man thats nasty :)

15:58 It was the ~@(for...) I couldnt work out, but it makes perfect sense

15:58 Chouser: :-)

16:00 krumholt_: why is it every? but some without "?"

16:01 Lau_of_DK: Chouser, mind if I annote it so that others can benefit?

16:01 Chouser: Lau_of_DK: by all means.

16:01 lisppaste8: Chouser annotated #82973 "Macroed" at http://paste.lisp.org/display/82973#1

16:02 Chouser: krumholt_: the "?" suggests it'll return true or false

16:02 achim: Lau_of_DK: umm, why a macro? that's "reduce" ...

16:02 (reduce #(foo %1 %2) "hi!" ["mister" "#clojure"])

16:02 krumholt_: Chouser, ok thanks

16:02 Chouser: krumholt_: 'some' returns the value returned by the predicate -- could be something other than boolean

16:03 achim is absolutely right.

16:03 * Chouser is ashamed.

16:03 jackdempsey: heh

16:04 Chouser: I violated the first rule of writing macros.

16:04 Lau_of_DK: Achim... ehm.... I was just setting Chouser up of course, I had it figured out hours ago :)

16:04 jackdempsey: lol

16:05 Lau_of_DK: Chouser you should paste your user.clj .... (defmacro println) etc... :)

16:18 achim: did anybody here have a look at Qi?

16:18 * achim just ordered the Qi book

16:22 technomancy: can you start nailgun from an already-launched clojure instance?

16:22 i'm using (com.martiansoftware.nailgun.NGServer/main (make-array String 0)) to no effect

16:23 rhickey: achim: Qi is definitely interesting

16:29 jackdempsey: ah cool

16:29 hadn't heard of Qi

16:29 foox: i have three sub-expr in a 'let'. the third gets evaluated before the second; how can i prevent this

16:30 the second sub-expr is a doseq

16:32 drewr: technomancy: I haven't tried nailgun yet. Like it?

16:32 technomancy: drewr: works like a charm

16:32 krumholt_: how can i remove an item from a map?

16:32 technomancy: except for starting the server in an already-running instance; I can't figure that out

16:32 krumholt_: dissoc

16:33 krumholt_: thanks

16:33 technomancy: drewr: on the whole it's very simple and obvious

16:33 drewr: krumholt_: Also look at select-keys if you have a bunch to remove.

16:34 technomancy: Looked like it. I'll give it a shot.

16:34 krumholt_: thanks

16:44 technomancy: if the nailgun server is runnable, can I pass it to a new thread and have the thread run it for me?

16:44 how does that interface work?

16:45 oh, looks like that works.

17:51 dysinger_: thank goodness for #clojure's active irc channel

17:53 Chouser: hm. a joke?

17:53 Chousuke: :P

17:55 technomancy: I think he means relative to Java IRC channels

17:55 #hadoop is like a tomb

17:55 Chouser: ah

17:55 technomancy: and dysinger_ is dancing among the gravestones

17:56 dysinger_: y Chouser - seems like often Java dudes ( I am on ex-10-yr one myself ) just hang out on IRC and don't actually participate in discussion.

17:56 Chouser: ah.

17:56 dysinger_: I've tried to ask a question on #hadoop 4 times - every time there's like 60 people in there but all I get is crickets

17:56 Chousuke: Can you do the moonwalk? Maybe it'd activate the channel.

17:57 dysinger_: I ran naked through the channel

17:57 technomancy: as long as it's not the Thriller zombies...

17:57 dysinger_: but nobody said anything :)

17:57 Chouser: normally I would have assumed you were making a straight statement, but since your comment was the first in over an hour I just wasn't sure.

17:57 dysinger_: seriously :) "dysinger_ runs by naked and nobody notices [2:52pm] •"

17:57 Chouser: heh

18:03 jackdempsey: man

18:03 this is really interesting, but i feel like i'm starting to walk again

18:03 except i have arthritis from OO land

18:03 i'm staring at (let [id gen-id]....) for a while and wondering why i get the function back

18:04 maybe because thats exactly what i asked it to set id to

18:04 [id gen-id] will just st id to be the function referred to by gen-id, correct? if i actually want it to be the result i have to do (let [id (gen-id).....) right?

18:04 Chousuke: yes.

18:05 jackdempsey: cool

18:05 Chousuke: first-class functions are fun little things :)

18:05 jackdempsey: technomancy: that little web port is coming along ok....so far the hardest part has been trying to figure out what i can borrow from java......and of course some basic clojure stuff.

18:05 haha, yep

18:05 going to take a while to unlearn some bad habits

18:06 i can't wait to see what this does to my ruby....

18:06 Chousuke: jackdempsey: you'll be using code blocks a lot more I guess.

18:07 jackdempsey: yeah, blocks are already kinda ubiquitous, but i think the way i use them and approach certain problems will certainly be different

18:07 Chousuke: or then you do an assignment and go "wtf, why is the old reference changing too?"

18:07 jackdempsey: i saw somethhing in couchdb earlier and thoguth" but but but, thats a side effect, oh god no!.......oh wait........ahem"

18:07 lol

18:08 user=> (def foo #{})

18:08 #'user/foo

18:08 user=> (conj foo 1)

18:08 #{1}

18:08 user=> (conj foo 2)

18:08 #{2}

18:08 that still cracks me up....not used to it at all :-)

18:08 Chousuke: yeah.

18:08 jackdempsey: "where'd the 1 go.........oh......ha"

18:09 its definitely easier to think about things in the more pure functional sense...appeals to my math side for sure

18:09 Chousuke: I find it easier because functions become true black boxes.

18:09 once they work, you *only* need to know what they do, not how

18:09 jackdempsey: yep

18:09 exactly

18:10 "does that still set that random thing or not......have to go look"

18:10 man, i really really want to reply with something about refs and STM: http://stackoverflow.com/questions/1080993/pure-ruby-concurrent-hash :-)

18:11 arohner: Clojure makes me more irritated by ruby

18:11 I get annoyed by things like not being able to pass multiple blocks to a function

18:11 technomancy: yes.

18:12 arohner: and blocks are not a replacement for first class functions

18:12 technomancy: I find myself writing classes for pure IO and keeping them totally separate from the bulk of the logic.

18:12 but I've only written like two pages of Ruby since learning Clojure. =)

18:13 Chousuke: arohner: what, you can only pass one? :/

18:13 slashus2: technomancy: Was it your main language before?

18:13 * Chousuke is not that familiar with ruby

18:13 jackdempsey: heh

18:13 arohner: Chousuke: yes, one "normal" block. After that, you have to start passing procs around, which use a different syntax

18:13 jackdempsey: yeah, if you do def (foo, &bar)

18:13 arohner: that, and there are 6 or 7 different kinds of blocks

18:14 jackdempsey: can pass that one normal block, otherwise as arohner says you have to use lambdas

18:14 hehe

18:14 Chouser: though in a mutable language, first class functions are not a replacement for blocks

18:14 arohner: Chouser: how so?

18:16 http://innig.net/software/ruby/closures-in-ruby.rb

18:16 that is a great example of how Ruby is insane

18:16 jackdempsey: oh man

18:16 lol

18:16 really exposing the skeletons in the closet now :-D

18:16 Chouser: ruby blocks can use 'break' and such to control the loop they're in

18:16 arohner: ewww

18:16 jackdempsey: lambas can return as well....but procs return differently......and well......yea

18:17 ruby's an excellent language for some things.....but for others, not so much, and like anything, has its warts

18:17 k, workout time, later gents

18:28 codyK: is there an existing pretty-printer for xml-zip ?

18:31 Chouser: codyK: you can zip back up to the root and use 'emit' to print it as xml again.

18:35 codyK: good enough, thanks

19:11 _hrrld: Is there a function to tell me if a Var is "bound"?

19:16 Chousuke: _hrrld: (when-let [v (resolve sym)] (.isBound v)) perhaps

19:21 _hrrld: Comically, I can't seem to call resolve on an unbound symbol.

19:22 (declare x)(resolve x) ; Var user/x is unbound.

19:24 achim: _hrrld: (.isBound #'x) seems to do the trick

19:25 resolve is a function, it doesn't even see the x, the compiler tries to substitute it before calling resolve

19:28 _hrrld: That makes sense, and the hash quote does work. Thanks.

19:28 Chouser: That assumes the var exists

19:29 which is why Chousuke use 'resolve' first to see if there's even a var named by that symbol

19:37 unlink: hi

20:47 something: if I know the name of the function, is there a way to get the fn definition back during runtime?

20:59 Chouser: something: have you tried clojure.contrib.repl-utils/source ?

21:00 something: Chouser: no I didn't yet. let me take a look at that.

21:01 Chouser: it actually uses the var name not the fn, and it needs to be able to find the original .clj file in the classpath

21:01 something: Chouser: I want to figure out # of arguments a particular fn takes before I invoke it. Is there an easy way to do that?

21:02 Chouser: something: not perfectly, but you could get an 80%-type solution if you have access to the var

21:02 if the var has been resolved to an actual fn, or if the fn was never in a var, you're pretty much out of luck.

21:03 the var has :arglists metadata you can try to use

21:03 something: Chouser: awesome! let me check that out.

21:05 Chouser: the thing is even if you have the var, it's possible for the var's arglists to have been left out or changed

21:07 something: in what scenario can the arglists be left out?

21:08 Chouser: (def foo (fn [a b c] ...))

21:09 something: Chouser: right,

21:10 Chouser: I'm going after the defn case, so I should be ok, but I understand what you are saying.

21:23 Chouser: I guess the question is how to get a hold of the var when I only know the string representation of it

21:36 Chouser: something: (resolve sym)

21:46 something: Chouser: ah, thanks

21:49 Raynes: Joining #Concatenative after making less-than-nice remarks on reddit - Awkward.

23:33 Knekk: does clojure provide data/object serialization functionality (for writing to a stream, for instance) or does one need Java interop?

23:34 Chouser: Most Clojure collections can be printed as ascii that can then be read again.

23:35 There's also a *print-dup* var that can be set to make sure you get identical object types when read as when printed.

23:37 Knekk: thank you. I have too much data to keep in memory and need to find an efficient way to offline to disk

Logging service provided by n01se.net