#clojure log - Feb 08 2010

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

1:51 ajazz: hello, I have map {:a 2 :b 4}, how I can multiply each value on 3 to get {:a 6 :b 12}? I have solution but it's ugly.

1:51 http://pastebin.com/d76128f06

2:09 hoeck: ajazz: I don't think your solution is ugly

2:17 ajazz: however, if you're interested, here are two other ways: http://pastebin.com/m3136c152

2:18 ajazz: and, by the way, predicate taking functions have usually the function as the first argument and the sequences, maps, whatever as the second argument in clojure

2:41 LauJensen: Good morning

3:05 ajazz: thank you

4:44 ned: http://pastie.org/814387 does anyone know why that would happen?

4:44 it was working fine previously, the exact same code, and now it doesnt seem to work

4:49 LauJensen: Are you sure that you evaluated process-line ?

4:50 And if you're running this from the REPL, make sure you're actually in the tokenize namespace

4:52 ned: LauJensen, that was it. thank you sir.

4:52 LauJensen: np

4:56 spariev: LauJensen: hi. Could you shed some light on state of reworked ClojureQL API ? Is it ok to use it now or I'll be better off with stable version

4:58 LauJensen: sec

5:00 spariev: I am currently reviewing and extending on Meikels work on the 2.0 Frontend - I hope to complete that process within a couple of weeks. Once thats done, it will be the preferred version to work with, but now its not adviseable

5:01 spariev: laujensen: ok, thanks

5:03 LauJensen: np

5:23 ordnungswidrig: hi, all

5:25 LauJensen: yo

5:26 achew22: Is there a good tutorial on getting started with clojure?

5:28 vu3rdd: does completions work for java classes in slime? It doesn't seem to work for me.

5:29 LauJensen: achew22: setting up IDE or actually coding?

5:29 achew22: I'm interested in writing code

5:30 LauJensen: achew22: http://www.bestinclass.dk/index.php/blog/

5:30 achew22: I'm having difficulty writing a function that does more than just return a single value

5:30 that is, I would like to check 4 or 5 if statements

5:30 LauJensen: Thats my blog, there are many easy to follow tutorial style articles, if you have questions shoot them off in here - myself or someone else will be able to answer

5:30 achew22: and I don't exactly understand how to "return" something from a function

5:30 quotes because I'm not sure that's the best way to think of it, I have seen some stuff about "yielding"

5:31 LauJensen: ok

5:31 http://www.bestinclass.dk/index.php/2010/02/clojure-list-comprehension/

5:31 Start with that one, shows you how to build lists using the for loop, mimics yielding

5:32 achew22: LauJensen: I also really liked reading the article on the reddit clone when it hit HN a few weeks ago

5:32 maybe more recently than that

5:32 LauJensen: Then try this one: http://www.bestinclass.dk/index.php/2009/12/beating-the-arc-challenge-in-clojure/

5:32 Also super simple

5:32 achew22: Great :)

5:32 achew22: keep it up, that article was why I started looking at clojure over CL or straight lisp

5:33 LauJensen: And finally this one, which shows a lot of diversity http://www.bestinclass.dk/index.php/2009/12/rosetta-serving-dish-4/

5:33 Ah really? Great - I'm glad to hear it!! :)

5:34 achew22: also, keep submitting it to HN or else I won't read it ;)

5:34 that's equally important

5:35 LauJensen: I never do

5:35 achew22: hrm... then someone is doing you a favor. You might try submitting it yourself then you will be able to read the feedback from those guys

5:37 LauJensen: When I start getting a lot of traffic, I usually drop by to check out the comments

5:40 achew22: Would this make more sense if I had a lisp or java background?

5:46 LauJensen: That I don't submit links to HN? :)

5:46 achew22: No, Clojure as a general idea

5:47 LauJensen: For Java Interop, a Java background helps of course. Lisp takes a while to learn, but the main principles are extremely simple - So practice gets you far

5:47 The functional mindset takes a while to acquire, but is supremely important - this is where the actual work is

5:47 achew22: Okay, well I've been looking for a while. How do you typecast something to a string?

5:47 LauJensen: #¨String s

5:47 achew22: really?

5:48 somnium: achew22: http://java.ociweb.com/mark/clojure/article.html << might be useful

5:48 LauJensen: Thats not casting as much as adding a hint, which many times is what you want

5:48 achew22: but the documentation talks about hinting

5:48 and it only has stuff for basic types (int, float, bool) excluding strings

5:48 LauJensen: ,(apply str [\a \b \c])

5:48 clojurebot: "abc"

5:48 LauJensen: achew22: what I showed you first was a hint

5:48 Second was characters to string

5:48 (str \a)

5:49 achew22: Is that a double quote after the #?

5:49 LauJensen: No

5:50 achew22: do you have a preferred codepad?

5:51 LauJensen: codepad?

5:52 achew22: pastebin

5:52 LauJensen: ~paste

5:52 clojurebot: lisppaste8, url

5:52 Chousuke: the reader macro for type hinting is #^, not #¨ :P

5:52 achew22: Okay, is this absolutely insane http://codepad.org/8dfzxain ?

5:53 LauJensen: ah, sorry I hit the wrong key

5:53 Chousuke: I think there's an odd? predicate already

5:53 ,(doc odd?)

5:53 clojurebot: "([n]); Returns true if n is odd, throws an exception if n is not an integer"

5:53 LauJensen: achew22: Read up on cond and condp

5:53 ,(condp = 5 even? "Its even" odd? "Its odd" :else "huh?")

5:53 clojurebot: java.lang.IllegalArgumentException: No matching clause: 5

5:54 Chousuke: I really can't tell what those ands are doing there

5:54 LauJensen: Chousuke: Its a homemade cond

5:54 somnium: wouldnt that be nested ifs?

5:54 Chousuke: but it returns true if all of those return true

5:55 also, (int x) is not for converting strings to integers

5:56 you'll want Integer/parseInt

5:56 avarus: hello

5:58 achew22: Okay, so you said that #^String hints something to a string

5:58 TheBusby: Arg, so "(use 'clojure.contrib.http.agent)" now throws a state exception "bytes already refers to: #'clojure.core/bytes in namespace: user" in 1.1.0

5:58 achew22: but it says that an Integer can't be cast to a clojure.lang.IFn

5:59 TheBusby: works fine in 1.0, but is bugged in 1.1.0 ?

6:00 can anyone else replicate this please?

6:00 tomoj: replicated

6:00 ,(doc bytes)

6:00 clojurebot: "([xs]); Casts to bytes[]"

6:00 tomoj: if you like you could hide that

6:00 TheBusby: tomoj: do tell

6:00 ahh, :only?

6:01 tomoj: I haven't ever needed to do this yet, but I believe in your ns declaration use (:refer-clojure :exclude (bytes))

6:01 something like that

6:01 somnium: ,(require '[clojure.contrib.http.agent :as http])

6:01 clojurebot: nil

6:01 somnium: http/bytes

6:02 or like that

6:02 tomoj: that's what I've been doing

6:02 TheBusby: so then http.http-agent?

6:03 tomoj: /

6:03 or, like you say, you could :use :only to pick out what you need

6:03 TheBusby: I guess my lazy-ness regarding including everything is catching up to me

6:03 still that's kind of a nasty surprise

6:03 tomoj: I kind of like that or :require :as better since it makes it easier to tell where a function is coming from

6:03 opqdonut: any indentation guidelines?

6:03 tomoj: though M-. is amazing

6:03 TheBusby: ah, good point

6:04 tomoj: clojurebot: style?

6:04 clojurebot: style is http://paste.lisp.org/display/81021

6:04 tomoj: hmm

6:04 clojurebot: style guidelines?

6:04 clojurebot: Huh?

6:04 konr: I need to write a program that generates a pdf file, but Clojure's startup time makes a stand-alone program dedicated to that unacceptably slow. What are the alternatives? I'm considering creating a server, containing this and possibly other utilities, to minimize the problem.

6:04 TheBusby: nailgun

6:04 http://martiansoftware.com/nailgun/index.html

6:05 tomoj: opqdonut: http://mumble.net/~campbell/scheme/style.txt

6:05 TheBusby: tomoj & somnium: thanks!

6:05 konr: TheBusby: hmm, the same used by vimclojure, it seems... thanks!

6:11 avarus: konr: if the pdf is simple you could use lout

6:11 konr: that would be fast only with simple documents :)

6:12 or embed jetty!

6:12 and wait for a request :)

6:13 you could use compojure as a web framework...makes embedding probably easier

6:13 AWizzArd: yes, the pdf producing code could be a RESTful webservice.

6:14 Then your shell tool can make a http request to your localhost or a google apps application which generates in Compojure the pdf.

6:16 tomoj: facebook developer wiki has been down for.. must be at least 48 hours now :(

6:30 avarus: guys...clojure-mode is fine :)...I did the step and learned some emacs basics

6:43 raek: I want to make a subclass of Exception, (how do|should) I do it in clojure?

6:54 hmm, what happened to gen-and-load-class?

6:56 hoeck: raek: its gen-class now, preferably used within (ns :gen-class <gen-class-args>)

6:57 raek: for instant interface implementation, deftype is the way to go (in the latest 1.2-master branch)

6:58 raek: "When not compiling, does

6:58 nothing."

6:58 is this true for :gen-class too?

7:00 hoeck: raek: yes, you have to compile in order to generate a working .class

7:01 raek: maybe deftype will simplify this...

7:02 ordnungswidrig: does anybody know about a validation lib for clojure?

7:05 hoeck: raek: it greatly simplifies implementing interfaces, and creates a named type when its AOT compiled

7:14 esj: tomoj: http://groups.google.com/group/clojure-dev/browse_thread/thread/d090b5599909497c

7:26 tomoj: esj: cool, thanks

7:26 avarus: great!

7:44 avarus: it's really awesome how clojure-mode works

7:44 caljunior: ,(let [boing (atom nil)])

7:44 clojurebot: nil

7:44 avarus: that's not comparable to gedit, textmate etc...

7:44 tomoj: "Use (:property foo) to access objects, but (foo :property) to reach into collections. The difference communicates what you think foo is."

7:44 can someone say that in different terms?

7:45 I don't understand what it means by "access objects" vs "reach into collections"

7:45 caljunior: (let [boing (atom nil)] (swap! boing assoc 1))

7:45 tomoj: avarus: :P told you you'd see the light

7:45 caljunior: ,(let [boing (atom nil)] (swap! boing assoc 1))

7:45 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$assoc

7:46 avarus: hehe

7:46 tomoj: I didn't know you could assoc nil

7:46 avarus: can clojurebot also do swing guis? :P

7:46 caljunior: how do I swap the value of the atom?

7:46 Chousuke: tomoj: in the former case, foo represents something opaque, while in the latter case it's just a collection (and you're allowed to mess with its contents freely)

7:47 caljunior: tomoj: you can if nil is in a vector or a set.

7:47 tomoj: hmm, how is it things become able to be passed as the arg to a keyword function?

7:48 ,(assoc nil :foo :bar)

7:48 clojurebot: {:foo :bar}

7:48 tomoj: that's what I meant

7:48 Chousuke: tomoj: keywords are functions of associative things.

7:48 ,(ifn? :foo)

7:48 clojurebot: true

7:49 tomoj: so besides collections, that would be.. datatypes?

7:49 Chousuke: I think the things need to implement IAssociative

7:49 somnium: wow, you can assoc onto nil, is that accidental (seq {}) or something?

7:50 Chousuke: somnium: I guess nil is just treated as an empty map.

7:50 tomoj: I'm just trying to think of examples where you're doing (:property foo) and foo is not a collection

7:50 AWizzArd: somnium: convenience functionaliy

7:50 +t

7:50 Chousuke: tomoj: the difference between an object and a collection is purely logical

7:51 tomoj: you might have {:foo bar} represent an object so you would access it as (:foo ...)

7:51 tomoj: oh, "what you think foo is", I see

7:52 on the other hand you might have a map of ids -> objects or the like, which would be (foo :an-id), then?

7:52 I think I understand now, thanks

7:56 avarus: mhmh...

7:56 "clojure.contrib.sql/with-connection dbc (clojure.contrib.sql/transaction" <-- is there a "way" to make that short? :P

7:56 tomoj: caljunior: you mean just reset it, ignoring what it was before?

7:57 swap! wants a function to call with the value of the atom as a first arg

7:57 in your example, assoc takes at least 3 args and you only have 2 (nil and 1)

7:57 ,(let [boing (atom nil)] (swap! boing assoc 1 2))

7:57 clojurebot: {1 2}

7:58 tomoj: and,

7:58 ,(doc reset!)

7:58 clojurebot: "([atom newval]); Sets the value of atom to newval without regard for the current value. Returns newval."

7:59 Chousuke: avarus: (require '[clojure.contrib.sql :as sql])?

7:59 caljunior: tomoj: I just want to reset it.

7:59 avarus: Chousuke: oh! thx :)

7:59 haven't thought about that :=)

8:00 caljunior: tomoj: I guess reset! would work.

8:04 tomoj: if you just want to reset it, why are you guessing?

8:04 that's exactly what reset! does, in the simplest way I can imagine

8:14 caljunior: tomoj: yes. I guess your right :-)

8:15 you're

8:34 jeffmess: whats the correct way to install a clojure library? I ran mvn install which resulted in a clojure-http-client-1.0.0-SNAPSHOT.jar file, I placed the file in my classpath but in clj when I run (use 'clojure.http.client) I get a java.io.FileNotFoundException. However this is definitely in my classpath, i can use clojure.contrib lib fine.

8:35 clojure noob, so im not sure if i'm meant to run another build tool on the lib?

8:36 chouser: FileNotFound is not what I'd expect -- can you paste the entire stack trace somewhere?

8:36 lisppaste8: url?

8:36 hm.

8:36 jeffmess: java.io.FileNotFoundException: Could not locate clojure/http/client__init.class or clojure/http/client.clj on classpath: (NO_SOURCE_FILE:0)

8:36 chouser: oh. I guess that is what I'd expect. :-/

8:38 jeffmess: hmm, the jar file is in my .clojure file in the same dir

8:38 chouser: the .jar itself needs to be named on your classpath, not just the directory where the .jar is.

8:38 tomoj: jeffmess: lein :)

8:39 jeffmess: hmm, okay

8:43 avarus: I love lein

8:43 lein jar, thank you, let's go on!

8:46 a_strange_guy: hi there

8:46 avarus: hi a_strange_guy

8:46 a_strange_guy: I need some advice

8:47 trying to write a pattern matching macro

8:47 like http://www.brool.com/index.php/pattern-matching-in-clojure

8:47 but without the limitations

8:48 matching sequential things works already

8:49 but before releasing it, i want to add matching against asossotiative things

8:49 so that it works like the builtin destructuring in clojure

8:51 is there a fast way to check if a map(or map-like ting) contains ONLY some specified keys?

8:52 chouser: I guess I'd use 'count' to make sure the map doesn't have too many keys, then check each of the ones I want to be there -- if they all are, it matched.

8:53 a_strange_guy: hmm, does (associative? x) imply that you can (count x)?

8:53 chouser: That should be O(n log32 n) worst-case, O(1) best case. I don't think you'll get any better than that.

8:54 Hm... Probably not in the abstract, but vectors, hash-maps, and sorted-maps are all 'counted?'

8:55 tomoj: they will all respond to count, at least

8:55 a_strange_guy: and for deftypes?

8:55 no guarantees?

8:56 matching against types is a really nice usecase

8:57 somnium: a_strange_guy: deftypes could implement associative or sequential

8:59 chouser: all Associative have a .count method which (count x) will use, so at least it will work, though as I said in the abstract that could be O(n)

8:59 tomoj: just looked to see that assoc is special-cased on nil to give a new array-map

8:59 chouser: so if a deftype extends Associative it ought to implement 'count'

9:02 a_strange_guy: but only if it does implement Associative

9:03 cow-orker: it seems (Klass.) is more popular than (new Klass), any particular reason for this?

9:05 chouser: cow-orker: two reasons I've noticed. One is it feels more declarative. The other is it plays nicer with ->

9:05 a_strange_guy: cow-orker: and it's shorter xD

9:05 chouser: ,(-> "5" Integer.)

9:05 clojurebot: 5

9:05 Chousuke: silly use of -> though :P

9:06 a_strange_guy: thanks everybody, will post the pm-macro soon

9:07 Chousuke: I wonder if (Integer. "5") is actually preferable to (Integer/valueOf "5") nowadays

9:08 fdaoud: or even (Integer/parseInt "5")

9:09 avarus: mhh... contrib.sql makes 'nextval(''users_seq'') out of "nextval('users_seq')"

9:10 cow-orker: ok, thanks!

9:12 chouser: Chousuke: well, sure it's silly with nothing else in the pipeline.

9:12 Chousuke: replace with the appropriate combination of Reader and Stream ctors as needed to be compelling. :-)

9:13 fdaoud: ,(apply str (map (comp char +) (map int "Want FP without the fuss") [-3 17 11 -84 35 38 31 74 -2 9 -15 -72 -6 -1 -77 83 -84 -7 18 69 13 -6 -6 -14]))

9:13 clojurebot: "Try Clojure it's awesome"

9:14 chouser: heh

9:15 fdaoud: :-)

9:30 LauJensen: Nice :) chouser, make the t-shirt !

9:30 chouser: hmm...

9:30 that's a lot of numbers for a t-shirt

9:31 LauJensen: (iterate fn -3) - work out what fn is then

9:31 chouser: "q ¾r}e,ns'Ç m¹nnf"

9:31 I guess that's worse.

9:33 avarus: how can I escape

9:33 oops :)

9:34 chouser: avarus: try the ductwork. Always works in the movies.

9:34 avarus: how can I escape nextval('users_seq') properly? :)

9:35 when I put it in " contrib.sql even tries to escape the '

9:35 so it looks wrong to pgsql (of course)

9:37 fdaoud: ,(apply str (map (comp char +) (map int "Want FP without the fuss") [-3 17 11 -84 35 38 31 74 -2 9 -15 -72 -6 -1 -77 83 -84 -7 18 69 13 -6 -6 -14]))

9:37 clojurebot: "Try Clojure it's awesome"

9:37 fdaoud: oops sorry that was supposed to be something different

9:40 chouser: ,(apply str (map (comp char +) (map int (.toUpperCase "Want FP without the fuss")) (map int "Qe_ wZS~R]E,NS' MfyaNNF") (repeat -84)))

9:40 clojurebot: "TRY CLOJURE IT'↓MZj-@OE"

9:40 chouser: heh. oops.

9:42 fdaoud: lol

9:45 chouser: ,(apply str (map (comp char +) (map int (.toUpperCase "Want FP without the fuss")) (map int "Qe_ wZS~R]E,NS'\207 MfyaNNF") (repeat -84)))

9:45 clojurebot: "TRY CLOJURE IT'S AWESOME"

9:46 chouser: fdaoud: very slightly shorter, but not really better than your original.

9:47 fdaoud: chouser: guess it's just a matter of taste, whether you're a chars person or a numbers person :)

9:48 avarus: ah fuck, I create a trigger poh

9:48 the db has to set the id :P

9:49 ordnungswidrig: hmm, what is an easy way to the values of a map to a map of the mapped values?

9:49 (map-map inc { :a 1 :b 2 }) -> { :a 2 :b 3 }

9:49 s/easy/idiomatic/

9:50 AWizzArd: zipmap

9:50 ,(let [x {:a 1, :b 2}] (zipmap (vals x) (keys x)))

9:50 clojurebot: {2 :b, 1 :a}

9:50 chouser: ,(let [m {:a 1 :b 2}] (zipmap (keys m) (map inc (vals m))))

9:50 clojurebot: {:b 3, :a 2}

9:52 fdaoud: ,(apply str (map (comp char #(- % 1)) (map int "Qmfbtf!epo(u!txfbs!;.*")))

9:52 clojurebot: "Please don't swear :-)"

9:52 ordnungswidrig: chouser: thx

9:55 avarus: yes, my pgsql trigge is a nice workaround :)

9:55 *happy

9:56 even cleaner as there is now no specific pgsql code in the "app"

9:57 ordnungswidrig: and how would I merge to maps so that { :a 1 :b 2 } { :a "a" :c "c" } would give { :a [1 "a"] :b [2] :c ["c"] }?

9:58 I tried merge-with but I failed on the combinator

9:58 chouser: ,(->> "Clojure" (map int) (map + (map int "ivatefk") (repeat -107)) (map char) (apply str))

9:58 clojurebot: "Awesome"

9:58 avarus: freak

9:58 fdaoud: lol

10:00 ordnungswidrig: chouser: you'd better switch to #haskell or even #pfhaskell :-)

10:01 chouser: yikes. In that case, I take it all back.

10:03 esj: chouser: your outburst brings me into mind of having too much coffee, so I shall go brew some now.

10:03 chouser: ,(reduce (fn [m [k v]] (assoc m k (conj (m k []) v))) {} (concat {:a 1 :b 2} {:a "a" :c "c"}))

10:03 clojurebot: {:c ["c"], :b [2], :a [1 "a"]}

10:03 chouser: ordnungswidrig: that might work -- not sure if it's best.

10:04 fdaoud: ,(apply str (map (comp char +) (map int "Haskell") [-5 11 -4 -1 16 6 -7]))

10:04 clojurebot: "Clojure"

10:04 ordnungswidrig: chouser: hmm, I just notice I need are different result: {:a [1 "a"] :b [2 nil] :c [nil "c"]}

10:05 AWizzArd: chouser: charge 50 cents per LOC ;)

10:05 ordnungswidrig: chouser: I could your result with merge-with… But I need the nil.

10:05 AWizzArd: you can explicitly insert it

10:05 tomoj: doesn't merge-with only call the function when there are duplicate keys?

10:06 would be nice to be able to also supply a function to wrap an unduplicated value

10:06 chouser: yeah, I don't think merge-with would work for either set of results

10:06 tomoj: er, value for an unduplicated key

10:07 AWizzArd: maybe this is so specific that a hand-written reduce/loop is the best route

10:07 tomoj: ordnungswidrig: do you really need them in order?

10:07 the vectors in the result, I mean

10:08 chouser: AWizzArd: take it back!

10:08 reduce should be sufficient.

10:09 AWizzArd: Taking back what?

10:09 chouser: your advice to use loop/recur. :-)

10:10 ordnungswidrig: (reduce (fn [m [k v]] (assoc m k [(m k) v])) { :a 1 :b 2} { :a "a" :c "c"})

10:10 ,(reduce (fn [m [k v]] (assoc m k [(m k) v])) { :a 1 :b 2} { :a "a" :c "c"})

10:10 clojurebot: {:c [nil "c"], :a [1 "a"], :b 2}

10:10 ordnungswidrig: here we go

10:11 In my case I need only the key are in the first map :-)

10:11 AWizzArd: chouser: I would suggest reduce, as this can pretty much solve any looping requirements. Just sometimes a loop can be more readable and less clumsy. But for this case yeah, reduce is a good choice.

10:11 ordnungswidrig: however always having a seq values whould be nice...

10:11 chouser: ordnungswidrig: gah. quit changing your requirements!

10:11 ordnungswidrig: so you're satisfied?

10:12 ordnungswidrig: chouser: this is agile dev .-) Not pair-programming but irc-channel-croud-programming.

10:13 chouser: ordnungswidrig: in that case you should have started with a test, right?

10:14 ordnungswidrig: the test was wrong. final spec: (f { :a 1 :b 2 } { :b "b" :c "c" }) -> { :a [1 nil] :b [2 "b"]}

10:17 ,((fn [m1 m2] (map (fn [k] [(m1 k) (m2 k)]) (keys m1))) { :a 1 :b 2} { :b "b" :c "c" })

10:17 clojurebot: ([1 nil] [2 "b"])

10:20 ordnungswidrig: ,((fn [m1 m2] (apply hash-map (map (fn [k] [k [(m1 k) (m2 k)]]) (keys m1)))) { :a 1 :b 2} { :b "b" :c "c" })

10:20 clojurebot: {[:a [1 nil]] [:b [2 "b"]]}

10:20 ordnungswidrig: ah.

10:21 AWizzArd: chouser: btw, did you see that I orgininally suggested reduce/loop? Maybe you misread it as recur/loop

10:21 ordnungswidrig: is the usage of hash-map fine, here?

10:21 AWizzArd: ordnungswidrig: yes

10:21 chouser: AWizzArd: ah, indeed I did. sorry.

10:23 AWizzArd: chouser: btw, I made progress with the transaction stuff today and can hopefully report success tomorrow.

10:24 chouser: cool

10:35 DeusExPikachu: taking a poll, how many people directly depend on the function start-repl in swank.clj in swank-clojure?

10:38 chouser: not me

10:39 * ordnungswidrig uses lein swank

10:42 DeusExPikachu: ordnungswidrig, do you just use lein swank by typing "lein swank" and don't ever call start-repl yourself?

10:42 tomoj: I didn't know there was a start-repl function

10:42 I don't even see it

10:43 ordnungswidrig: ordnungswidrig: right.

10:44 starting clojure as a inferior-lisp started failing for me about 3 month ago. But I am fine with slime-connect and did not mind anymore.

10:52 DeusExPikachu: ordnungswidrig, do you ever run multiple clojure lisps and switch between them?

10:53 ordnungswidrig: DeusExPikachu: umm, nope.

10:53 DeusExPikachu: only accidentl, I assume

10:54 DeusExPikachu: ordnungswidrig, I think using the slime-connect method is actually more flexible then inferior-lisp, and I'm starting to think that its worth doing even on a local machine

11:01 LaPingvino: hello

11:01 AWizzArd: Hallo LaPingvino

11:01 LaPingvino: I am in the compojure-chat as well

11:01 but everybody there seems asleep

11:02 can I ask a compojure-specific question here?

11:02 AWizzArd: Try it :)

11:02 LaPingvino: are there people out here who could help me?

11:02 AWizzArd: likely

11:02 LaPingvino: well, it's actually quite stupid... I think I am missing some essentials of Compojure

11:03 AWizzArd: Though, the Compojure newsgroup is also very helpful.

11:03 LaPingvino: what is the normal way to get to the request-information?

11:03 and use it in your software

11:03 AWizzArd: What do you mean by that? What is request-information?

11:03 LaPingvino: the information that is send as a request to the server

11:03 AWizzArd: Each handler that you write is a function which must take a request object (a hash-map).

11:04 Tcepsa: LaPingvino: Do you mean the Get or Post parameters?

11:04 LaPingvino: ah okay

11:04 how does that look?

11:04 underdev: sexp is natural, sexp is fun, sexp is best when its one on one

11:04 AWizzArd: This is how handlers look: http://compojure.org/docs/handlers

11:05 tomoj: compojurecasts.com is available :)

11:05 LaPingvino: ah okay

11:05 AWizzArd: And the documentation here lists some things that may be available in a request: http://compojure.org/docs/requests

11:05 LaPingvino: and with defroutes?

11:06 tomoj: AWizzArd: what's the deal with returning a vector as a response?

11:06 LaPingvino: I get GET and POST distinguished with defroutes, but it seems that gets somehow in the way of passing the request...

11:06 it confuses me a bit...

11:06 tomoj: I use [200 response-body], but I saw something else that had three elements

11:07 LaPingvino: I do stuff like this:

11:07 (GET "/locations" locations/get-handler)

11:07 AWizzArd: tomoj: http://compojure.org/docs/responses

11:07 tomoj: where locations is some other namespace and get-handler a function there

11:07 LaPingvino: sure

11:07 AWizzArd: Allowed is: map, integer and string

11:07 LaPingvino: and how to pass the request data to the handler?

11:07 tomoj: you don't

11:07 AWizzArd: that can be in the result vector, tomoj

11:07 LaPingvino: this will be done by Compojure for you

11:08 tomoj: (defn get-handler [request] ...)

11:08 LaPingvino: ah okay

11:08 tomoj: the line above sets it up to pass the request to the function

11:08 AWizzArd: LaPingvino: just write functions that you want to call from a client (for example a .html page in a browser).

11:08 LaPingvino: ???

11:08 somnium: I always return a map as the response {:status ... :headers ...}

11:08 tomoj: AWizzArd: map is for headers?

11:09 underdev: compojurecasts.com doesn't seem to exist

11:09 AWizzArd: List them in (defroutes LaPingos-Routes (GET "/resource1" function) (POST "/resource2" function2) ...)

11:09 tomoj: underdev: yeah, it's available

11:09 AWizzArd: tomoj: exactly

11:09 tomoj: I see

11:09 wonder how multiple values of each type are handled

11:09 LaPingvino: right

11:09 tomoj: gotta find where compojure does this in the source..

11:09 underdev: compojurecasts.com => Oops! This link appears to be broken.

11:09 AWizzArd: tomoj: they get added if possible, last value wins

11:10 LaPingvino: and the functions you list there get called with the handler as first parameter?

11:10 tomoj: aww

11:10 LaPingvino: riiiiiiiiiight :)

11:10 tomoj: last value wins is I guess the least confusing way

11:10 LaPingvino: thanks a lot :)

11:10 AWizzArd: LaPingvino: yes, just write the hello-world function as given in the example

11:10 tomoj: I assume then that assoc-session returns a header map

11:10 LaPingvino: I will have to rewrite a bit then

11:10 AWizzArd: yes

11:11 you can start with the examples, and then do a minor modification

11:11 LaPingvino: I got a nullpointererror because I had the details wrong...

11:11 thanks a lot!

11:11 AWizzArd: yes, that will go away

11:11 np

11:11 Are you from the east of the NL?

11:11 somnium: tomoj: the sessions are what got me to always return a map

11:11 LaPingvino: AWizzArd: I am from Ede

11:11 around the middle

11:12 AWizzArd: k

11:12 tomoj: er, session-assoc I meant

11:12 LaPingvino: why?

11:12 clojurebot: http://clojure.org/rationale

11:12 AWizzArd: west DE here

11:12 LaPingvino: ah cool :)

11:12 which city?

11:12 tomoj: I found this way to do it somewhere: [(session-assoc :foo bar) {:status 200}]

11:12 now I'm actually confused why that works

11:12 somnium: I wrote a tiny middleware to bind sessions/flash to dynamic vars so they can be accessed and set! downstream (doesnt work with in memory sessions)

11:13 tomoj: since {:status 200} should be interpreted as a header map and overwrite session-assoc's value

11:13 LaPingvino: someone should complete a course or write a book about compojure, as clear as Stu's book

11:13 think I get it now :)

11:13 will have to experiment a bit still, but you have helped me a lot :)

11:14 somnium: hopefully the sessions api will be better once they add it to ring

11:14 AWizzArd: LaPingvino: at first Compojure seems overwhelming. But it is amazingly trivial and powerful. There are just some very few core concepts which you need to learn.

11:14 LaPingvino: AWizzArd: I begin to see it :P

11:14 tomoj: hmm, session-assoc returns something like {:session foo}

11:14 LaPingvino: Compojure is a bit more complex than just plain clojure :P

11:14 tomoj: oh, guess the with-session middleware is changing the way that's interpreted

11:14 LaPingvino: but it is great really :)

11:16 tomoj: oi

11:16 I'm going to wait till after the refactor to try to understand this stuff in detail

11:17 LaPingvino: tomoj: where are you from? brasil?

11:18 and which languages do you speak?

11:19 hiredman: oy is yiddish

11:19 * nuba o/ brazilian show of hands :)

11:19 tomoj: LaPingvino: US, texas

11:19 just english

11:20 latin really slowly :P

11:20 somnium: tomoj: the with-session middleware looks for a :session key in the response (but in-memory sessions are broken currently, no way to invalidate a session) and then updates accordingly

11:20 tomoj: ok, but my response is a vector

11:20 somnium: ooh, spoken latin

11:20 tomoj: this is why I am confused

11:21 er, I didn't mean spoken :(. unless writing and then reading it out loud counts

11:21 somnium: I dont get the vector mini language, I think its supposed to be sugar, but I got nothing but problems trying to use it

11:21 tomoj: I guess somebody else is turning the vector into a map before with-session sees it

11:21 because sessions are working fine :)

11:22 AWizzArd: somnium: what problems?

11:22 tomoj: well, hadn't tried invalidation yet

11:22 AWizzArd: If you want that your handler returns 401 just return this

11:22 if you want it to return 401 with more text return [401 "No auth data given"]

11:23 A handler may return an int, a string or a map

11:23 DeusExPikachu: what's the inverse of hash-map?

11:23 somnium: so default is {:status :body} ?

11:23 AWizzArd: If it is an int, then this is the status code for the response

11:23 tomoj: the thing that's confusing me is I'm apparently returning [{:session ..} {:status ..}]

11:23 both maps

11:23 AWizzArd: the string ensembles the body of the response, while the map allows you to add extra headers.

11:24 tomoj: and neither are headers :D

11:24 hiredman: rhickey: I've been digging through the compiler and as a learning exercise added a "jop" special form which lets you use java operators directly, example (jop + (int 1) (int 1)) compiles to an iadd instead of a call through Numbers.add, the latest iteration does away with jop and uses #^{:primitive true} (+ (int 1) (int 2)), I am wondering if you would be interested in this?

11:24 somnium: I ended up moving most things into middleware and just using defroutes to call fns

11:24 AWizzArd: somnium: good

11:24 tomoj: yeah, I did that too

11:24 AWizzArd: sounds good

11:24 tomoj: with my namespaces corresponding to restful resources

11:26 rhickey: hiredman: I'm interested in the facility in general, as when we move to cinc, we will need a more generic way to invoke primitive ops. I'm not sure 'jop' is it. On my todo is to run with the experiment I've proposed here to moveto Long as base type

11:26 hiredman: be aware though that HotSpot turns the static call into the opcode so there is no perf benefit to what you are doing

11:26 hiredman: sure

11:27 perf is not my thing generally :)

11:27 rhickey: so, is the objective just to get a guaranteed primitive op?

11:27 hiredman: yes

11:27 rhickey: because if it has to unbox and rebox, there isn't much benefit to the primitive op

11:28 esp rebox

11:28 hiredman: if Numbers.java becomes a protocol it has to bottom out somewhere

11:28 rhickey: Number.java much be the primitive interface

11:28 might be

11:29 subject to inlining when there is no hotspot-like thing

11:29 hiredman: really? it would not be written in clojure?

11:30 rhickey: dunno. If it was you'd need different bodies for different platforms

11:30 actual opcodes can't be Clojure

11:31 hiredman: opcodes being? the Ops stuff in Numbers?

11:31 tomoj: anyone interested in thrift?

11:32 I have this vague idea that compiling thrift files to deftypes and protocols could be really awesome

11:33 hiredman: it seems like you wouldn't need different bodies, you just add #^{:primitive true} to calls you want to be primitive and the compiler would take care of what and how

11:37 rhickey: hiredman: begs the question as to what 'primitive true' means

11:37 hiredman: not a fn?

11:43 if we are talking about clojure on many hosts it would be up to the compiler on each host to determine what it means, but if we just talk about Clojure, then primitive for + means iadd,fadd,dadd,etc

11:52 mengu_: hi. should i develop my web application with clojure? why? why not rails or why not erlang?

11:53 Chousuke: because Clojure is fun!

11:54 mengu_: that's it?

11:54 cp2: well mengu_, if we told you, we would have to kill you

11:55 nuba: what did you expect? the answers for all life's questions chewed up for you?

11:55 rhickey: hiredman: then the semantics would change, potentially

11:55 Chousuke: well, I can't give you a bullet-list of features, because taken individually almost every other language is capable of the same things.

11:55 pjackson: mengu_: It's very capable too.

11:55 Chousuke: DSL's, concurrency, the JVM, functional programming, etc...

11:55 nuba: go to #[whatever] and expect to hear [whatever] is better

11:56 Chousuke: but it's how all those things work together that makes Clojure special.

11:56 nuba: you should read and play with it a little

11:56 tomoj: one problem I have with clojure is that we don't have the kind of community that e.g. rails has, yet

11:56 so for example I couldn't just script/plugin install something to make my compojure app take image uploads and resize them

11:56 Chousuke: Though I suppose the STM value/identity concurrency approach is somewhat unique

11:57 tomoj: yet, I'm still sticking with clojure

11:57 hiredman: rhickey: but they aren't going to be the same at that low of a level across hosts anyway

11:57 tomoj: I feel like making up for that problem is easier in clojure than it would be elsewhere, and in the long run I will be more sane with clojure :)

11:57 mengu_: Chousuke: what i am building will be a social network. so it will be all about concurrency. for example rails is fun too. and i am happy with it. but then will i be happy, hopefully, when it grows?

11:58 i don't want to make a switch after the run. i just start with the best fitting one at the beginning.

11:58 fdaoud: mengu_: what is compelling to me personally is functional programming and Clojure's simple, consistent syntax. now, when I look at Java, Ruby, Groovy, Python code, the enormous amount of syntax jumps out at me.

11:58 Chousuke: mengu_: I wish I knew the answer. There is not enough data to say anything for certain yet

11:59 rhickey: hiredman: integer add etc certainly could be made so. But only if a decision was made to guarantee that

11:59 Chousuke: mengu_: but I think if you're looking to build something scalable, Clojure is not a bad bet.

12:00 tomoj: I'm more concerned with the health of my code

12:00 no tentacles of state squirming around through all different parts of the code

12:00 mengu_: fdaoud: i can accept that for java & groovy but not for py and rb. however from what i have seen, clojure has a different approach to programming at the beginning.

12:02 fdaoud: http://clojure.org/rationale that one i'm talking about by the way :9

12:02 *:)

12:03 fdaoud: mengu_: you mean you don't accept that I think that py and rb have too much syntax?

12:03 mengu_: compared to java and groovy

12:03 cp2: i wouldn't really say too much syntax, personally i think its more of 'undesirable syntax'

12:04 tomoj: they both certainly have far more syntax than clojure, though

12:04 fdaoud: mengu_: compared to clojure

12:04 e.g. ruby: => , sometimes () around params sometimes not, |x| for blocks, do end or { }, the list goes on and on

12:05 tomoj: we have, what, [] {} and #* ?

12:05 alexyk: tomoj: (def *tentacles* :of-state) :)

12:06 Ober2: ruby you have too many options?

12:06 mengu_: i have another question. for example people build their applications, for say, php or django or rails. and then they say they make their front-end application communicate with a functional language like clojure or erlang. how do they do that?

12:06 Ober2: *cough*SOAP*cough*

12:06 Chousuke: Which language has more "semantics" though?

12:06 tomoj: to me it's more like, the structure of a clojure program is pretty damn simple for a computer to understand, and pretty uniform all over

12:07 which makes editing much more pleasant

12:07 Chousuke: Clojure has few syntax elements, but each macro in effect creates a new semantic construct. :/

12:07 Ober2: reminds me of initial reviews of lisp code going "where's all the variables and state information?"

12:07 mengu_: tomoj: that got me, for example. http://paste.pocoo.org/show/175201/

12:08 Chousuke: Though in Clojure similar code elements usually mean similar things so it's mitigated.

12:08 tomoj: compared to metaprogramming in ruby, I'll take macros

12:09 somnium: and theres no macroexpand in ruby, just pain :)

12:09 Chousuke: CL suffers somewhat from the lack of different elements :P

12:09 you have to use lists for everything

12:09 so their meaning is overloaded by necessity.

12:10 tomoj: I wonder if other lisps before clojure added [] and {}

12:10 Chousuke: well, in some schemes [] are interchangeable with (), but I don't think that counts .)

12:10 tomoj: apparently elisp has [] vectors

12:11 that doesn't really count either, it's elisp :P

12:12 Chousuke: :P

12:12 I got a new monitor today

12:13 I must say, a 24" widescreen LCD looks enormous compared to a 17" CRT

12:13 tomoj: I alternate between 24" widescreen and 10" netbook

12:13 Chousuke: still connected via vga though. the package didn't include a DVI cable. :P

12:15 but since it apparently can handle a fullhd signal I'll bear with it for a moment.

12:19 hiredman: rhickey: just to be clear, is what you are saying is you would like Clojure's, uh, numerical interface, to be higher level and more abstract?

12:29 cp2: Chousuke: 24" is pretty big

12:29 i use 20" widescreen lcds, and they are plenty big for me

12:29 Chousuke: cp2: yes it is.

12:29 it's got about twice the screen space compared to my old 17" crt :P

12:29 cp2: haha yeah

12:30 i have some ancient dell crt around somewhere

12:30 cant stand using it =P

12:30 makes my head hurt

12:31 * esj just upgraded from 13" to 17" and though it the new screen was monumentally huge. Behind the curve :(

12:32 cp2: speaking of upgrades, i love my new keyboard

12:33 got one of those unicomp model m remakes

12:33 it kicks ass =P

12:33 esj: cool

12:34 i just 'upgraded' to standing desk - tired of back pains

12:34 looking forward to foot pain instead

12:34 cp2: haha

12:34 i should really get a better chair

12:34 i think my back has had enough of this one

12:35 rhickey: hiredman: no, I'm just saying it's probably premature to define the interface to low-level arithmetic bytecodes

12:41 noidi: I'd like to write a pure function that adds objects to a collection, returning the new version of the collection. I'd also like the function to return handles to the values in the collection. ...

12:42 is this something that monads are good for, or should I write a macro?

12:42 hiredman: handles?

12:42 noidi: indices to be exact

12:43 somnium: noidi: could you give an example of the desired return value?

12:43 noidi: in an OO language I'd write something like foo = coll.add(something()); bar = coll.add(something());

12:43 but doing this in a purely functional way requires me to thread the changed state of the collection through the calls

12:44 hiredman: noidi: if you are conj'ing stuff to a vector the index is (dec (count ...))

12:45 ,(let [a [] b (conj a 1) onedex (dec (count b))] [b onedex])

12:45 clojurebot: [[1] 0]

12:46 noidi: hmm.. I'll try to come up with an example

12:47 hiredman: it sounds like you want multiple returns values, which you can't have

12:48 you could use binding to fake it

12:48 (def *return1*) (binding [*return1* nil] (set! *return1* idx))

12:50 ,(doc binding)

12:50 clojurebot: "([bindings & body]); binding => var-symbol init-expr Creates new bindings for the (already-existing) vars, with the supplied initial values, executes the exprs in an implicit do, then re-establishes the bindings that existed before. The new bindings are made in parallel (unlike let); all init-exprs are evaluated before the vars are bound to their new values."

12:50 noidi: http://gist.github.com/298397

12:50 hiredman: bah

12:51 I think the docs for binding on the website explicitly talking about using binding to communicate up the stack, but it is more commonly used for implicit args

12:51 tomoj: why don't you just do (let [foo (object/new ..) bar (object/new ..)] ...) and then (conj scene foo bar) ?

12:52 Knekk: Good morning

12:53 noidi: tomoj, I don't want the objects themselves, I want handles that I can use to refer to specific objects in the scene

12:54 tomoj: oh, bizarre

12:54 doesn't the scene know enough to project the {:foo foo :bar bar} at the end?

12:54 hiredman: why would you want handles, if not to get the objects?

12:55 tomoj: er, I don't know what word was supposed to go where "project" is

12:55 construct?

12:55 noidi: yeah, it's all a bit weird at the moment, I'm trying to adjust to pure functional programming so I'm probably doing everything the wrong way :)

12:56 hiredman, to create a new version of the scene with one object in the scene replaced with an updated version

12:56 hiredman: ah

12:58 noidi: of course I could simply use refs for the objects, and update their values

12:58 but I'd like to try pure FP and see what the fuss is about :)

12:59 hiredman: you could return pairs

12:59 like [[1] 0]

13:02 noidi: yeah, I thought about that

13:03 but I was hoping that this problem could be solved using monads, somehow, so that I'd have an excuse to learn them :)

13:05 I guess I'll read Konrad Hinsen's tutorials and look into clojure.contrib.monads

13:07 somnium: noidi: you could use the state monad

13:09 noidi: somnium, great, thanks

13:09 from the first hit on google, http://www.haskell.org/all_about_monads/html/statemonad.html, it appears to solve the exact problem I have

13:10 or at least I think it does, that horrible Haskell syntax always makes my brain freeze and eyes glaze over

13:12 fmu: with clojure-mode, is there an easy way to dump the result of C-c C-e (lisp-eval-last-sexp) into the file, either plain or as a comment?

13:15 hmm the mode documentation looks wrong

13:28 tomoj: fmu: eval-print-last-sexp

13:28 oh, no

13:29 that does elisp only, I guess

13:33 fmu: tomoj: yeah, i tried that. i think this would be a useful thing to have, in particular when demonstrating code to others.

13:33 tomoj: aha

13:33 slime-eval-print-last-sexp

13:34 that dumps it into the source file on the next line though, which seems odd to me

13:34 I remember seeing something that copied a sexp into the repl and evaluated it

13:34 but don't remember where

13:34 er, it's slime-eval-print-last-expression

13:35 (not sexp)

13:35 needs slime, of course

13:35 fmu: the sexp variant is useful for stuff that is not toplevel

13:36 anyway, working perfectly now. must have put slime into some weird state previously.

13:39 tomoj: slime-pprint-eval-last-expression sounds attractive, but doesn't work for me

13:43 scottj: There used to be a function str* (not sure if it was in clojure, contrib, or compojure) that would behave like str but call name I think on arguments that were named. I can't find it, did it get removed, renamed, replaced?

13:45 arohner: scottj: as-str?

13:45 lypanov: has anyone around played with clojure/terracotta?

13:46 scottj: arohner: thanks, maybe it was renamed to that.

14:11 underdev: i laughed so hard

14:12 http://tcltk.nfshost.com/quantifiedconception.png

14:12 grabbed it from the paredit presentation

14:14 cemerick: underdev: then you see hardcore scheme impls in perl, like this, and the cycles just keep on going: http://billhails.net/Book/

14:15 tomoj: underdev: where's the paredit presentation?

14:15 cp2: cemerick: oh my....

14:16 tomoj: mudphone's?

14:16 noidi: underdev, here's the original http://xkcd.com/224/

14:17 Raynes: Ioke is painfully slow, and apparently that's expected and intended. :|

14:17 Which is a real mood killer.

14:17 underdev: tx

14:17 noidi, tx

14:17 http://www.slideshare.net/mudphone/paredit-preso

14:18 cemerick: Raynes: it's by no means intended to be a production language

14:18 lypanov: Raynes: same crap as the ruby guys gave for years.

14:18 cemerick: AFAIK

14:19 noidi: underdev, and, as always on xkcd, keep your mouse on the strip to see the second punchline

14:19 Raynes: cemerick: After a little discussion with Ola, his interests aren't totally academic. He just doesn't seem to care about performance over expressiveness.

14:19 cemerick: lypanov: no need to start flaming

14:19 Raynes: that's about the point at which he'd probably say "patches welcome" :-)

14:21 Raynes: If he has a choice between speed, and more expressiveness, he'll take the latter. I doubt contributions would be very helpful for this particular language. I'm very interested in see where this goes over the next couple of years, if the project holds up.

14:21 Even with poor performance, it's still pretty awesome.

14:21 Needs moar concurrency.

14:21 underdev: pre-mature optimization and all that...

14:21 cemerick: everyone has different motivations *shrug*

14:21 underdev: and cowbell

14:27 * chouser is uncomfortable with the innuendos implied by pronouncing "bound-fn" aloud.

14:27 Chousuke: :P

14:28 underdev: one things for sure, you have to be impressed with kyle oba's command of metasyntatic symbols

14:28 hiredman: bound-fn closes over dynamic scope, right?

14:31 Mec: does a jar file have to be added specifically to the classpath to use, or just the folder?

14:32 stuartsierra: Mec: named on the classpath

14:32 Mec: Sun Java 6 permits -cp "folder/*"

14:37 Mec: thanks

14:45 avarus: re

14:52 Raynes: "DateTime now notice split("T") second split(":")" holy chain of messages. :>

15:18 LauJensen: To all you Americans, Best In Class is now the 98.460.th most visisted page in the US!! :)

15:22 alexyk: LauJensen: that probably makes it #1 Belgian-made website in the Universe :)

15:23 triyo: no its Danish I think :)

15:23 alexyk: and transitively Danish as well then :)

15:23 LauJensen: Its fun how many people are so ignorant of Danish - On of the first comments I got on the site was "Too dutch for me" ... :)

15:24 alexyk: Belgians got the Chimay and the Trappist preserves, which must be more popular anyways :)

15:24 triyo: When I worked for IBM I flew to Copenhagen a lot

15:24 alexyk: LauJensen: I was at a conference in Copenhagen in 2007, so I should have known

15:26 what with all the crossed Øs...

15:27 LauJensen: well... its not too late to appologize

15:27 alexyk: LauJensen: I bow before the Danish people collectively and you individually!

15:28 LauJensen: Alright - You are hereby pardoned by the sovereign pingdom of Denmark

15:28 blakki: is there a better/nicer way to do this? http://pastebin.com/d1202e470

15:28 triyo: member:LauJensenn: I also worked for a Danish shipping company Mærsk

15:28 alexyk: LauJensen: furthermore, I promise to spell København in its original script from now on

15:29 pingdom is something network-related, or souped-up cars

15:29 souped-up cdr's I meant

15:29 cp2: LauJensen: what is this moonspeak? ahhh!!

15:30 alexyk: triyo: so you're the one koading all those reailway containers passing by everywhere and stacked up high next to Amazon.com in Seattle?

15:30 must be pretty string then

15:30 strong

15:31 chouser: ok, so that's one downside of manual CPS in clojure ... exception handling.

15:32 if you're supposed to return a value, throwing an exception is an easy and handy way to report an error

15:32 triyo: alexyk: hhehe, pretty much about 3 years ago. Also if you ever had a shipment delayed. You can prob thank me :) (Wouldn't be the first time we had a freight sent to a wrong location.)

15:33 chouser: if you're supposed to call a callback, you need a secondary mechanism to report the error -- some shared state that you set, some other callback to call instead, some return protocol instead of a simple value, something...

15:34 alexyk: triyo: somebody has to make the world interesting

15:34 somnium: chouser: the error monad to the rescue!?

15:35 neotyk: congrats Lau

15:35 LauJensen: thx :)

15:36 chouser: somnium: I guess I need to know more about monads... :-/

15:36 rhickey: anyone got a Google wave invite they'd like to send my way?

15:36 neotyk: how do I do callbacks idiomatic?

15:36 xp_prg: hi all, I am a mere mortal and I need help understand how to make clojure programs creating a dynamic language with macros etc...

15:36 neotyk: rhickey: everyone

15:37 triyo: alexyk: perishables were the funniest. Client needs it in Cape Town, South Africa and it lands up in Reo, Brazil. No rolling back that transaction.

15:38 arohner: rhickey: sure. What's your email?

15:38 chouser: rhickey: sent

15:38 rhickey: thanks

15:39 I noticed in the twitter stream someone was holding a clojure conference on g.wave

15:39 Chousuke: neotyk: callbacks? aren't those just functions? :/

15:40 xp_prg: if you need help, ask a question first :)

15:40 neotyk: Chousuke: true, but have seen agents (c.c.http.agent) used for it

15:41 so am wandering how to write real async http client idiomatic way

15:41 chouser: rhickey: in french, apparenly?

15:41 triyo: yup french seems like it ... http://bit.ly/afD0ck

15:42 I think thats the one in paris

15:43 hiredman: http://googlewavebots.info/wiki/index.php?title=Main_Page#Wave_Language_and_Translation_Bots

15:43 :D

15:45 underdev: hmmm, anyone know how i can configure paredit-mode and show-paren-mode on by default

15:45 ?

15:46 lancepantz: did the sql libs get removed from clojure-contrib?

15:46 hiredman: clojurebot: translate from fr Syntaxe imbitable et la mauvaise

15:46 clojurebot: Syntax WET and poor

15:46 hiredman: :(

15:46 chouser: heh

15:47 hiredman: clojurebot: translate from fr Je trouve la communaute Scala beaucoup plus interessante

15:47 clojurebot: I found the community much more interesting Scala

15:47 hiredman: :O

15:47 chouser: perhaps we're helpful but boring?

15:47 triyo: underdev: I have this http://gist.github.com/298569

15:48 Tcepsa: underdev: Not sure, but seems like there should be some way to do it in your .emacs file

15:48 blakki: AA

15:48 triyo: underdev that autoloads paredit-mode

15:49 underdev: Tcepsa: ty, that's what i'm trying to do

15:50 triyo: underdev: the autoload part in -> http://gist.github.com/298569

15:50 underdev: triyo: ty! this is much like the code i found on the web, but much cleaner

15:50 Tcepsa: underdev: Hehe, okay, wasn't sure how far along the path you'd gotten.

15:51 fanatico: is there a clearer way to write (reduce f (reduce f list-one) list-two)?

15:51 underdev: triyo: it also makes it more clear how to add the show-paren-mode

15:51 Tcepsa: tyvm

15:51 * Tcepsa is still mostly an Emacs noob, but feels that he's learned a few useful things through getting Slime/Swank/Clojure working ^_^

15:51 LauJensen: fanatico: Check out the latest post on http://clj-me.cgrand.net

15:52 underdev: Tcepsa: where would i store paredit.el so that autoload would find it?

15:52 Tcepsa: yeah, im editing my .emacs in vim :)

15:52 is that wrong?

15:53 the-kenny: underdev: Yes

15:53 chouser: underdev: it's how work gets done.

15:53 Tcepsa: underdev: The easiest place would probably be in the site-lisp folder under emacs, unless you want other users to NOT be able to use it

15:53 the-kenny: underdev: You need "alias vim=emacs"

15:53 triyo: underdev: do you have ELPA installed?

15:53 Tcepsa: underdev: As long as it doesn't garbage the file for you ^_^

15:53 cemerick: underdev: oh, that's funny :-)

15:53 underdev: Tcepsa: yeah, thats where it is by default

15:54 it was suggested i move it to ~/.emacs.d

15:54 'preciate it

15:54 triyo: underdev: if so the paredit will be already on necessary path. Then just place snippet in my link above in your .emacs, using emcs edit and not vi :)

15:55 Tcepsa: underdev: That would work as well, and ensure that only you would be able to use it (assuming you had multiple users using the same emacs installation; if you're on your own home box it's probably less of an issue)

15:55 underdev: okay

15:55 cool

15:55 thanks guys

15:55 cemerick: has anyone knocked together a FSM wrapper for agents?

15:55 Tcepsa: np ^_^

15:55 fanatico: LauJensen: I don't use list comprehension enough. Thanks.

15:56 LauJensen: np

15:58 Tcepsa: underdev: I suspect that you'll also want to add a corresponding (add-hook 'clojure-mode-hook <etc.>) if you want to have it automatically activate for Clojure files. Is that right, triyo?

15:59 triyo: Tcepsa: yup spot on

15:59 chouser: that french wave seems to repeat some common misconceptions. :-/

16:00 triyo: Tceps: in the example, I have it hooked into my lisp-mode for CL dev. You'd need the clojure mode one of coruse

16:00 kotarak: french wave?

16:00 Tcepsa: triyo: Great, thanks!

16:00 chouser: though it's hard to tell for sure through the translation.

16:00 "The lists have a lot of ways, for example (first lst) returns the first element. The methods and rec conj can add an item to the end and beginning of the list, respectively."

16:00 triyo: Tceps: np

16:00 Tcepsa: triyo: (I'm also trying to set it up for my own environment ^_^)

16:00 chouser: kotarak: http://bit.ly/afD0ck

16:02 hiredman: man, I am used to using machine translation with, say, Korean, which is just terrible, the french apears to be very good

16:03 kotarak: chouser: I'm not sure I understand.

16:03 chouser: you don't have to explain

16:03 chouser: kotarak: you don't understand what?

16:03 underdev: w00t!!!

16:03 triyo: Tcepsa: cool, have you used paredit before? Its great but can be quirky at first. Once you get use to it, you want look back :)

16:04 chouser: dont understand french :)

16:04 kotarak: chouser: "french", "wave" and "misconceptions" Is about the content of the wave at the link? Google wave in general? Some involved technology? But it's too late and I'm too tired. So I will count the as another mystery in the wide open of the plane of things I don't understand. :]

16:05 chouser: kotarak: oh, sorry. The Google Wave at that link is all in French, and as best I can tell from the machine translation to English, that content includes some innaccuracies about clojure.

16:06 kotarak: chouser: ah. Ok. I could try with my long rusty french, but I don't have access to the wave. (I think... at least it says "limited" and "get an invitation")

16:07 triyo: any current guestimate as to when Clojure 1.2 is seen to be released and will deftype and defprotocol make it into the release?

16:07 this question prob pops up a million times. (I haven't been around)

16:08 chouser: kotarak: ah, sorry. :-/ Google wave's are only readable by people with a wave account. It's a shame, though I believe they plan to open up read access eventually.

16:08 Chousuke: triyo: types and protocols will be in the next release, but I don't know of any estimates for a release date :/

16:08 avarus: good night

16:10 chouser: hiredman: are you using a wave translation bot, or something external?

16:10 the-kenny: chouser: They will, someday....

16:10 hiredman: google has some bots on xmpp for translation

16:10 dakrone: chouser/kotarak: Either of you need a wave invite?

16:10 hiredman: I am using one

16:10 * the-kenny got some invites left too

16:11 hiredman: http://blogoscoped.com/archive/2007-12-19-n41.html

16:11 * kotarak raises hand

16:11 * somnium raises hand

16:11 chouser: hiredman: ok. I saw someone added "Translatey" and wasn't sure how to use it.

16:11 triyo: Chousuke: been messing about with that branch, loving the additions, so was wandering when it will be in and also if it will remain, to a large degree, in form it is in now.

16:11 hiredman: no idea

16:11 http://markfayngersh.com/post/333326632/clojure-bot-is-a-google-wave-robot-that-evaluates <-- I just added this

16:11 (not my work)

16:12 dakrone: PM me an email address if you'd like a Google Wave invite

16:12 chouser: yeah, I saw that too.

16:12 Chousuke: triyo: I think there might still be new stuff coming :P

16:12 chouser: hiredman: it used to work for me, but hasn't recently.

16:12 hiredman: :(

16:12 Chousuke: triyo: but I'm not the best person to ask

16:12 the-kenny: dakrone: Same for me. Just PM me if you want one.

16:12 hiredman: clojurebot does xmpp, and so does appengine, so maybe I could just proxy clojurebot's xmpp over appengine

16:13 dakrone: I'm coming into the middle of the conversation here, are you talking about wave robots in clojure?

16:13 hiredman: tangentally

16:15 a french wave was found that supposedly is about clojure, but seems to be heavy pro scala

16:15 chouser: I think something about the phrase "french wave" tends to be misleading without context. :-)

16:16 kotarak: could it be a swiss wave?

16:19 somnium: chouser: http://gist.github.com/298581 << is this similar to the kind of boiler plate for CPS exceptions you mentioned?

16:22 chouser: somnium: sure, I think that falls into the "return protocol" category I mentioned.

16:23 I think.

16:24 somnium: chouser: so, the monad just invisibly chains the protocol together, but can also make all preceding state in the chain available

16:24 I found a great video by the microsoft guy who interviewed rich

16:25 http://channel9.msdn.com/shows/Going+Deep/Brian-Beckman-Dont-fear-the-Monads/

16:25 chouser: But I don't think I can allow that invisibility. Some of my functions need to pass the callback along to other functions, or store it somewhere, etc.

16:25 somnium: hmm

16:25 chouser: though perhaps I still don't understand.

16:26 I think I have a solution for now. because of 3rd party apis, the callback takes a single arg.

16:27 triyo: talking about monads, I saw this questions few days ago on reddit "What Does Monad Mean?" and somewhat answered -> "Only possessing a single testicle."

16:27 chouser: (fn f [input done-callback] (done-callback (inc input)))

16:27 nDuff: chouser, for folks buying a prerelease of The Joy of Clojure -- are deltas available when previously-released chapters are updated?

16:27 triyo: * somewhat=someone

16:28 hiredman: #(done-callback (inc input))

16:28 chouser: actually, it's worse

16:28 kotarak: monads rock sometimes, monads suck some other times. I'm not sure which times get the bigger share...

16:29 chouser: (fn f [input controller done-callback] (if (valid? input) (done-callback (inc input)) (do (.setFailed controll "invalid input") (done-callback nil)))

16:29 but because I can control the inner layers here, I can support this instead:

16:30 (fn f [input _ done-callback] (if (valid? input) (done-callback (inc input)) (done-callback :error "invalid")))

16:30 which is at least a little less noisy.

16:30 Tcepsa: triyo: Sorry, had to step away for a bit there. I'm new to paredit, but I've heard very good things about it.

16:31 chouser: and although it's entirely legal for f to return without calling done-callback (because it has stored it for later use), it seems unlikely for f to throw an exception and then later try to claim successful completion, so I can catch exceptions thrown by it as a kind of special-case error.

16:31 triyo: Tcepsa: takes a bit of getting use to. I found it a bit tricky at first.

16:31 Tcepsa: triyo: The few things I've seen so far look neat (the autoclosing, for example; I used to hate it in Eclipse, but this implementation looks like it behaves in a way that makes more sense to me)

16:33 Chousuke: Tcepsa: it doesn't really "autoclose"... it just maintains a consistent structure, which happens to require matching parentheses

16:33 somnium: when fns have metadata it might open up some more options. anyway, just a suggestion (trying to get some value from recent haskell reading)

16:34 Tcepsa: Chousuke: Ah, that makes sense.

16:38 chouser: nDuff: I don't think we can provide anything useful like that with the version of the PDF that's up now. That content will be substantially reorganized in an upcoming release.

16:39 nDuff: However, we may have something like that later -- Manning has a system (that we're not really using for this book yet) to allow per-paragraph comments and change history.

16:41 qbg: Random question: why does let do sequential binding?

16:42 chouser: qbg: because it's no less efficient on the JVM, and people would just write macros to do sequential binding anyway.

16:43 qbg: is that a sufficient answer? :-)

16:43 triyo: I see wikipedia entry on Macros, says "It is possible to force a capturing macro expansion, but this must be done explicitly. ". Out of interest how is this possible in CLojure? In CL its implicit behavior.

16:44 Clojure wikipedia page that is -macros section

16:44 hiredman: triyo: you have to use the right combination of quote and syntax-unquote

16:44 qbg: chouser: guess so; someone else asked me that question

16:44 hiredman: triyo: you have to unsyntax-quote ad quoted symbol

16:45 an

16:45 a

16:45 triyo: hiredman: Oh I see, makes sense.

16:45 hiredman: so you have to really want to capture that name

16:45 chouser: qbg: I guess another answer would be to ask: what would be the benefit of simultaneous binding for 'let'? you can already do it with destructuring and function calls, so no much benefit to yet another way.

16:46 qbg: That helps even more

16:46 thanks

16:47 chouser: sure

16:48 triyo: hiredman: yup, I know what you mean. I know, 99% cases, variable (name) capture is not desired hence Clojure does the opposite of the way CL handles it. Just was curious how to go about it if need ever comes up and that there is no limitation in actually doing it.

16:54 zenoli: blakki: Here's a possible approach - http://pastebin.com/m1609944f - won't return the remainder as a chunk, though.

16:56 mabes: what is the best way to apply a hashmap into a function defined by defnk? Right now I am having to do: (apply foo (flatten (vec m)))

16:57 the above works but seems clunky

16:57 Chousuke: mabes: (flatten m) should work just as well

16:57 kotarak: (apply foo (mapcat identity m)) should do without external deps.

16:58 hiredman: kotarak: well he is already using defnk

16:58 kotarak: and he wants to apply a map there, no?

16:58 mabes: yes.. trying just flatten now...

16:58 hiredman: if he wants no deps he could use map destructuring directly

16:59 and he could just pass the map

16:59 no need to apply

16:59 mabes: simply passing the map does not work

16:59 ordnungswidrig: re

16:59 hiredman: mabes: if you used map destructuring directly it would

16:59 mabes: how would I use destructuring in this context?

17:00 hiredman: ~destructuring

17:00 clojurebot: destructuring is http://clojure.org/special_forms#let

17:00 hiredman: ,((fn [{:keys [a b]}] [a b]) {:a 1 :b 2})

17:00 clojurebot: [1 2]

17:00 abrenk: chouser: we talked about epub's of manning's clojure books a couple days ago

17:01 mabes: hiredman: but that is when you create a function.. I am passing the map in this case.. I didn't think you could use destructuring outsite of def and let

17:01 abrenk: chouser: imagine my horror when after downloading a pdf from http://ebook.manning-sandbox.com today and checking the "manning blog" linked to on the left side of the page and it talked about replacing the PDFs with DRM protected ThoutReader format...

17:02 hiredman: mabes: I am saying if you used map destructuring directly when creating the function instead of defnk

17:02 abrenk: chouser: ...turned out it were blog entries from 2004/2005! I guess I should write them about removing those links.

17:02 mabes: ahh, I see. Yeah, I didn't write this function (using congomongo)

17:03 somnium: theres a thread on clojure-dev about unrolling keyword args being preferred style now? (or suggested as preferred)

17:03 hiredman: somnium: unfortunately

17:03 but they'll pry it from my cold dead fingers

17:05 somnium: Ive been wondering about having a defnk derivative create a foo and a foo* where foo* just destructures a map, for this case

17:05 ordnungswidrig: re

17:06 hiredman: or just don't use defnk

17:06 somnium: so (fn foo* [opts a b & cs]) can still be overloaded on positional args

17:07 hiredman: too late in congomongo's case

17:07 hiredman: somnium: someone could file a bug

17:08 kotarak: the map argument for destructuring is not Rich's favoriute

17:08 somnium: thats like filing a bug with php for adding goto to the language :p (which has been done)

17:08 hiredman: I know this function takes a map, you know this function takes map, but it has been contrived not to take a map

17:08 somnium: goto is good

17:09 it will make writing a scheme to php compiler easier

17:09 somnium: just what Ive always wanted

17:09 hiredman: http://github.com/hiredman/php.lisp

17:10 :D

17:10 not scheme though

17:10 somnium: http://bugs.php.net/bug.php?id=48669

17:10 hiredman: somnium: the "goto considered harmful" is repeated without thought these days

17:11 somnium: hiredman: come on, that was kind of funny

17:11 hiredman: if λ is the ultimate goto, and we can't have λ's, at least let us have goto's

17:12 somnium: for compilers its handy, but I wouldnt want to see it in application code

17:13 hiredman: why not?

17:13 somnium: hmm, because it would it mean I was reading php

17:13 * the-kenny likes the "goto hell;"-comment

17:14 hiredman: I just think it's crazy

17:14 * technomancy has been known to "raise Hell" in Ruby code

17:14 hiredman: I know I am passing a map, the function obviously takes a map

17:15 but for some reason we want it to not take a map?

17:15 technomancy: actually, that's one thing Ruby's crazy syntax is really nice for

17:16 if the last argument is something like :foo => "bar", :baz => 3 then it wraps it up in a map

17:16 best of both worlds (except for the fact that you need those noisy arrows)

17:20 somnium: hiredman: part of its in the declaration too, if you take umpteen keyword args, you also have to specify umpteen default maps, and maybe an arglist too

17:21 hiredman: if you are passing umpteen billion arguments it's take to rewrite

17:21 somnium: my only complaint is defnk prevents arity overloads

17:21 hiredman: and I certainly would not want to use destructuring on umpteen args

17:22 I haven't look at the source for defnk, but I bet it uses destructuring as well

17:22 ~defnk

17:22 clojurebot: Pardon?

17:22 hiredman: ~def defnk

17:22 somnium: hiredman: it does)

17:23 hiredman: *sigh*

17:28 somnium: pythons *args, **kwargs is nice

17:31 ordnungswidrig: Is there api doc for contrib on clojure.org somewhere?

17:31 the-kenny: ordnungswidrig: http://richhickey.github.com/clojure-contrib/

17:31 ordnungswidrig: the-kenny: thanks, I didn't manage to navigate there from clojure.org...

17:32 the-kenny: ordnungswidrig: I always forget how to go to this doc. I have a bookmark for it :)

17:32 kotarak: ordnungswidrig: http://clojure.org/API links there

17:33 ordnungswidrig: kotarak: to bad that the sidebar link "API" links to http://richhickey.github.com/clojure/

17:33 kotarak: ordnungswidrig: I get two links, one for clojure, one for contrib

17:35 ordnungswidrig: ah ok. nevermind. misunderstanding. sorr

17:35 y

17:35 ordnungswidrig: no problem

17:46 opqdonut: somnium: no no, common lisp's keyword arguments are nice

17:46 i'd like to see a bit richer defn macro in clojure

17:46 neotyk: how do I list methods of java object in clojure?

17:47 hiredman: ,(doc show)

17:47 clojurebot: "clojure.contrib.repl-utils/show;[[x] [x selector]]; With one arg prints all static and instance members of x or (class x). Each member is listed with a number which can be given as 'selector' to return the member object -- the REPL will print more details for that member. The selector also may be a string or regex, in which case only members whose names match 'selector' as a case-insensitive regex will be printed. Finally

17:47 neotyk: hiredman: thanks

17:48 hiredman: ,(map #(.getName %) (.getMethods (class {})))

17:48 clojurebot: ("seq" "withMeta" "withMeta" "withMeta" "assoc" "assoc" "valAt" "valAt" "entryAt" "without" "assocEx" "asTransient" "asTransient" "count" "iterator" "containsKey" "capacity" "empty" "empty" "create" "equiv" "invoke" "invoke" "get" "put" "hashCode" "clear" "equals" "toString" "isEmpty" "values" "size" "entrySet" "putAll" "cons" "remove" "keySet" "containsValue" "applyTo" "call" "applyToHelper" "throwArity" "invoke" "invoke"

17:51 hiredman: ,(map #(.getName %) (.getDeclaredMethods (class {})))

17:51 clojurebot: ("seq" "withMeta" "withMeta" "withMeta" "assoc" "assoc" "valAt" "valAt" "entryAt" "without" "assocEx" "asTransient" "asTransient" "createHT" "equalKey" "indexOf" "count" "iterator" "containsKey" "capacity" "empty" "empty" "create" "create")

17:59 seths: has anyone else using swank-clojure noticed that *out* points to the *inferior-lisp* buffer while an agent is running?

17:59 disconcerting when you're expecting to see stuff at the REPL

18:00 hiredman: I don't think I've used an agent in slime/swank and I know about this

18:02 neotyk: seths: I've noticed it as well

18:02 hoeck: seths: yes, *out* is only bound properly in the slime-repl thread

18:11 wlr: seths: invoking (slime-redirect-inferior-output) supposedly redirects all output to the repl. can't *personally* vouch for all situations, however.

18:20 hoeck: wlr: didn't know about this one, thanks

18:23 wlr: hoeck: neither did i until reading one of bill clementson's blog entries. (don't have the exact one handy right now.)

18:44 hoeck: good Bill, his blogposts really helped me with my first slime setups some years ago

19:11 lancepantz: boo

19:12 joshua-choi: I'm trying to figure out how to call Clojure code from Java code, but with AOT-compiled Clojure. Is the only way to use clojure.lang.RT?

19:12 rhickey: joshua-choi: use RT.var to get the vars for any fns you want to call

19:13 you don't need any more of the Java API than that

19:13 i.e. you can get the var for require etc

19:13 joshua-choi: The thing I'm afraid of is compiling the code every time I call RT.loadResourceScript(someClojureFilename);.

19:14 Well, I think that happens, from what I understand

19:14 rhickey: wouldn't require just work?

19:14 joshua-choi: Is require a method in RT?

19:14 underdev: rhickey: its really cool that you are answering questions on the irc channel. ty.

19:14 joshua-choi: I'm looking at a tutorial (I can't find the API of RT).

19:14 Yes, it is really cool.

19:15 rhickey: joshua-choi: no, use RT.var to get the var for require

19:15 joshua-choi: Ah.

19:15 underdev: im very interested in this topic

19:15 rhickey: you can call any clojure fn that way

19:16 joshua-choi: So, RT.var("clojure.core", "require").invoke(clojureClassFilename); instead of RT.loadResourceScript(clojureScriptFilename);.

19:17 * aldebrn begs you guys/gals to make a DSL in Clojure for numerical computing, especially servicing linear algebra

19:17 rhickey: well, require would take (at least) the ns as a symbol

19:18 joshua-choi: but in general, if you know a clojure fn that does what you need, RT.var it then invoke

19:18 joshua-choi: Do you mean after loading a script or requiring a class?

19:18 rhickey: some RT and other Java API things can make that easier, but you don't *need* them

19:19 joshua-choi: what would you do in Clojure code?

19:19 scottj: With congomongo, is there a way to fetch a record based on it's id as a string not an ObjectId object?

19:19 joshua-choi: (require name.of.namespace) as long as name/of/namespace.clj or .class is findable

19:21 ninjudd: if i have a long running loop with recur, will previous persistent copies of data structures be garbage collected, or does that only happen after the loop is finished?

19:22 Raynes: I think I want to code something in Io now.

19:22 joshua-choi: @rhickey: So: RT.var("clojure.core", "require").invoke(clojureClassNamespace);, as long as the Clojure class is in the classpaths?

19:22 * Raynes runs off to do that.

19:22 rhickey: Var symbolFn = RT.var("clojure.core", "symbol");

19:22 Var requireFn = RT.var("clojure.core", "require");

19:22 requireFn.invoke(symbolFn.invoke("name.of.ns"));

19:22 joshua-choi: Okay. I see now; thank you very much.

19:23 rhickey: sure

19:31 ninjudd: if i have a long running loop with recur, will previous persistent copies of data structures be garbage collected, or does that only happen after the loop is finished?

19:32 rhickey: ninjudd: should be collected

19:32 if in the loop locals

19:33 ninjudd: ok, specifically, i'm using clojure.lang.PersistentQueue

19:34 it seems like the loop is getting slower and slower, and i wanted to rule out clojure as the problem

19:34 rhickey: ninjudd: with pqueue your productions/consumption ratio will affect collection

19:35 somnium: scottj: no, not if its a mongo-generated id. (ObjectId. "id-string") is all thats needed. (the reason is that :_id can hold anything, mongo-ids are just the default)

19:36 ninjudd: rhickey: right, the queue should never get bigger than a couple of thousand entries, but i'll look into it more

19:40 scottj: somnium: sweet, thanks

19:58 xp_prg: anyone want to tutor me on clojure?

20:10 Tcepsa: I'm attempting to do an implementation of Conway's Game of Life such that each cell is aware of (has a set containing) its neighbors.

20:10 That way, to determine what state each cell should be in, it can quickly check its neighbors' states.

20:11 Do I need to use refs to refer to the neighboring cells so that when they change state (from alive to dead or vice versa) their neighbors can see that change instead of still looking at an unchanged version of the cell?

20:11 chouser: if you're going to go that route, yes.

20:12 Tcepsa: chouser: Thanks

20:14 In that case, do I need to do something special to ensure that all of the cells change state at the same time? I don't want to update a cell before its neighbor knows what its state used to be.

20:16 seths: if I use (last (partition _ coll)) is that going to realize the whole collection? in linear time?

20:20 err, I guess the linear time is mentioned in the docs for (last), sorry

20:20 still curious about realizing everything tho

20:21 ulfster: Tcepsa: you could do a two-phase update und synchronize that

20:21 Tcepsa: ulfster: You mean, store the next-state on the first pass and then make a second pass that copies that into the current state?

20:22 ulfster: exactly

20:22 that will work

20:22 Tcepsa: ulfster: Awesome, I was just setting up to try that. Thanks for the confirmation! ^_^

20:22 ulfster: i am not sure if you can do it easier

20:23 Tcepsa: ~nods~ I'm not thrilled about walking the list twice, but at least it's still linear time.

20:30 scottj: How do you undefine a function? Say you've defined a fn and you move it to a new namespace, in order to use that namespace now you need to undefine the original (or restart clojure).

20:31 xp_prg: so nobody wants to tuor me?

20:31 hiredman: ,(doc ns-unmap)

20:31 clojurebot: "([ns sym]); Removes the mappings for the symbol from the namespace."

20:31 scottj: thanks

20:33 seths: xp_prg: some good offline resources are http://en.wikibooks.org/wiki/Clojure and http://clojure.org/getting_started

20:40 Tcepsa: xp_prg: Most of the people here seem happy to help out with specific questions when they can, but there are lots of good resources on the web for learning the basics and getting your feet wet.

21:11 If I'm inside a transaction, and I attempt to get the value of a ref that has been changed within that transaction, will the value returned be the value before the change, after the change, or will it throw an error?

21:11 s/error/exception

21:12 rhickey: Tcepsa: you will see your own changes inside a transaction

21:14 Tcepsa: rhickey: Okay, thanks ^_^

21:15 chouser: ,(let [r (ref 0)] (dosync (alter r inc) (prn :now @r)))

21:15 clojurebot: :now 1

21:16 Tcepsa: chouser: Ah, I see.

21:16 * Tcepsa loves how you can do that with clojurebot.

22:05 Tcepsa: Is there a way to use destructuring when passing a ref to a function (and/or is there a reason why that would be a bad thing to do?)

22:07 arohner_: Tcepsa: no there is not a way. I suppose it's possible, but a bit weird

22:08 Tcepsa: arohner: Thanks

22:11 drewr: Tcepsa: you mean to deref straight to a lexical?

22:14 Tcepsa: drewr: Say I have a reference to a map with :fname and :lname keys. Rather than using something like (let [fname (:fname @map-ref) lname (:lname @map-ref)] body) I'd prefer to just have those bound to the scope of the function when they're passed in.

22:14 I'm still unclear enough on exactly what "lexical" binding means to know whether that's what I just described ~wry grin~

22:15 drewr: in that case you could do (let [{:keys [fname lname]} @map-ref] ...)

22:16 Tcepsa: Ahh, thanks, that's better than nothing ^_^

22:16 rads: what is the advantage of using the upcoming deftype over a hash map? performance?

22:21 drewr: that, and abstraction

22:22 I'm not sure how much faster it is over map access though

22:23 I think the main performance pain point deftype addresses is multimethod dispatch

22:24 rads: coming from an OO background, I'm not sure when to create a new type and when to leave it as a hash map

22:25 in the context of functional programming, that is

22:27 drewr: I'm still developing a mental model myself

22:27 danlarkin: I haven't had occasion to use deftype myself :-/

22:27 Still looking out for the use case though

22:27 drewr: I've found it helpful to think in terms of protocols

22:27 what kinds of things do I want to *do*

22:28 map out the methods, then add types as they encapsulate components

22:31 rads: isn't the use of objects discouraged in clojure?

22:33 drewr: you have to go out of your way to create objects that contain mutable state

22:33 well, not that far out of your way

22:37 rads: I can understand using deftype like a struct, since defstruct is deprecated, but why would you add methods to a type in clojure when you have namespaces?

22:38 drewr: think of it as multimethods where the most common usage, dispatching on type, is given some perf and sugar

22:40 rads: is it mostly for the clojure-in-clojure stuff? it seems much more complicated than what is already there

22:43 drewr: yes, that was the primary catalyst

23:17 DeusExPikachu: I'm reading the definition for -main in core.clj in leiningen and I'm unsure why -main's argument list is as it is. What is the difference between [& [task & args]] and [task & args]?

23:18 chouser: [task & args] will throw an exception if you pass fewer than 1 arg

23:18 DeusExPikachu: ah, ok

23:18 chouser: [& [task & args]] will bind both task and args to nil and not throw any error if no args are passed in.

23:27 TheBusby: anyone using "Electric Ret" with Paredit (for emacs)

23:27 great screen demo of it here, http://img8.imageshack.us/img8/9479/openparen.gif

23:30 boyd: All it seems to do is put the closing parens in the wrong place

23:30 TheBusby: er, well yes, on the following line

23:31 boyd: ... which is great for, say, C

23:31 TheBusby: definitely a preference then

23:32 boyd: Sure. But closing parens on a seperate line is quite un-idiomatic in lisps

23:33 _mst: hitting the close paren moves the paren back off its own line, I think

23:33 TheBusby: notice at the end of the demo though

23:33 you just hit ) repeatedly to clean it up and make it look like normal lisp

23:33 boyd: Yes, but then why put them down there in the first place

23:33 ?

23:34 TheBusby: make it a little more clear while you're typing

23:34 I find it useful...

23:35 boyd: I can see the appeal. I think I am in the habit of watching the highlighted open parens when I close, so they seem a bit superfluous.

23:36 TheBusby: I'd like to integrate "Electric Ret" w/ paredit, but am unsure how to do so though

23:41 added the code snippet to ~/.emacs.d/$(USER).el but no luck

23:44 wlr: TheBusby: Are you experienced with paredit? Seems to me, if you were, you'd declare Electric Ret functionality superfluous.

23:45 TheBusby: wlr: I've used it quite a bit, but I'm still far from having mastered it

23:46 is there some paredit feature that makes electric ret superfluous

23:47 I use ")" quite a bit to pull close-round to end of line, but find having the "mountain of parens" easier to navigate when adding code in a hierarchy

23:49 wlr: TheBusby: just a gut feeling. the focus in paredit is on editing the structure/form of the program and only incidentally on the textual aspects.

23:51 i'm close to the point where old lispers say "What parentheses?" when newbies complain about Lotsa Irrelevant Stupid Parens.

23:52 TheBusby: wlr: I don't mind the parens, beginning to love them with paredit in fact, but you need to pay attention of them to determine which part of the code hierarchy you're in though

23:54 by the sound of it I just need more practice with paredit as is ;)

23:54 wlr & boyd: thanks for the help!

23:55 JonSmith: hi

23:56 is there a way to do array access in scriptjure?

23:58 arohner: JonSmith: you mean javascript array access?

23:59 JonSmith: yup

23:59 arohner: off the top of my head, I think you can use the function call syntax for arrays

Logging service provided by n01se.net