#clojure log - Nov 29 2010

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

2:29 raek: I love the smell of homoiconicity in the morning

2:46 Raynes: technomancy: Ever heard of PyTyle?

2:52 pppaul: what would be an easy way to write data with meta data to a file?

2:52 will spit record the meta-data?

2:55 replaca: pppaul: see http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/*print-meta*

2:55 pppaul: I've never used it, so YMMV

2:56 Raynes: &(doc *print-meta*)

2:56 sexpbot: ⟹ "; If set to logical true, when printing an object, its metadata will also be printed in a form that can be read back by the reader. Defaults to false."

2:56 pppaul: thanks

2:57 replaca: oh, that's right, bots!

2:59 Raynes: &(-> (binding [*print-meta* true] (pr-str (with-meta [1 2 3] {:doc "ohai"}))) read-string meta)

2:59 sexpbot: ⟹ {:doc "ohai"}

2:59 Raynes: Ta da

3:01 raek: &(meta (-> (binding [*print-meta* true] (pr-str (with-meta [1 2 3] {:doc "ohai"}))) read-string meta))

3:01 sexpbot: ⟹ nil

3:01 raek: oh. nevermind. :)

3:02 Raynes: That would have been super meta metadata.

3:05 pppaul: only the best kind

3:06 i'm trying to make a backup up a lasyseq using spit... how would i do so?

3:07 i tried doall, and doseq

3:07 data looks like: ({:custom3114088 "Mr.", :firstname "Blair", :lastname "Collins"})

3:08 tried dorun too

3:09 Raynes: I'm not an expert, but I'm pretty sure it's impossible to print a lazy sequence without unlazifying it.

3:09 pppaul: i would like to do so

3:10 raek: store the data without looking at it? :-)

3:10 Raynes: Since, being lazy, it doesn't know what it's elements are, and if it were to print "I'm stupid", the reader wouldn't know what to read it back as.

3:11 raek: maybe you could traverse the lazy seq and append the string version of each element to the end of a file

3:11 if holding on to the head was the issue

3:11 pppaul: it's not... i gave the whole data

3:11 ({:custom3114088 "Mr.", :firstname "Blair", :lastname "Collins"})

3:12 that is the whole thing i want to save

3:12 Raynes: Oh, you don't care if it remains a lazy seq?

3:12 raek: what do you get in your file?

3:12 pppaul: don't care

3:12 nothing, or @lazyseq.clojure... sutff

3:13 raek: hrm, are you calling str on it?

3:13 pppaul: no

3:13 raek: weird

3:13 pppaul: (spit "file.bak" (dorun corrected-contacts))

3:13 raek: dorun returns nil

3:13 pppaul: yeah

3:13 Raynes: &(pr-str (lazy-seq [1 2 3 4]))

3:13 sexpbot: ⟹ "(1 2 3 4)"

3:13 Raynes: Use pr-str

3:13 That's what all the cool kids do.

3:14 pppaul: i'll give it a shot

3:14 raek: weird! I can see in the source that it uses 'str' to make a string from the form

3:14 which is wrong

3:14 pppaul: bug?

3:15 raek: looks like it

3:17 I'll make a ticket

3:18 pppaul: the last issue i have is backing up the metadata

3:18 raek: ,(doc spit)

3:19 &(doc spit)

3:19 sexpbot: ⟹ "([f content & options]); Opposite of slurp. Opens f with writer, writes content, then closes f. Options passed to clojure.java.io/writer."

3:19 raek: &(doc slurp)

3:19 sexpbot: ⟹ "([f & opts]); Reads the file named by f using the encoding enc into a string and returns it."

3:19 pppaul: (#^{:id 324234} {:custom3114088 "Mr.", :firstname "Blair", :lastname "Collins"})

3:19 raek: pppaul: sorry, I was wrong. spit and slurp does not operate on data structures as I assumed

3:19 they work on strings

3:20 pppaul: oh

3:20 raek: i.e. no bug

3:20 pppaul: so, i should be using something else?

3:20 raek: well, you simply have to convert your seq to a string first

3:20 using pr-str

3:21 ,(binding [*print-meta* true] (pr-str ^{:foo :bar} [1 2 3]))

3:21 &(binding [*print-meta* true] (pr-str ^{:foo :bar} [1 2 3]))

3:21 sexpbot: ⟹ "[1 2 3]"

3:21 pppaul: pr-str wasn't smart enough to walk my structure to print the meta-data of each element

3:22 i guess pr-str doesn't print meta data period

3:22 maybe there is a smarter way to write out objects

3:22 raek: &(binding [*print-meta* true] (pr-str (with-meta [1 2 3] {:foo :bar})))

3:22 sexpbot: ⟹ "^{:foo :bar} [1 2 3]"

3:23 brehaut: what is the correct way to compare two byte arrays for equivalence?

3:23 raek: brehaut: value or identity?

3:23 brehaut: value

3:23 raek: pppaul: ^

3:23 pr-str can indeed print metadata

3:23 pppaul: ok

3:24 not sure why it's not working for me

3:24 raek: but metadata on the *code* (introduced by ^) is not the same as metadata on the *value*

3:24 pppaul: oh, i didn't use binding

3:26 raek: &(= (seq (to-array [1 2 3])) (seq (to-array [1 2 3]))) ;; <-- this is one way

3:26 sexpbot: ⟹ true

3:26 brehaut: raek, works for me

3:26 i only need it for a testcase

3:26 pppaul: i have metadata on the values

3:27 raek: &(java.util.Arrays/equals (to-array [1 2 3]) (to-array [1 2 3])) ;; <-- this seems to be the java way

3:27 sexpbot: ⟹ true

3:28 brehaut: raek cheers

3:29 pppaul: so, i used the binding and the metadata still isn't printing out

3:29 (binding [*print-meta* true]

3:29 (pr-str corrected-contacts))

3:29 (meta (first corrected-contacts))

3:30 solve360=> "({:custom3114088 \"Mr.\", :firstname \"Blair\", :lastname \"Collins\"})"

3:30 solve360=> {:id 9916966}

3:30 the metadata is on the inner hashmap

3:35 raek: also, which version of clojure do you use?

3:38 pppaul: 1.2

3:38 do i have to walk my structure calling pr-str on each item?

3:40 actually, i just tried (map pr-str data) and it didn't work

3:42 (binding [*print-meta* true]

3:42 (pr-str (with-meta [123] {:doo 4})))

3:43 raek: &(binding [*print-meta* true] (pr-str (lazy-seq [(with-meta {:a 1, :b 2} {:foo "bar"})]))))

3:43 sexpbot: ⟹ "(^{:foo \"bar\"} {:a 1, :b 2})"

3:43 pppaul: just prints [123]

3:43 raek: &(binding [*print-meta* true] (pr-str (with-meta [123] {:doo 4})))

3:43 sexpbot: ⟹ "^{:doo 4} [123]"

3:43 raek: that is very weird

3:43 pppaul: ok

3:44 before i used binding i did (def *print-meta true)

3:44 could that be screwing stuff up?

3:44 raek: yes

3:44 pppaul: is there a way to revert?

3:44 raek: then you created your own var called *print-meta* in your namespace

3:44 yes

3:44 pppaul: ^_^

3:44 raek: (ns-unmap 'your-ns '*print-meta*)

3:44 (refer-clojrue)

3:44 (refer-clojure)

3:45 pppaul: ok

3:45 both those, or just the last one?

3:45 raek: the repl is in a binding form that rebinds the usual *earmuffed* vars

3:45 so you can change it with set!

3:45 ns-umap to remove your

3:46 refer-clojure to add clojure's

3:46 pppaul: thanks so much, that fixed things :D

3:46 i'm so silly

3:46 raek: (set! *print-meta* true)

3:47 pppaul: spit is spitting good things

3:47 raek: np.

3:49 if you read it back using slurp and read-string, you might want to bind *read-eval* to false for security reasons

3:56 pppaul: oh

5:52 birdspider: hi, is there another option to call clojure from java apart of (typedef,gen-class + AOT) or RT,VAR, stuff ? something like gen-class without AOT ?

5:54 LauJensen: not yet, AFAIK

8:46 Licenser: aloaeh!

9:28 chouser: clojure.contrib.json can't be extended to add new kinds of things in the reader?

9:38 tonyl: morning

9:44 opqdonut: how can I make eval evaluate something inside a given ns?

9:44 use case: I'm dumping data as clojure exps that use a couple of utility functions to build the data

9:45 (also, it seems that evalling a very large vector of things causes the constant pool to overflow. thus i'm doing a (map eval (read-string "...")) )

9:48 chouser: (binding [*ns* your-namespace] (eval ...))

9:49 (binding [*ns* your-namespace] (vec (map eval ...)))

9:50 opqdonut: thanks

9:50 err but in that case eval evals in the current namespace?

9:50 which doesn't seem to be the case

9:51 chouser: it evals in your-namespace

9:51 opqdonut: i mean, if I don't bind

9:54 octe: i have a seq of strings and want to change on character in one of the strings, what's the simplest way?

9:54 tonyl: just one character in one string? do you know the index of that string?

9:55 octe: yes, i know the index in the seq and in the string

9:56 jarpiain: opqdonut: you get a VerifyError from (eval '[x y z ...]) ?

9:56 octe: basically, replace the nth item of a seq

9:56 i'll figure out how to create the new string

9:58 tonyl: octe: you can use the nth function

9:58 and clojure.string/replace

9:58 opqdonut: java.lang.ClassFormatError: Invalid this class index 3171 in constant pool in class file sick$eval8275 (measurements.txt:4)

9:58 that's what I get when trying to load-file it

9:59 octe: tonyl, i dont understand how to use the nth-function to generate a new seq with one item replaced

9:59 map-indexed perhaps

10:00 chouser: yeah, map-indexed, though if you'll be dealing with indexes into that seq much at all, it may be worth using a vector instead

10:00 tonyl: yes map-indexed would help in that case

10:00 chouser: then you can just use update-in

10:01 octe: chouser, yeah, i guess. it's a seq due to reading it from a file

10:01 i'm making an ascii-game and it's a representation of the level

10:01 feels kind of inefficient to make a new copy of the structure every time something needs to change (door opened for example)

10:02 chouser: with a vector, you'll get structural sharing

10:02 with a seq, you'll likely have to keep working around the laziness of the thing (map-indexed is lazy!) and you'll get no structural sharing

10:03 just sharing of unchanged leaf objects (which you'd get with vectors as well)

10:04 Chousuke: immutable world state enables all kinds of fun things

10:04 like time travel

10:04 octe: update-in sounds like it's suppsoed to be used with maps

10:05 Chousuke: it works with anything associative

10:08 octe: hmm, this seems convoluted

10:08 ,(update-in (vec '("a" "b")) '(1) (fn [& rest] "x"))

10:08 chouser: assoc-in, if you don't care about the old value

10:08 & (assoc-in ["a" "b"] [1] "x")

10:08 sexpbot: ⟹ ["a" "x"]

10:09 octe: nice, thanks

10:09 new bot?

10:16 chouser: oh, he's been here a while now. handy to have a backup. :-)

10:17 djpowell: chouser: I was playing with finger trees - made a sortedvector. It seemed a bit slow though...

10:17 chouser: yeah. they have large constent cost compared to Clojure's collections. :-(

10:17 performance patches welcome! :-D

10:18 djpowell: I tried using the jvisualvm sampling profiler - it pointed to a couple of things in clojure, but I'm not sure whether to trust it

10:20 I think the vec call is taking a bit of a slow path in clojure because clojure can't determine whether there are <= 32 elements in the concat-ed expression

10:21 chouser: I can't work on it right now, but I'd be thrilled to accept a performance patch.

10:22 djpowell: I was wondering whether there could be a better way of combining the metrics too than calling reduce over them. When the metric is stored in a defrecord or something, it might be more efficient for the monoid to accept more than 2 params, rather than producing a bunch of junk intermediate defrecords

10:23 Would be interesting to compare against Functional Java's fingertrees too

10:23 I'll have a play with it

10:37 octe: is there a simple way of writing and reading clojure structures to files? like vectors and maps

10:37 Chousuke: depends on what they contains

10:37 -s

10:38 octe: well, assuming simple stuff, primitives, strings, vectors, maps

10:38 Chousuke: then you can use pr and read

10:38 octe: what if they'd contain java serializable objects?

10:39 Chousuke: then I have no idea.

10:39 you'd have to do something custom

10:39 octe: alright

10:39 thought there might be something built in

10:41 Chousuke: the safest approach will probably be to use json or xml :P

11:05 edbond: /set irc_conf_mode 1

11:16 AWizzArd: http://news.ycombinator.com/item?id=1950312

11:17 * fogus` (name-quiz) ;; 17/20

11:18 chouser: still trying to get cake working

11:19 ah, don't need cake

11:19 AWizzArd: fogus`: grats :)

11:19 chouser: bah, said 'disj' not 'disj!'

11:20 AWizzArd: (:

11:20 fogus`: The struct stuff kills me. :-(

11:21 jaley: hi guys. does anyone know what needs to be in project.clj file for leiningen to generate an uberjar including some java code from my source tree? do i need an :aot field?

11:22 cemerick: fogus`: bah, 16/20 here! :-D

11:23 the quiz should filter out subjects where the answer is in the doc as part of an example

11:24 chouser: 16/20

11:26 raek: jaley: you want to compile the java sources with leiningen too?

11:26 then you need to use a plugin

11:26 jaley: raek: yeah, i've compiled them with lein-javac actually. now i want the compiled classes included in the jar

11:27 raek: ah, they don't get included?

11:27 jaley: raek: not with my current configuration... that's why i'm wondering if anything special needs adding to the project.clj?

11:28 raek: at least i imagine that's the issue. at the moment leiningen is trying to compile my clojure code and aborts on the (ns) form that attempts to import the java classes

11:29 raek: does it work in the repl?

11:30 what happens if you do (import 'one.of.the.Classes) in the repl?

11:30 jaley: raek: actually... no. not now that i've added a gen-class to my core.clj (where -main is)

11:31 fogus`: cemerick: My next attempt was only 15/20 ... apparently there is no unchecked-sub function :-(

11:32 raek: jaley: does you java code depend on you clojure code, or the other way?

11:32 chouser: you gotta be kidding. 'unchecked-remainder-long' sheesh

11:33 jaley: raek: clojure depends on java. i just found the issue actually, but not sure how to fix. lein uberjar "cleans up" the generated java classes

11:33 fliebel: Is there something like Clojure.news, similar to its arc counterpart? In other words: any reddit clones in Clojure?

11:33 jaley: raek: lein javac puts them back, then the repl works again

11:34 raek: but then lein uberjar will re-erase them before attempting to build the jar

11:35 raek: I'm afraid I'm out of advice

11:35 maybe you could ask technomancy when he is around

11:36 also, make sure you have a recent version of lein-javac, etc

11:37 jaley: raek: cool, thanks, i'll play around with it some more. i have 1.2.1, which is the latest i can see on clojars

11:37 chouser: 2nd attempt: 17/20

11:39 raek: jaley: also, leiningen has a mail list. could be worth checking out.

11:40 fliebel: hah! Not much, but it might do what I need. https://github.com/LauJensen/cloneit/blob/master/src/cloneit.clj

11:41 raek: jaley: also, it looks like the lein 1.4 release candidate has something like lein-javac built in

11:41 * dnolen is glad for gvec.clj as a thorough reference on writing highly optimized Clojure

11:42 jaley: raek: got it... lein-javac comes with a hook to add itself to the compile and clean targets, so you have to add :hooks [leiningen.hooks.javac] to project.clj for uberjar to work.

11:42 raek: I see

11:57 fliebel: How would I remove the repetition in this code? There are some unique parts and a recur, which make it hard to abstract. Only workable thing I can come up with is putting the lets in a macro. https://github.com/pepijndevos/clojure-quiz/blob/master/src/clojure_quiz/core.clj#L43-54

12:33 hugod: looking for github advice - best way to transfer a personal github repo into a github organisation? create the new repo and push from the pld? I know clojure went through this process, so hence the question here

12:34 dgreensp: er

12:35 ^H^H

12:35 does anyone know why this is false?

12:35 (list? (list* 1 '(2 3)))

12:37 raek: ,(class (list* 1 '(2 3)))

12:37 clojurebot: clojure.lang.Cons

12:37 raek: ,(seq? (list* 1 '(2 3)))

12:37 clojurebot: true

12:37 raek: list? checks if it is a persistent (counted) list

12:38 list* just conses things on a sequence

12:38 dgreensp: ah, interesting

12:39 so, I'm trying to parse an s-expr, kind of a domain-specific language

12:39 and one of my cases is (list? x)

12:39 should I be using something different?

12:39 raek: ,(class ''foo)

12:39 clojurebot: clojure.lang.PersistentList

12:40 raek: ,(class (read-string "'foo"))

12:40 clojurebot: clojure.lang.Cons

12:40 mduerksen: is the author of the clojure quiz in here?

12:40 raek: dgreensp: I think seq? would work in your case

12:40 mduerksen: I think the author is fliebel

12:41 dgreensp: ,(seq? [1 2 3])

12:41 clojurebot: false

12:41 dgreensp: so vectors are never seqs?

12:41 raek: true

12:41 dgreensp: ok, sounds like seq? is what I want then, thanks :)

12:42 raek: PersistentList and Cons are the only types that implement the ISeq interface directly

12:42 *collection types

12:42 tonyl: dgreensp: or if you want vectors too you can use coll?

12:47 dgreensp: I'm using a nested combination of vectors and parenthesized lists as a data structure

12:47 so basically I need to tell them apart, and when transforming them generate an expression that passes the tests again

12:48 I knew from past experience that (list? (map ... wouldn't necessarily be true, but I thought (list? (list* ... would be, heh

13:03 fliebel: mduerksen: Yes, he is :)

13:04 mduerksen: ping

14:03 mduerksen: fliebel: pong :)

14:03 fliebel: mduerksen: what's up?

14:05 mduerksen: fliebel: i was enjoying your game, and will eventually use it to test my overall clojure knowledge

14:05 nickik: did you make the clojure quiz?

14:06 i just downloading that atm. :)

14:06 fliebel: yes, I did.

14:08 mduerksen: fliebel: maybe you already considered this, but i have a suggestion (for the "hardmode"): i often could guess the answer because the exact funtion name was mentioned in the doc string. how about mask the occurrences of the literal funtion name in the doc string?

14:10 fliebel: mduerksen: Yes, I did consider this. But I found some occasions where the same word was used in a sentence in a not so obvious way. By emphasizing these words by removing them, you will also spoil it.

14:10 I will look up an example

14:11 &(doc class)

14:11 sexpbot: ⟹ "([x]); Returns the Class of x"

14:11 mduerksen: fliebel: i know what you mean. another problematic example would be "key", as you could only guess the semantics with the word 'key'

14:12 fliebel: &9doc keys)

14:12 sexpbot: java.lang.NumberFormatException: Invalid number: 9doc

14:12 mduerksen: exactly. for these cases, it could be sufficient to mask the literal function name in all sentences except the first one

14:13 fliebel: $(doc keyword)

14:13 mduerksen: i haven't completely checked if that would work all the time, but my impression (after 60 questions :) ) was that it might be sufficient

14:14 fliebel: keyword has keyword mentioned in the second sentence

14:15 mduerksen: hmm, yes, and in an unemphasized way. :(

14:16 fliebel: And on the other hand, namespace would eb impossible to guess with the word namespace replaced.

14:18 mduerksen: well that wouldn't be the case the first sentence remained unmasked.

14:18 fliebel: true

14:19 So that would work 99% of the time. Probably worth it.

14:20 mduerksen: maybe there is a pattern to be found for the "spoilers", something like ' around it or so? i'm checking now :)

14:21 tensorpudding: how might one use 'require' on the repl to import namespaces?

14:21 fliebel: I think (<word> might be a good one.

14:21 tonyl: (require 'clojure.string)

14:22 fliebel: tensorpudding: (require 'some.namespace)?

14:22 tonyl: tendsorpudding: ^^

14:22 tensorpudding: i want to import something from clojure-contrib

14:22 ah, that seems to give me classpath issues

14:22 i'm running the repl through lein

14:22 tonyl: it's the same ##(require 'clojure.contrib.repl-utils)

14:22 sexpbot: java.io.FileNotFoundException: Could not locate clojure/contrib/repl_utils__init.class or clojure/contrib/repl_utils.clj on classpath:

14:23 tensorpudding: hey, that's the error i got

14:23 tonyl: if that happens means that that namespace is not in the classpath

14:23 dnolen: tensorpudding: useful to alias, (ns your.foo (:require [clojure.contrib.monads :as m]))

14:23 tensorpudding: is the contrib jar in your lib folder in your project?

14:23 tensorpudding: yes

14:24 tonyl: what ns are you trying to require?

14:24 tensorpudding: oh wait

14:24 damn

14:25 i was using a hyphen

14:25 it works now

14:25 dnolen: if you don't alias you will have to write really long names.

14:25 tensorpudding: clojure.contrib.repl-utils/source and the like

14:26 tensorpudding: i was require-ing clojure-contrib.foo, not clojure.contrib.foo

14:26 dnolen: if you alias you can write r/source or whatever

14:26 tensorpudding: i know

14:26 i have it aliased in my file

14:26 but i'm testing things out on the repl at the same time

14:33 fliebel: This returns all functions that contain their own name. (filter #(.contains (str "" (:doc (meta (val %)))) (name (key %))) (ns-publics 'clojure.core))

14:40 mduerksen: 125 one of them. with the pattern (<name> i get 30

14:40 so 95 would be left :)

15:04 fliebel: mduerksen: But these 30 are good to replace for sure

15:05 tensorpudding: what's the clojure equivalent to #' ?

15:05 fliebel: tensorpudding: #'?

15:05 tensorpudding: from common lisp

15:06 fliebel: What does it do in CL?

15:06 tensorpudding: for instance, (apply #'+ '(10 10 10)) => 30

15:06 zellio: tensorpudding: you don't need it

15:06 (apply + [10 10 10]) works as is

15:06 joly: &(apply + '(10 10 10))

15:06 sexpbot: ⟹ 30

15:07 tensorpudding: ah, but what i have is more complicated

15:07 zellio: tensorpudding: what do you have/

15:07 tensorpudding: though let me see

15:07 fliebel: #'+ allows you to redefine + though, and make it use the redefined version.

15:07 zellio: ( sorry it's scrolled away )

15:07 tensorpudding: apply is complaining that i give it a symbol

15:09 zellio: tensorpudding: pastebin your code

15:09 tensorpudding: i've got a hash of functions, and i'm using (get table keyword) to pick a function, then apply-ing it

15:10 but it turns out that i was referring to the functions with symbols, that was the issue

15:10 zellio: mmkay

15:21 Raynes: tensorpudding: You should be able to just do (keyword table), since keywords are functions that take a map and look themselves up in it. No need for get.

15:22 &(:blah {: blah 1 :rawr 2})

15:22 sexpbot: java.lang.Exception: Invalid token: :

15:23 Raynes: Well, you get the idea. Hard to type code on this phone.

15:24 joly: &(apply ({:add + :sub -} :add) '(10 10 10))

15:24 sexpbot: ⟹ 30

15:27 Raynes: That works too. ;)

15:27 tensorpudding: what's the syntax of cond?

15:28 dgreensp: tensorpudding: (cond test1 then1 test2 then2...

15:28 Raynes: &(cond false 1 true 2)

15:28 sexpbot: ⟹ 2

15:28 defn: dnolen: logos == cool

15:29 tensorpudding: okay, so it's not like scheme

15:29 Raynes: defn: Buy me a better phome for Christmas.

15:30 joly: I think condp is more like Scheme's cond

15:30 tensorpudding: lisp is quite the mess

15:31 dgreensp: no, scheme's cond is just like clojure's but with more parens

15:31 tensorpudding: syntax, i meant

15:31 Raynes: Dare I say Clojure is less of a mess than some others?

15:31 tensorpudding: though lisps differing by frustrating little bits of syntax is par for the course

15:32 dgreensp: what's the most readable way to test whether a value is of the form ('Y foo), i.e. (list 'Y foo) for some foo?

15:33 Munksgaard: Raynes, i think things like (cond test1 then1 test2 then2) is much more of a mess than (cond (test1 then1) (test2 then2)). It has more parens, but imo it's much clearer what belongs to what.

15:33 tensorpudding: yay, it builds! boo, it fails on running!

15:33 dnolen: defn: hey thx! a bit broken at the moment

15:33 Munksgaard: What is the advantages of clojures conds over lisps?

15:34 tensorpudding: fewer parens, apparently

15:34 dnolen: defn: looking forward to seeing what kind of perf deftypes can bring to the mplus/bind stuff.

15:34 tensorpudding: my program somehow can't find my main method...

15:34 dnolen: defn: I'd like to have a Prolog-like REPL that you can start from w/in Clojure

15:35 tensorpudding: but it was able to build?

15:40 Raynes: Munksgaard: I am a fan of clear indentation rather than pointless parens.

15:43 defn: dnolen: yeah! that'd be awesome.

15:44 www.github.com/jashmenn/clj-file-utils

15:45 oh wait -- i forgot the 11th commandment: "thou shalt not say 'awesome' without considering tradeoffs"

15:46 dnolen: that's be 'interesting'. :)

15:47 Munksgaard: Raynes, I definitely see your point, but i'm just wondering if there are any implementational advantages. Is it faster to parse (cond test1 then1 test2 then2 ..) than (cond (test1 then1) (test2 then2) ..), or does it allow clojure to use some faster datatypes (vectors?) for the arguments, or whats the deal? I don't think you should be changing syntax just because you can get rid of a few

15:47 parens, if you need to have way more messy compiler-code.

15:48 chouser: it's not *changing* syntax. Clojure's cond has always been that way.

15:48 Munksgaard: Good point :-)

15:48 chouser: :-)

15:49 to the extent that "too many parens" is cited as an excuse to ignore lisp, it may be worth some effort in the compiler code to reduce the validity of that claim.

15:50 fogus`: ,(inc chouser)

15:50 clojurebot: java.lang.Exception: Unable to resolve symbol: chouser in this context

15:50 fogus`: no love

15:51 Raynes: (inc chouser)

15:51 sexpbot: ⟹ 1

15:51 fogus`: (inc chouser)

15:51 sexpbot: ⟹ 2

15:51 fogus`: Raynes: thx

15:55 Munksgaard: chouser, you're propably right :-). I'm just a bit sad that the simplicity/purity of lisp is being sacrificed like this, but then again, as you said, this ain't lisp...

15:56 * defn beats himself in the head with a rock.

15:56 fogus`: Munksgaard: What defines purity?

15:56 defn: not this paren talk again!

15:56 Munksgaard: defn, sorry! I'll stop!

15:56 defn: haha nono it's fine

15:57 Munksgaard: :-)

15:57 defn: I was going to take this opportunity to say that you check out Land of Lisp

15:57 Munksgaard: I guess it's been discussed a billion times in here already.

15:57 defn: the author does a terrific job of "selling" lisp

15:57 hiredman: I assume by "lisp" you mean "common lisp"

15:57 chouser: I think it'd be fair to say Clojure is a step or two away from the purity of something like scheme, in exchange for a whole load of practicality and avoidence of several kinds of accidental complexity.

15:57 defn: hiredman: that assumption (at least in my case) would be correct

15:57 tensorpudding: is there a function which mangles strings to integers?

15:58 hiredman: in which case a. common lisp is not the only lisp, so please specify and b. common lisp is hardly something to be considered "pure"

15:58 chouser: & (pr-str 1234)

15:58 sexpbot: ⟹ "1234"

15:58 defn: i've never heard that terminology: "mangles"

15:58 Munksgaard: defn, yeah i'm actually in the (slow) process of reading through it atm. I like it and lisp a lot, but clojure also draws me a bit with it's smaller standard library, speed etc.

15:58 tensorpudding: i want the other way around

15:58 defn: im just doing land of lisp to have some context

15:59 tonyl: &(Integer.parseInt "1234")

15:59 sexpbot: java.lang.ClassNotFoundException: Integer.parseInt

15:59 tonyl: &(Integer/parseInt "1234")

15:59 sexpbot: ⟹ 1234

15:59 defn: i plan on sticking around in clojure-land for some time to come

15:59 Munksgaard: chouser, good way to put it, i'll keep that in mind.

15:59 tensorpudding: i *have* to use java for this?

15:59 also it would preferably not be restricted to integers?

16:00 defn: tensorpudding: (defn str->int [i] (Integer/parseInt i))

16:00 (str->int "5423")

16:00 err replace that i with an s

16:00 chouser: & (read-string "[:not :a Integer 123.456]")

16:00 sexpbot: ⟹ [:not :a Integer 123.456]

16:00 tonyl: so any number?

16:00 mabes: and type hint the i

16:01 defn: i dont really see any problem with using Java in your clojure code. that's sort of the point, isn't it? use what's there? that being said, i like to break most of the java I use out into a tiny clojure function to keep things tidy

16:01 tensorpudding: i don't know, when i feel that i must call java (which has happened twice since i started writing this thing) that it's a shortcoming of the language

16:02 moreover, i have a dislike of java

16:02 defn: tensorpudding: there are other ways to do it in clojure

16:02 tensorpudding: i suppose i could use a regex

16:02 that would be a lark

16:03 defn: im a walking lark

16:03 danlarkin: no I'm a walking lark!

16:03 chouser: tensorpudding: Clojure intentionally embraces the host environment and so does not abstract parts of it that don't need to be abstracted. Using Java method calls really is fine.

16:03 defn: chouser: i had the same reaction initially to using Java in Clojure

16:03 it felt...dirty...

16:03 chouser: defn: we all did

16:04 tensorpudding: i'm mostly using clojure because it's a lisp with more features and less cruft, in spite of my ambivalence about java

16:05 chouser: http://clojure-log.n01se.net/date/2009-10-04.html#21:24

16:05 tensorpudding: in any case, if i used that parseInt i'd have to catch an exception if it's not an integer

16:05 chouser: sorry to quote myself. :-P

16:05 tensorpudding: you saw you could use read-string ?

16:05 tensorpudding: and i haven't gotten far enough in clojure to handle exceptions

16:06 defn: 1. "oh! Java!?" 2. "Eww! Java!" 3. "Ah... Java..."

16:06 chouser: though that can throw exceptions too

16:06 hiredman: I wouldn't use read-string

16:07 use parseInt or similiar

16:07 chouser: hiredman: why?

16:08 hiredman: the domain and the range are just too broad

16:08 tensorpudding: hmm, read-string works nicely

16:08 hiredman: read-string will take any string and try and turn it into anything

16:09 you may not even get the type of number you want

16:10 it's just way to loose

16:11 defn: dont i remember some other way of doing it

16:11 hmmm

16:12 chouser: I want a pod

16:12 so I can put a SimpleDateFormat in it.

16:12 * chouser glares at Java

16:12 chouser: I guess I'm back to 2

16:13 defn: wasn't there some way of mapping char across your string and then doing something to get a number?

16:13 brehaut: tensorpudding: late reparens: dont forget that clj allows optional commas

16:13 hiredman: defn: just use parseInt

16:14 dakrone: defn: ping

16:14 chouser: unless you want to allow floats, then use parseFloat or parseDouble

16:14 or if ints are big enough, then use parseLong

16:14 hiredman: chouser: indeed

16:14 chouser: aren't

16:14 defn: dakrone: pong

16:14 clojurebot: No entiendo

16:14 hiredman: infact parseLong would be better than parseInt

16:15 defn: hiredman: oh i agree with you, i was just thinking for the sake of brevity

16:15 might as well mention it

16:15 hiredman: chouser: why would you ever want floats :(

16:16 tonyl: because we don't want to discriminate the natural numbers

16:17 then again there are also imaginary ones

16:17 qed: don't want the ACLU to get involved...

16:17 (rimshot)

16:17 hiredman: I wonder if Ratio has a parseRatio (my guess is no)

16:18 might be a nice patch...

16:20 tonyl: that would be

16:20 chouser: hm, clojure.lang.LispReader/readNumber looks nice

16:20 too bad it's private

16:21 tonyl: I was thinking of a generic fn

16:21 chouser: like that readNumber

16:22 hiredman: https://github.com/hiredman/clojure/blob/readerII/src/clj/clojure/reader.clj#L728

16:23 Chousuke: that is seriously a hideous function. :P

16:24 I mean read, not read-number

16:24 but I guess that's what you get when you translate java.

16:24 hiredman: well, you know, I was forced to it for bootstrapping reasons

16:25 and that

16:25 Chousuke: I somehow managed to get my reader working without any weird tricks.

16:25 but it's pretty bit-rotted right now.

16:25 hiredman: mine too

16:25 Chousuke: it was fun to write though.

16:26 hiredman: yep

16:27 I want to rewrite using defrecord(deftype?) sometime, should be much cleaner and easier, but I hate to have to muck with the build again

16:28 I re-worked the build to build normally -> aot compile the reader -> build again using the reader

16:29 and, uh, I can only imagine the build.xml has gotten worse since then

16:34 defn: is there no way to delete a jar from clojars?

16:35 lancepantz: defn: correct

16:36 hiredman: you can ask someone (technomancy?)

16:40 defn: lancepantz: is that...intentional?

16:41 hiredman: immutable

16:44 lancepantz: defn: i'm not sure, but it does make some sense, if your project is dependent on something there, you don't want it going away

16:44 it's obviously troublesome to correct accidents tho

16:56 dmart_: does clojure have a sorted list, or just the sorted map? I have a defrecord with one field being a date, and I'd like to create a list of them sorted by that date field, without re-referencing the date through a key

16:56 did I just make any sense?

16:56 chouser: dmart_: how does a sorted-set strike you?

16:57 dmart_: hmm, does that also require a key/value? I suppose my dates are unique

16:58 maybe it just makes sense to sort the list once I've built it up, heh

16:58 I'm probably over complicating things

16:58 chouser: hm, could be. sort on a seq is pretty fast

16:59 dmart_: I also appear to be using a tonne of memory building up this data set, but I'll try and figure that out next

17:02 chouser: huh, I thought there was a compare-by

17:02 ossareh: Hey, I've a deftype which the defprotocol P implements the "talk" functions of. When im in other-ns and I import P I cannot call "talk" on P.

17:03 chouser: like (defn compare-by [f] (fn [a b] (compare (f a) (f b))))

17:03 hiredman: ossareh: a protocol creates a group of functions

17:03 ossareh: (talk (P.)) => "Unable to resolve symbol: draw in this context"

17:03 hiredman: uh

17:03 ossareh: s/draw/talk/

17:03 sexpbot: <ossareh> (talk (P.)) => "Unable to resolve symbol: talk in this context"

17:03 chouser: & (sorted-set-by #(compare (:date %1) (:date %2)) {:date 5 :name "foo"} {:date 3 :name "bar"} {:date 8 :name "baz"})

17:03 sexpbot: ⟹ #{{:date 3, :name "bar"} {:date 5, :name "foo"} {:date 8, :name "baz"}}

17:04 hiredman: and you don't create instances of a protocol

17:04 ossareh: hiredman: huh... I'm clearly in need of some education.

17:04 :)

17:04 hiredman: ossareh: right, so go do some reading

17:07 dnolen: ossareh: defprotocol and deftype/record are a bit abstract, easy to be confused at first. Joy of Clojure probable does the best job in explaining them.

17:12 cpfr: If I am creating a graph structure that I want to be lightweight, should I use defstruct or defrecord?

17:12 danlarkin: cpfr: neither

17:13 cpfr: danlarkin, what should I use? maps and edgelists?

17:14 danlarkin: yup

17:16 cpfr: danlarkin, when is using a defstruct or defrecord appropriate?

17:17 * ossareh now owns the joy of clojure.

17:17 danlarkin: cpfr: defstruct is never appropriate imo

17:17 defrecord is appropriate when used in conjunction with protocols

17:18 but it's not right to use when what you really want are hash maps

17:18 birdspider: hello, is it possible to use defprotocol/deftype with gen-class ? (and AOT)

17:18 cpfr: as I understand protocols is for doing multimethod like things efficiently

17:19 chouser: danlarkin: I think it's ok to use defrecord when you have a lot of hashmaps with the same keys. Sames time and memory, with very small downside.

17:20 Saves

17:21 birdspider: yes, though if you're using gen-class for anything other than interop with existing Java code or creating static methods, there's probably a better way.

17:22 dnolen: cpfr: if you want something to be very light weight, I would use deftype. But I would start with map and work backwards.

17:23 there are even many costs with defrecord - i.e. lookup time in collections.

17:23 birdspider: chouser, i'm interoping (well experinmenting with)

17:23 chouser: dnolen: how is defrecord heavier than deftype when you wan something like a map?

17:25 dnolen: chouser: sorry I missed the part where he said he needed it to be like a map. then sure.

17:25 mefesto: Hey everyone. I'm implementing a web service using jax-ws and want to use clojure for the impl. I'm using maven w/ the jaxws plugin which generates artifacts from an existing wsdl. It seems that the clojure-maven-plugin cannot see these generated artifacts and fails to compile. Does anyone know if there is a way to configure the classpath for the clojure-maven-plugin?

17:26 stuartsierra: I don't know, but the clojure-maven-plugin Google Group probably will.

17:26 mefesto: stuartsierra: thanks, i should've checked

17:27 stuartsierra: I meant you'll probably have to ask there… that's a question for Mark Derricut (plugin author)

17:39 mefesto: n/m my problem was completely user error :)

17:47 birdspider: chouser, what could it be if the defprotocoll and reify things work in clojure but AOT gives me a "java.lang.ClassNotFoundException: test.withclass.H (withclass.clj:9)" clj: http://pastebin.com/AFj4G6Ew java: http://pastebin.com/grAt03Qy

17:54 chouser: birdspider: sorry, won't be able to look at it just now

17:56 birdspider: chouser, kk

17:58 vilfredo: I'm trying to run through the compojure getting starting, but hitting 'Wrong number of arguments to repl task. \n Expected ([] [project])'

17:58 what is this beginner missing?

18:00 joegallo: Is your current directory in a place that has a project.clj file?

18:00 You might need to cd to the right place.

18:00 technomancy: vilfredo: sounds like the compojure tutorial is out of date

18:01 just do "lein repl" without any arguments, then (use 'whatever.namespace) that the tutorial needs

18:02 vilfredo: perfect. Cheers

18:19 ossareh: so I've read chapter 9 of The Joy of Clojure - so now I have a defprotocol that has a couple of methods on it and a defrecord that implements those methods. I guess the only thing that is tripping me up is accessing the methods on the record from a different NS.

18:21 hiredman: they are not methods

18:21 they are functions

18:21 ossareh: you're right. I meant that.

18:25 though that is a hard distinction to keep in mind given nearly everything refers to the functions on defrecords as methods. case in point (doc defrecord):

18:25 ,(doc defrecord)

18:25 clojurebot: "([name [& fields] & opts+specs]); Alpha - subject to change (defrecord name [fields*] options* specs*) Currently there are no options. Each spec consists of a protocol or interface name followed by ...

18:41 birdspider: i have a defprotocol and a call to reify which works as expected in repl, given I want to pass the reify generated object pack to java, what should I do in gen-class:methods ?

18:47 qed: whoa. the little schemer book /is/ awesome. i had no idea about the format.

18:50 replaca: Does anyone know if there's a maven command that takes a package name and version number and gives me a jar?

18:51 Munksgaard: qed, cool, i've considered buying it! What's it like?

18:52 qed: Munksgaard: There are two columns on every page. The column on the left asks a question like: What is (car (car l)) where l is (((hotdogs)) (and) (pickle) relish)

18:53 The column on the right says: (hotdogs)

18:53 the preceding question was: the same except it was (car l) instead of (car (car l)), the right column explains: ((hotdogs)), because (car l) is another way to ask for "the car of the list l."

18:54 What is (cdr l) where l is ()? Right column: No answer.(1) You cannot ask for the cdr of the null list. footnotes: 1. (L: nil)

18:55 and so on and so forth, slowly building you up from these basic components to the bigger ideas

18:56 it's a really cogent way of explaining the process that a lisp programmer takes in everyday programming -- start with these basic things and combine them, evolve them, etc.

18:57 brehaut: munksgaard: it will take someone from no lisp understanding right through to the Y combinator and bit further

18:57 Munksgaard: sounds great! maybe i can find it on offer somewhere

18:57 qed: brehaut: yeah I'm glancing at the back of the book -- this is pretty amazing.

18:57 * Munksgaard goes looking

18:57 brehaut: qed yeah i really like it

18:58 qed: you could literally read this in an afternoon

18:59 i wonder -- has anyone "ported" this book to clojure? that could be fun.

18:59 aww, yes, several people have in fact.

18:59 * qed doesn't peek and gets to work

19:00 Munksgaard: just searching for the little schemer on google, and the little lisper pops up too, looks like an older version (obviously using a different language too), is that correct?

19:00 qed: so... reading list for the next few months: land of lisp, the little schemer, lisp in small pieces, and create your own freaking awesome programming language

19:01 brehaut: Munksgaard: i think so yeah.

19:01 Munksgaard: theres an equivalent book for smalltalk somewhere too

19:01 Munksgaard: 'A Quick Trip to ObjectLand' i think

19:01 qed: hm -- i didnt even think to google for the little lisper -- i guess i just assumed scheme and lisp were close enough and looking into scheme could be interesting

19:02 now im wondering if i made the right choice

19:02 brehaut: qed the schemer version is the more famous i think

19:02 qed: everyone recommended the little schemer to me

19:02 brehaut: any particular reason why?

19:03 brehaut: qed: i tihnk be because scheme is a 'cleaner' (not trying to start a war!) lisp, the book is able to teach ideas without some of the language getting in the way that might exist for say CL

19:03 Munksgaard: makes sense

19:03 brehaut: it really is a book a bout thinking computationally rather than just a 'learn lisp' book

19:03 qed: i dont know enough scheme to agree with that, nor enough CL

19:04 brehaut: now that makes more sense

19:04 brehaut: the TL;DR; history is CL is the Big, kitchen sink lisp designed by a committee of Lisp venders, and scheme is the tiny elegant science experiment devised by Steele

19:05 but i think that does a disservice to both

19:05 Munksgaard: please do elaborate

19:06 :-)

19:06 brehaut: well, you will want to read http://www.paulgraham.com/thist.html

19:06 its related

19:07 Munksgaard: another side added to my loooong reading-list

19:07 anyone acquainted with The Seasoned Schemer, supposedly a sequel to the little schemer?

19:07 Chousuke: CL was cobbled together from existing Lisps, Scheme was built from the ground up. :P

19:09 brehaut: Chousuke: hah :)

19:10 qed: Munksgaard: there's the reasoned schemer, the seasoned schemer, and the little schemer

19:11 im not quite sure on the order you're supposed to read them. being reasoned vs being seasoned, seasoned seems more senior-ish but i'm not entirely confident

19:11 brehaut: i think seasoned is the followup to little

19:11 reasoned is sort of an aside. dnolen could tell you; hes ported the miniKanren library from the reasoned schemer to clj recently

19:12 birdspider: any idea what could possibly induce such line number behaviour ? http://pastebin.com/ndkaGmPv

19:13 brehaut: miniKanren in clj: https://github.com/swannodette/logos

19:27 octe: % ()

19:28 ,()

19:28 clojurebot: ()

19:28 octe: ,(map (fn [x] x) '("a" "b"))

19:28 clojurebot: ("a" "b")

19:28 octe: ,(defn read-level [fn] (map (fn [x] x) (streams/read-lines fn)))

19:28 clojurebot: DENIED

19:29 octe: ,(defn read-level [fn] (map (fn [x] x) '("a" "b")))

19:29 clojurebot: DENIED

19:29 octe: hmm

19:29 (defn read-level [fn]

19:29 (map (fn [x] x)

19:29 (streams/read-lines fn)))

19:30 gives me Unable to resolve symbol: x in this context

19:30 strange

19:30 hiredman: octe: no it doesn't

19:30 brehaut: octe, identity will save you two chars on those maps ;)

19:31 octe: well i was reducing it since i got that error

19:31 there's more done in the fn

19:31 hiredman: right, and the fn you pasted could not ever get you that error

19:31 so you reduced it wrong

19:31 octe: strange, maybe some slime / swank issue then

19:32 hiredman: I doubt it

19:35 clizzin: I have a macro looks something like this (defmacro foo [strs] `(hash-map :bar ~(str/join \, strs))). However, if I pass in a symbol for strs, i.e. i pass in x, when previous i had (def x ["a" "b" "c"]), this expands to (hash-map :bar "x") instead of (hash-map :bar "a,b,c"). How can I further unquote x so that I get the result I want?

19:36 sorry if that's not very readable, let me know if i can make it easier to read

19:37 macro that looks something like this: *

19:42 Chousuke: clizzin: you can't, really.

19:42 or shouldn't, because it's really hacky.

19:43 any solution will only work for def'd global values.

19:44 clizzin: basically you'd have to do in your macro (eval strs) to get the value of x instead of the symbol, and that only works if x is a global.

19:46 clizzin: Chousuke: would i be able to bind ~x to an autogenerated symbol and then eval that symbol?

19:46 Chousuke: You might be able to use the implicit &env parameter that is passed to macros but that too feels pretty hackish

19:46 clizzin: there's no ~x at macroexpansion time. (there's just the strs parameter)

19:47 clizzin: whoops, sorry, i meant ~strs

19:47 Chousuke: what would that help?

19:47 you would have to generate code that evals something, which is almost never what you want to do

19:49 in this particular case, why are you even using a macro though?

19:49 that looks like something a regular function can do just fine

19:49 jjido: what is the equivalent of indexOf in Clojure?

19:50 Chousuke: for Strings?

19:50 jjido: yes

19:50 Chousuke: I guess that would be .indexOf :P

19:50 jjido: :(

19:50 clizzin: Chousuke: the macro actually defines a variable, and the name of that variable is an argument to the macro. the version i put before was simplified.

19:50 Chousuke: since Clojure Strings are Java Strings

19:51 jjido: Chousuke: but Java methods are not first class

19:51 Chousuke: jjido: wrap them in a function

19:51 clizzin: Chousuke: the actual macro looks something like (defmacro foo [var files] `(def ~var {"key1" "value1" "key2" ~(str/join \, files)}))

19:51 Chousuke: clizzin: right.

19:52 clizzin: you cal always generate code that does `(def ~var {key val key2 (str/join \, ~files)})

19:53 clizzin: ie. doesn't actually do the joining at macroexpansion time.

19:53 pdk`: (doc some)

19:53 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

19:53 pdk`: (doc all)

19:53 clojurebot: Gabh mo leithscéal?

19:53 pdk`: (doc none)

19:53 clojurebot: No entiendo

19:54 clizzin: Chousuke: that was my initial thought, but the str/join part becomes (join \, [file1 file2]), and that requires that 'join' exists in any namespace that i call the macro from

19:55 Chousuke: clizzin: well, yeah

19:55 clizzin: Chousuke: and it seems silly to write something that requires a use/require in the calling namespace. shouldn't it be more self-contained?

19:55 Chousuke: or actually it requires that the namespace is require'd

19:56 hm

19:56 clizzin: well you have two choices really

19:56 clizzin: make it work with literals only, or make it require str/join

19:56 at runtime

19:57 any other solution will most likely be really hacky and brittle :P

19:57 clizzin: Chousuke: what is the danger of eval in a case like this?

19:57 it seems to be the most straightforward solution on face

19:58 Chousuke: well if you do (let [x ["some" "stuff"]] (foo varname x)) it won't work

19:59 and even though you can inspect the local environment from a macro and theoretically make that case work, then you need to deal with (let [x [some variables]] (foo varname x))

19:59 it's a lot of work and prone to breakage.

20:00 clizzin: hmm okay

20:01 Chousuke: in fact, dealing with (let [x [(some-function blah) ...]] (foo varname x)) is probably nigh impossible :P

20:01 you'd have to do code walking

20:02 and that's never a good sign

20:02 clizzin: i see. unfortunate. what is the danger of designing macros such that macros take on the same bindings as the call?

20:07 Chousuke: clizzin: same bindings?

20:10 clizzin: Chousuke: hmm that may not actually make sense now that i think about it. let me mull it over, and i'll come back if i can't see an issue with it. thanks for your help!

20:10 Chousuke: clizzin: your problem here is that you want your macro to generate different code depending on the runtime value of x, instead of the symbol x

20:11 clizzin: in other words, the parameter to the macro can only be the symbol x, not what the symbol x represents at runtime.

20:11 clizzin: Chousuke: right, i think this is what i was starting to realise...that the idea of bindings from the call don't make sense in a macro.

20:16 jjido: what does (or) expand into?

20:17 tomoj: $(macroexpand-1 '(or x y))

20:17 ,(macroexpand-1 '(or x y))

20:17 clojurebot: (clojure.core/let [or__3470__auto__ x] (if or__3470__auto__ or__3470__auto__ (clojure.core/or y)))

20:19 jjido: tomoj: thanks. I can't make sense of it

20:20 tomoj: (or x y) = (let [foo x] (if foo foo y))

20:20 jjido: ok

20:21 tomoj: (or x y z) = (let [foo x] (if foo foo (let [bar y] (if bar bar z))))

20:22 jjido: I see.

21:51 brehaut: why does clojure.xml/emit and family use println for the xml text rather than returning it ?

21:54 _ato: so that it doesn't have to keep the entire XML output in memory

21:55 wrap it in (with-out-str ...) if you need a string of it

21:55 brehaut: oh right. cheers

22:10 gertalot: I'm trying to apply a function to every value of a map, and return a map. Is there an easier way than doing this?

22:10 brehaut: (into {} (map (fn [[k v] (fun k v)) source-map)

22:10 )

22:10 i think

22:11 gertalot: ,(apply hash-map (flatten (map (fn [kv] [(key kv) (* 2 (val kv))]) {:a 1 :b 2})))

22:11 clojurebot: {:a 2, :b 4}

22:11 gertalot: into? cool

22:11 brehaut: into is great

22:11 general purpose pouring stuff into collection fun

22:11 _ato: another variant: (zipmap (keys m) (map f (vals map)))

22:11 gertalot: see, everytime I dream up something convoluted and difficult it turns out there's already a function for it

22:11 ahh

22:12 didn't think of that

22:12 awesome

22:12 brehaut: _ato wins

22:12 gertalot: i agree.

22:12 thanks everyone!

22:12 * gertalot goes back to drawing board

22:13 _ato: there's also clojure.contrib.generic.function/fmap but that means pulling in a library ;-)

22:13 clojure.contrib.generic.functor/fmap, I mean

22:13 http://clojure.github.com/clojure-contrib/generic.functor-api.html

22:14 ,fmap

22:14 clojurebot: java.lang.Exception: Unable to resolve symbol: fmap in this context

22:14 _ato: ,(use 'clojure.contrib.generic.functor)

22:14 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/generic/functor__init.class or clojure/contrib/generic/functor.clj on classpath:

22:14 _ato: mm, thought so

22:21 brehaut: im having a documentation fail regarding defrecords. how does clojure define accessors for the fields?

22:28 _ato: brehaut: not sure I understand your question. You can access fields with (:field some-record)

22:28 brehaut: ah right :)

22:28 cheers :)

22:28 tomoj: in protocol method definitions, just pretend the field list is like defn's

22:28 you can use those symbols to refer to the fields

22:29 for self-access

22:29 Intertricity: Can anyone suggest a book for a programmer with no experience in java, just C and Python?

22:29 KirinDave: Intertricity: Yes.

22:29 Intertricity: SICP.

22:29 Intertricity: I was hoping for a clojure book >.>

22:29 KirinDave: Intertricity: But for Clojure? :D

22:29 Intertricity: Yes :P

22:30 KirinDave: Intertricity: The book I am working on is for people who know either Java or Ruby/Python. But it's months from being even in beta.

22:30 Intertricity: aw ntus

22:30 *nuts

22:30 brehaut: Intertricity: joy of clojure?

22:31 Intertricity: brehaut, I can look that one up, thanks :)

22:32 brehaut: Intertricity: its in beta/MEAP ATM

22:32 Intertricity: What's meap?

22:32 brehaut: im from a python/javascript background and ive enjoyed it thus far

22:32 meap is manning (the publishers) pdf beta program

22:35 tomoj: you will probably want to learn how to read javadocs someday :(

22:35 KirinDave: brehaut: I love JoC, but I felt like it wants more java proficiency.

22:35 Intertricity: Ooh I see

22:36 I'm learning clojure to use it on the CLR

22:36 tomoj: oh

22:36 then..

22:36 Intertricity: after seeing the first bits of clojureclr showing up in binary

22:36 tomoj: you will not need to read javadocs

22:36 Intertricity: heh :P

22:36 tomoj: doesn't such a clojurist need to write most everything from scratch?

22:37 how much of contrib has been ported, I wonder?

22:37 brehaut: KirinDave: maybe? I learnt and used java in 2001-2003 and havent used it since and havent found that to be an impediment for JoC 

22:37 Intertricity: there's a .Net library I plan to use

22:37 KirinDave: .net?

22:37 Intertricity: yeah, clojureclr gives access to .net

22:38 tomoj: huh

22:38 could use that for f# interop I suppose?

22:39 brehaut: tomoj, presumably you would just expose your F# with classes and consume them from clojureclr just like you consume them from C#?

22:39 tomoj: I guess, I don't know f#

22:39 brehaut: ive only dabbled

22:40 tomoj: looks like even lamina won't work :(

Logging service provided by n01se.net