#clojure log - Nov 13 2010

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

0:44 kumarshantanu1: hi, is it possible to attach documentation to an anonymous function?

0:44 hiredman: no

0:44 but you could never look up the docs, so who cares

0:45 kumarshantanu1: I want to be able to...in an internal system

0:45 anonymous predicate function, that could tell why a boolean test failed -- from the doc

0:45 hiredman: uh

0:45 kumarshantanu1: well anyway, since it is not possible...

0:46 hiredman: but you would never be able to get the doc

0:46 kumarshantanu1: hmm

0:46 hiredman: the question is almost nonsensical

0:47 docstrings are metadata on vars, anonymous functions are not held in vars, qed

0:48 kumarshantanu1: right

1:16 gstamp: What does fn* do?

1:20 tonyl: it is an internal implementation of fn

1:21 whenever you see that just think it is fn, they are mostly used to bootstrap basic functionality for clojure i think

1:29 Derander: What is that mouse chording text editor called?

1:30 acme

2:08 sandGorgon: is anyone aware of any clojure wrappers for lucene ?

2:25 sivajag: sandGorgon: i am not aware of one

2:25 but thinking of writing

2:26 u wanna join and do it?

2:36 sandGorgon: sivajag, sure... I actually took a look at the mailindex and clucy projects on github and am cranking out something. I want to index a load of XML files

4:13 kjeldahl: How do I make and use a symbol with an embedded space in it?

4:14 Raynes: &(symbol "blah blah")

4:14 sexpbot: ⟹ blah blah

4:14 Raynes: As for using it...

4:15 kjeldahl: .. Incanter creates such headers by default when using read-data... :-)

4:16 Eh, I think I might meant keyword...

4:16 :quotedate with a space in it.

4:20 amalloy: &(keyword "1 2")

4:20 sexpbot: ⟹ :1 2

4:29 kjeldahl: Ok thanks. For some reason (keyword "price"), (keyword "paper") etc works fine, but not (keyword "quote date") using Incanter. I'll keep digging.

4:30 Raynes: Why would you need spaces in keywords?

4:30 I mean, do you have a specific reason?

4:59 kjeldahl: Raynes: Yes, the read-dataset method in Incanter uses keywords for column headers by default.

5:23 _ulises: morning all

5:57 has anybody used suart sierra's clojure-hadoop lib in production?

5:57 (sorry if this is a silly question)

5:57 alternatively, do you know of any "good" way of interfacing clojure w/hadoop?

5:58 I'm basically doing an investigation to see which are the available options and which ones are the best ones out there

5:58 (I've done my share of googling, of course)

6:14 sandGorgon: _ulises, cascalog ?

6:15 _ulises: only read about it, how is it different from cascading for instance?

6:16 sandGorgon: _ulises, it IS cascading - just wrapped in clojurey way. I believe it is also being used in production in a couple of places, notably flightcaster

6:16 _ulises: oh! :D

6:17 interesting, I assume this is even a higher level of abstraction from stuart sierra's clojure-hadoop?

6:20 sandGorgon: I'm not sure - if I had an opinion about it, i would say they are the same level of abstraction .. done differently. But dont take my word for it

6:20 esj: _ulises: Nathan has a good presentantation on cascalog somewhere... lemme go find it.

6:20 _ulises: hum, I just read a bit more about cascalog and it seems like it is a language for querying large data

6:20 I think that I am more interested in running my own map/reduce jobs so perhaps I need something more low level?

6:22 esj: _ulises: perhaps this: https://github.com/clj-sys/cascading-clojure

6:23 did sandGorgon mention it, I've just joined the room, and it looks like he might have ?

6:24 sandGorgon: esj, well i mentioned cascalog

6:24 _ulises: interesting

6:24 this looks good, thank you chaps

6:54 mobile: ,(reduce inc (range 5))

6:54 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (2) passed to: core$inc

6:57 Raynes: &(map inc (range 5))

6:57 sexpbot: ⟹ (1 2 3 4 5)

6:58 mobile: (loop [n 20] (recur (n-1))

6:58 whops

6:59 help me out raynes :) im on the ipad :)

6:59 Raynes: What do you need help with?

6:59 mobile: apparently it does work for irc

6:59 i forgot the comma

7:00 Raynes: &(loop [n 20] (recur (n-1))

7:00 sexpbot: java.lang.Exception: EOF while reading

7:00 Raynes: &(loop [n 20] (recur (n-1)))

7:00 sexpbot: java.lang.Exception: Unable to resolve symbol: n-1 in this context

7:01 mobile: (dec n)

7:01 sexpbot: ⟹ -1

7:01 mobile: (inc 1)

7:01 sexpbot: ⟹ 1

7:01 mobile: is that the karma guess.

7:01 Raynes: Yep.

7:03 mobile: is it supposed to be squares, or is that a missing character

7:30 _ulises: hum, where am I going wrong when I (require [clojure.contrib.json :as json]) ?

7:30 ok, nm

7:40 bartj: is there a way to lazily generate a sorted set ?

7:41 is it? (lazy-seq (into #{} [1 2 3 4 5 6 7 8]))

7:43 cemerick: bartj: no, into is eager

7:43 sets are by definition not lazy

7:44 Raynes: Eager to please!

7:44 bartj: hmm

7:46 lists are eager too!

7:47 cemerick: of course

7:47 if they weren't eager, then lists would be lazy seqs :-)

8:04 bartj: cemerick, the only way seems to be to use lazy seq

8:04 cemerick: bartj: the only way to do what?

8:05 bartj: to generate a lazy sequence of unique elements of a list

8:06 raek: ,(doc distinct)

8:06 clojurebot: "([coll]); Returns a lazy sequence of the elements of coll with duplicates removed"

8:07 raek: yes, lazy seq are the only things that are lazy

8:28 bartj: raek, thank you; is there anyway I can know a datastructure is lazy

8:29 raek, like lazy-seq? as we have seq?

8:50 fliebel: hrm, I just had Clojure read lines from a stream, and now I killed it and lost my history. Sad story :(

9:59 How can I do something after the return value of a function without that thing becoming the return value?

10:01 chouser: let

10:01 Raynes: You don't.

10:01 Why would you need to?

10:01 chouser: (let [x (rtn-value)] (something) x)

10:02 fliebel: I need to close an URLConnection, but that involves getting the stream first.

10:02 So simply using with-open wouldn't work.

10:02 Raynes: fliebel: let would probably work in that case.

10:03 fliebel: Thanks, I will try some of that magic, but it felt a little ugly, so I thought I might ask before making something evil.

10:04 I'm trying to do this: http://philippeadjiman.com/blog/2009/09/07/the-trick-to-write-a-fast-universal-java-url-expander/

10:06 Raynes: chouser: I've noticed you becoming more familiar with your & key lately. My heart pounds with glee each time.

10:10 I'm considering setting it up so sexpbot emails me every time chouser finds his fingers closer to & than ,. I could claim that it's just usage statistics.

10:16 fliebel: What does it mean when I get a java.io.FileNotFoundException for an url? Something like 404?

10:59 &(count (distinct (repeatedly 100 #(rand-int 100)))) ; can someone who knows his math tell me why this seems to average to somewhere near 63?

10:59 sexpbot: ⟹ 62

11:14 esj: fliebel: this is the Bithday Paradox: http://en.wikipedia.org/wiki/Birthday_problem

11:15 if you were to replace 100 with 365, and then instead of asking what is the probability of there being at least one shared birthday, asking what is the expected number of shared birthdays

11:16 fliebel: esj: Awesome :)

11:27 esj: fliebel: so, if you have N numbers, each drawn uniformly from [1,N], then the probability of there being n repeated numbers looks something like (N!/n!)(N-n)n/N^2, if I got my combinatorics straight (which is highly unlikely). Then to answer your particular question (which n is the most likely) you need to find the n that maximises this. I've forgotten how to do d/dn of a factorial, but you could plot the graph and see where

11:27 tops out.

11:28 fliebel: ouch...

11:32 esj: you asked !

11:32 pauldoo: wolfram alpha will be your friend for that kind of thing

11:33 fliebel: Yea, I did :) Thanks! Now I have some reading to do...

11:33 pauldoo: the continuous version of factorial is the gamma function, so that'll help if you do decide to try and do derivatives

11:51 jarpiain: &(/ (- 1 (/ (count (distinct (repeatedly 10000 #(rand-int 10000))) 10000.0)))

11:51 sexpbot: java.lang.Exception: EOF while reading

11:52 jarpiain: &(/ (- 1 (/ (count (distinct (repeatedly 10000 #(rand-int 10000)))) 10000.0)))

11:52 sexpbot: ⟹ 2.7601435274634283

11:52 jarpiain: that should approach e

11:52 kumarshantanu: jarpiain: what is '&' for?

11:53 fliebel: kumarshantanu: sexpbot

11:53 kumarshantanu: it evals all clojure prefixed with &

11:53 esj: jarpiain: pretty close !

11:54 fliebel: $google e

11:54 sexpbot: First out of 228000000 results is: E! Online - Entertainment News, Celebrity Gossip, Celebrity News

11:54 http://www.eonline.com/

11:55 raek: ,Math/E

11:55 clojurebot: 2.718281828459045

11:56 slyrus: technomancy: should "lein swank" work without a project?

11:56 fliebel: So, from this we can draw the conclusion that Java is better than Google, but Google is better than Clojure :)

11:58 kumarshantanu: fliebel: transitively, Java is better than Clojure? (Holy Cow!!) ;-)

12:00 fliebel: No, because universe is bent in such a way that Clojure is actually better than both if you look at it from certain angles.

12:00 jarpiain: &(reduce + (for [x (range 20)] (/ (reduce * 1.0 (range 1 (inc x))))))

12:00 sexpbot: ⟹ 2.7182818284590455

12:01 raek: bartj: (sorry for not responding earlier) no, there is no such function

12:02 bartj: raek, that is really ok...thanks again

12:09 pauldoo: do delays release the closure once they have been forced? (I'm interested if values in the expression now become eligeable for GC)

12:14 bmh: any vimclojure users about? I'm having a frustrating time with syntax highlighting

12:14 opqdonut: pauldoo: i see no reason why not

12:14 but I'm not completely sure

12:17 bartj: bmh, what is your question...not sure if I would be able to help, though

12:18 bmh: bartj: Highlighting is too eager. If I have a function called empty-vertex-list, empty and list get highlighted because the syntax file thinks that they're builtins

12:20 bartj: bmh, doesn't highlight for me

12:20 bmh: bartj: hurumph. Something must be broken in my vimrc then. Thanks.

12:32 LOPP: weird

12:32 1 million times: (conj [1 2 3] 4) = 107 msecs

12:32 (conj '[1 2 3] 4) = 75 msecs

12:33 why

12:34 and (conj '(1 2 3) 4) = 27 msecs

12:34 and here I thought vectors were faster than lists

12:34 opqdonut: conjing to the list is lazy

12:34 LOPP: in what sense?

12:34 opqdonut: vectors are faster than lists for random access

12:35 LOPP: that much is obvious

12:35 opqdonut: lazy in the sense that it only allocates a closure

12:35 LOPP: ok

12:35 but why is quoted vector conj faster

12:35 opqdonut: whereas conjing to a vector pretty much allocates a new vector

12:35 LOPP: than without conj

12:35 opqdonut: since they are persistent

12:35 i have no idea about the quote

12:36 what does the benchmark code look like exactly? (dotimes [i 100000] (conj [1 2 3] 4))?

12:36 LOPP: yes

12:36 opqdonut: maybe with quote the vector is only created once

12:36 LOPP: here's what I have now

12:37 (time (dotimes [n 1000000] (first (conj [1 2 3] 4))))

12:37 to force evaluation

12:37 hiredman: conj is not lazy

12:37 opqdonut: even for lists?

12:37 LOPP: and now I have 117 for list, 209 for quoted vector and 243 for vector

12:37 so no change even if list was lazy

12:38 seems to me lists are just faster than vectors in clojure, except for random access

12:39 hiredman: opqdonut: even for lists

12:39 LOPP: the main reason I use vectors is because I can't add at the end of list

12:39 hiredman: lists are a much simpler datastructure

12:39 why is it surprising that they would be faster?

12:39 LOPP: because they are not in java

12:40 ArrayList is much much much faster than LinkedList

12:40 even for inserting at the start, until you have 500000+ elements, arraylist outperforms linkedlist

12:41 that came as a surprise to me, since inserting at start is O(1) for linked list and O(n) for array list

12:42 opqdonut: that is surprising

12:43 LOPP: seems that using arrays + System.arraycopy is lightning fast

12:43 linked list requires alocating a new node, which slows it down tremendously

12:44 samx: it's also not true

12:44 LOPP: really?

12:49 I got my data from some detailed benchmarks some guy did

12:49 might have been faulty though

12:50 opqdonut: if there's something I've learnt from twiddling with different languages, it's that allocation should be cheap

12:50 LOPP: sure

12:50 opqdonut: the jvm is a PITA in this respect

12:50 LOPP: but spawning tons of objects is bound to trigger more GC cycles

12:51 noticed when testing clojure performance that results of consequtive runs would vary a lot

12:51 probably because of GC

12:51 GC doesn't only free up memory it also compacts memory

12:51 which isn't that cheap

12:52 KirinDave: Well, hopefully ojdk will start pursing more modern gc strategies.

12:54 LOPP: well that's a riot

12:54 :P

12:55 haven't seen any strong improvements in java, just piling up new libs into JRE

12:55 last big thing was (poorly) implemented templates

13:00 huh.... found a guy claiming that hashset is faster than list

13:03 samx: well, there's lies, there's bigger lies, and then there's performance metrics

13:04 LOPP: to be honest I'd use sequences/lists all the time if I didn't need adding at the end so damn often

13:05 gimme a list with pointer to the end and ability to add there and it's golden

13:09 jarpiain: &(let [que (repeatedly promise)] (dorun (map (fn [x q] (deliver (first q) x)) (range 10) (iterate next que))) (map deref (take 5 que)))

13:09 sexpbot: ⟹ (0 1 2 3 4)

13:21 LOPP: is (iterate next que) needed? doesn't the map already iterate through a coll?

13:22 jarpiain: hmm, right

13:25 raek: jarpiain: looks similar to something I saw on cgrand's blog

13:26 http://clj-me.cgrand.net/2009/11/18/are-pipe-dreams-made-of-promises/

13:49 amalloy: LOPP: well, with functional/immutable lists it's not really practical to add to the end

13:49 but have you checked out chouser's finger trees?

13:58 fliebel: This is weird. I'm profiling a Clojure script that is running at 1% CPU and presumably spends most of its time doing IO, but VisualVM tells me it's spending most of its time in hashmap functions like assoc.

13:59 amalloy: fliebel: allocation counts as io, doesn't it?

14:00 fliebel: amalloy: I don't know, but I'm fetching urls. ;)

14:01 So I was expecting to see all sorts of java.io and java.net functions, but I see none of them.

14:07 I thought there was a function in core to reverse keys and values? Or a function to sort a map by values? I found snippets for both, but I'm sure they're at least in contrib somewhere...

14:09 raek: fliebel: the first one is in clojure.set: http://clojuredocs.org/clojure_core/clojure.set/map-invert

14:09 fliebel: thanks :) the other is only doable by sorted-map-by, I believe?

14:10 raek: regarding the second one, would it do the same thing as (sort-by val m)?

14:10 what kind of data structure would you want from the second function?

14:11 fliebel: raek: except that it doesn;t return a map. But the other day someone said array maps guarantee order? so i can just do an into?

14:12 raek: well, I have understood things correctly, array map is an optimized implementation for hash map for small number of entries

14:12 I don't know if you can assume things about it

14:12 if you conj enough elements into it, the result will be a hash map

14:12 and the ordering will vanish

14:13 fliebel: really?

14:13 raek: (class {:a 1})

14:13 ,(class {:a 1})

14:13 clojurebot: clojure.lang.PersistentArrayMap

14:13 raek: ,(class (into {} [[:a 1]]))

14:13 clojurebot: clojure.lang.PersistentArrayMap

14:14 raek: ,(class (into {} (for [i (range 100)] [i i])))

14:14 clojurebot: clojure.lang.PersistentHashMap

14:14 raek: seems so :)

14:14 fliebel: wowzers...

14:14 raek: if you want an ordered map, perhaps sorted-map-by is the best solution

14:15 how will you use the map, btw?

14:17 fliebel: raek: Not all that mappish, so I think sorted is fine for now.

14:19 raek: but sort takes a comparator, not a predicate, so just val will not work.

14:20 raek: hrm, I think you could do something like #(< (val %1) (val %2))

14:21 there was something about functions and Comparator, anyway

14:31 amalloy: raek: #(max-key val %1 %2)

14:40 LOPP: amalloy why isn;'t it practical to add at end of immutable lists

14:41 amalloy: because your pointer is to the front of the list. you can't change the list it's pointing to, so you have to create a new list for it to point to. the same logic holds for every node but the last, so you end up copying the whole list

14:42 hircus: LOPP: you can use a vector instead; a Clojure vector is designed to grow at the end

14:42 ,(conj '(1 2 3) 'x)

14:43 clojurebot: (x 1 2 3)

14:43 hircus: ,(conj [1 2 3] 'x)

14:43 clojurebot: [1 2 3 x]

14:50 LOPP: amalloy you can say that for every Object, the reference points to the start of it

14:50 the list object could easily have 2 references

14:50 one to the head and one to the tail

14:50 amalloy: LOPP: yes. but you would have to modify the head element so that if you follow enough next pointers you get to the tail

14:51 LOPP: isn't that what happens now?

14:51 if you take next enough times you get to the end of the list...

14:52 amalloy: LOPP: yes. but if you add something to the end without updating the head pointer that won't be true anymore

14:52 LOPP: I don't understand

14:54 amalloy: &(let [x '(1 2)] (identical? x (drop 1 (cons 0 x)))

14:54 sexpbot: java.lang.Exception: EOF while reading

14:54 amalloy: &(let [x '(1 2)] (identical? x (drop 1 (cons 0 x))))

14:54 sexpbot: ⟹ false

14:55 amalloy: well, that's probably a terrible example

14:55 raek: the last cons cell of (1 2 3) has nil as its rest

14:55 LOPP: so what you are trying to say is that it's because you get a new list instance

14:56 raek: if you want to make the list (1 2 3 4), that cell's rest would have to change into the cell containing 3

14:56 but lists are immutable, so you aren't allowed to change it

14:56 *containing 4

14:56 LOPP: I'll take your word that it isn't possible because of the way persistency is achieved on lists

14:57 andreasmk2: hello guys, is there a way to use clojure as a scripting language inside my java program? currently what I see is that clojure can call java methods but not the opposite.

14:57 LOPP: you can call clojure from java just fine

14:58 andreasmk2: i mean calling clojure functions and passing arguments. do you have any urls for tutorials or documents ?

14:59 LOPP: I think you instantiate the Reader object and evaluate with that

14:59 other people here probably know the details

15:00 raek: andreasmk2: http://en.wikibooks.org/wiki/Clojure_Programming/Tutorials_and_Tips#Invoking_Clojure_from_Java

15:00 you can also fetch the var object with clojure.lang.RT

15:00 and then use its invoke method

15:01 andreasmk2: raek, this is what i need. thank you raek :)

15:05 tonyl: hello

15:09 LOPP: is it possible to return an infinite sequence of prime numbers?

15:09 using Euler's Sieve for instance(http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)

15:09 amalloy: LOPP: i think clojure.contrib.lazy-seq has a primes function

15:09 tonyl: i think there is something in contrib for primes

15:10 dnolen: LOPP: http://clj-me.cgrand.net/index.php?s=Everybody%20loves%20the%20Sieve%20of%20Eratosthenes

15:11 LOPP: infinite lazy version at the bottom.

15:12 LOPP: I wish I was as smart as cgrand :P

15:14 hm enqueue?

15:14 ,(doc enqueue)

15:14 clojurebot: It's greek to me.

15:15 LOPP: oh right, he declared it

15:18 dnolen: LOPP: I feel the same way, cgrand is a Clojure zen master

15:42 LauJensen: Gents. Everybody looked at the new design for ClojureQL? Certain functions (disj!,conj!,take,sort) shadow core names, so either use (:use [clojureql :as cql]) or accept that there are shadow warnings when importing. Can I get some oppinions on wether we should rename these functions, or if these warnings are acceptable? (I say the warnings, because the functions can be made to behave the exact same was as those in core)

15:48 morphling: LauJensen: I'd prefer renamed functions

15:51 LauJensen: vote registered

15:55 fliebel: LauJensen: I'd prefer familiar names, with sum multimagic to make it work as expected.

15:55 *some

15:55 LauJensen: yea me too, so its 2 vs 3 votes so far

15:56 fliebel: I think it might help to make it clear you can do the refer-clojure thing, to get rid of the warnings.

15:56 I didn't know about that until recently.

15:57 LauJensen: Which of the 2 are the pro-shadow?

15:57 LauJensen: either refer/exclude or use/as

15:57 fliebel: You and me, want conj/disj/sort/take etc, and ninjudd, pholdings nad morphling want insert-into, delete-from, sort-by, limit etc

15:58 fliebel: LauJensen: Is there some sort of setup fn involved which could automate the referring? (might be a bad idea nyway, just saying)

15:59 LauJensen: No, the automated solution is simply accepting the warnings when you import the lib

15:59 fliebel: right :)

16:08 pauldoo: can I make mutually recursive functions using two defn statements? (I don't care about tail call optimization)

16:09 I seem to run into an order of declaration type of problem.. ie the first defn body doesn't know about the not-yet-defined function

16:09 fliebel: pauldoo: oh, I'm to slow, I know this...

16:09 LauJensen: pauldoo: You can, but might run into stackoverflow problems. Use (declare y) to announce the 2nd function before defning the first

16:09 pauldoo: brilliant!,, declare it is :)

16:10 fliebel: Right, declare… I need to implement those fast hash lookups in my mind, and then touch typing.

16:10 Can I get to the queue of an agent? I'm doing send-off to an agent, and I want to see if it can keep up with the flow or builds up a backlog.

16:11 pauldoo: can I declare a multimethod too? or does declare only work for defn and def?

16:11 amalloy: pauldoo: another option is letfn, though i use declare myself

16:11 pauldoo: letfn is local though right... like let..

16:11 amalloy: pauldoo: you can declare any var

16:11 pauldoo: hehe, so are multimethods vars?

16:12 fliebel: pauldoo: No but you keep them in vars, right?

16:12 amalloy: pauldoo: no, but neither are functions. the names you def them with are vars

16:12 pauldoo: right ok.. :)

16:13 I'm new to clojure, I only create multimethods using defmulti

16:13 haven't encountered creating multimethod values (without defmulti)

16:14 hircus: pauldoo: think of generic functions as abstract method on steroid

16:14 fliebel: Coming to think of it, there isn't just multi, is there? or let-multi ;)

16:14 pauldoo: fliebel: that'll be why I haven't encountered them perhaps..

16:15 amalloy: pauldoo: i've never tried it either, and it might not be possible, but it doesn't matter. just about every def wraps a var around a value

16:15 pauldoo: amalloy: yes, indeed

16:15 hircus: amalloy: what you're calling "var" is probably what we call an identifier. "var" in clojure is something specific

16:15 amalloy: there is a function that gets all the multifn objects associated with a defmulti

16:15 hircus: i'm well aware. i'm talking about vars

16:15 &(class #'first)

16:15 sexpbot: ⟹ clojure.lang.Var

16:16 hircus: ah, yes

16:17 tonyl: what is the difference between a var and a symbol?

16:17 amalloy: tonyl: vars are a ref type

16:17 tonyl: it might be something obvious, but I'm fairly new to lisp

16:17 hircus: tonyl: a variable is bound to some value. a symbol is just a unique identifier

16:17 amalloy: &(deref #'first)

16:17 sexpbot: ⟹ #<core$first clojure.core$first@36f7e6>

16:18 tonyl: so the var (ref) can be rebinded

16:19 but not a symbol

16:19 hiredman: a ref is not a var

16:19 by ref amalloy meant reference

16:19 not (ref ...)

16:19 tonyl: ok

16:19 amalloy: right, thanks hiredman

16:19 tonyl: not clojure's ref

16:19 thanks

16:19 hircus: a var can be rebinded with set! but that's discouraged in functional programming :)

16:20 amalloy: &(map class [#'first (ref first)])

16:20 sexpbot: ⟹ (clojure.lang.Var clojure.lang.Ref)

16:20 tonyl: what about with (binding ...)

16:20 hircus: binding shadows the values bound to the variables

16:21 tonyl: ok

16:21 hircus: say you want to replace the function "first" with one that shouts out whenever it's called

16:21 (binding [first my-tracing-first] some-exp-that-uses-first)

16:21 tonyl: so it doesn't change the values and changes them back

16:21 hircus: actually, dotrace in clojure.contrib.trace does that for you

16:21 the changes happen only in the local scope

16:22 tonyl: ok

16:22 hircus: but it does break the otherwise static scoping

16:22 one sec

16:23 so let's say I bind x to 42 -- (def x 42)

16:23 tonyl: ok

16:23 hircus: and then define a function that just returns this value. (defn foo [] x)

16:24 you'd think this always returns 42, but now (binding [x 7] (foo)) => 7

16:24 but outside the binding, (foo) => 42

16:25 tonyl: thanks for the explanation

16:26 hircus: no prob :)

17:26 Zeiris_: What does Clojure/Lisp use to organize and structure code at a high level, higher than functions?

17:26 I mean, Java uses objects. C has files/compilation units. Does Clojure also rely on files?

17:27 tonyl: you mean sequences

17:27 maybe?

17:28 or list in lisp

17:28 LauJensen: Zeiris_: primarily namespaces

17:29 gregh: java has files, too, which don't always map 1-1 with objects

17:29 and clojure stores source code in files. :)

17:29 Zeiris_: Yeah, I should've said "classes". I think those map 1-1?

17:30 gregh: you can put more than one class declaration in a java source file

17:39 dakrone: defn: ping

17:44 alpheus: Can namespaces mutually require one another?

17:55 technomancy: alpheus: there are ways to make it work, but it's almost never worth the trouble

17:57 dakrone: hey technomancy, can you delete a jar on clojars for me? I accidentaly renamed something incorrectly

17:58 technomancy: dakrone: I'll take a look. I'm not sure quite how to but I can try.

17:58 what's the name?

17:58 dakrone: technomancy: sent pm

18:02 alpheus: technomancy: thought that was the case. Thanks.

18:02 amalloy: gregh: java quite often winds up with more than one class per source file

18:04 but clojure's main organizational unit is, as mentioned earlier, the namespace. these do have a 1-1 correspondence with files in practice, though (i think? technomancy?) it's possible to break that rule

18:04 gregh: yes, particularly with inner classes

18:04 amalloy: gregh: yep, exactly

18:05 hiredman: clojure allows you group functions into protocols

18:07 slyrus: anyone know where the clojure dependency for clojure-contrib is specified?

18:07 stuartsierra: slyrus: in clojure-contrib/modules/parent/pom.xml

18:08 slyrus: ah, parent... thanks stuartsierra!

18:08 stuartsierra: welcome

18:09 slyrus: so why does current clojure-contrib get built with 1.3.0-SNAPSHOT not 1.3.0-alpha3-SNAPSHOT?

18:10 (besides the obvious answer "because that's what parent/pom.xml says!")

18:11 Or should I say: what's the rationale behind commit 6711b9e03f415d744594ce2a8faed48f9a2bc882?

18:11 not that I have a problem with it, it just seems odd to reset the dependency here when the clojure HEAD is still on 1.3.0-alpha3

18:13 stuartsierra: I think the clojure HEAD just hasn't been updated

18:13 that's probably a mistake

18:14 slyrus: ah, OK, that makes sense

18:14 it's a bummer that that commit requires so many lines!

18:15 stuartsierra: yeah, another reason for phasing out the multi-module contrib; release versions are too hard

18:16 slyrus: oh... I didn't quite get that you were phasing it out...

18:16 guess I won't spend to much time having my stuff try to deal with the multi-module version then.

18:17 stuartsierra: well, it will probably hang around for a while

18:17 but new contrib libs are getting their own repositories

18:17 slyrus: and the old ones?

18:22 stuartsierra: dunno, don't have a plan for those yet

18:23 Probably take the most popular ones and give them their own repos

18:23 leave the rest in a "legacy" repo

18:28 slyrus: okey dokey

18:28 would be nice to see it stabilize

18:32 Ok, so when I build clojure, everything looks good (the jars) and I get a pom.xml, but when I mvn install, I get empty jars in .m2/repository

18:35 stuartsierra: yeah, mvn install in Clojure doesn't work

18:35 You have to use Ant

18:36 First download maven-ant-tasks.jar

18:36 Then run ant -lib /path/to/maven-ant-tasks.jar ci-build

18:37 Or try my branch with a proper Maven build: https://github.com/stuartsierra/clojure/tree/rebuild

18:37 Actually, don't try that until we get the parent POMs into central

18:38 which we will in a few more days probably.

18:42 slyrus: what's central?

18:43 and I see your branch removes ant building support :( I was hoping that I could do ant ; mvn install and the right thing would happen. I guess not.

18:43 clojurebot: most horrible thing is http://tinyurl.com/b65o8e

18:49 stuartsierra: slyrus: I might add back a simplified build.xml

18:49 for now just working on getting the Maven build to work so we can do faster releases

18:50 "central" means Maven central, the default repository for the Maven / Ivy toolchain

18:52 Right now, to build my branch, you first need to install the parent "pom.baseline" project locally.

19:42 quizme: (interleave [:a :b] [1 2]) gets turned into lists. How do I keep them as vectors? or should I just give in and use lists instead of vectors?

19:43 and if i pass that result into partition, i get more sequences. I kinda feel like i'm fighting an uphill battle.

19:43 tonyl: with into

19:43 jk_: (vec (interleave [:a :b] [1 2])) ?

19:44 quizme: oh

19:44 lemme try that

19:45 jk_: ,(vec (interleave [:a :b] [1 2]))

19:45 clojurebot: [:a 1 :b 2]

19:45 quizme: jk_ (vec (partition 2 (vec (interleave [:a :b] [1 2]) )))

19:45 jk_: ,(vec (partition 2 (vec (interleave [:a :b] [1 2]) )))

19:45 clojurebot: [(:a 1) (:b 2)]

19:46 tonyl: you dont need the double vec

19:46 ,(vec (partition 2 (interleave [:a :b] [1 2])))

19:46 clojurebot: [(:a 1) (:b 2)]

19:46 quizme: tonyl i want (:a 1) to be [:a 1]

19:47 tonyl: oh mm..

19:47 jk_: ,(map vec (partition 2 (interleave [:a :b] [1 2])))

19:47 clojurebot: ([:a 1] [:b 2])

19:47 MayDaniel: ,(map vector [:a :b] [1 2])

19:47 clojurebot: ([:a 1] [:b 2])

19:49 quizme: (vec (map vector [:a :b] [1 2]))

19:49 i think that's what i want

19:50 but again, should i just go with the flow and use lists ?

19:51 it feels like i'm saying "really, I really want a vector, not joking.... yeah and keep that one as a vector too. Oh yeah, and that one."

19:51 jk_: do you, in fact, really want a vector? does it matter? like you want to add to it at the end efficiently or something?

19:52 quizme: jk_ that's what i'm wondering...

19:52 tonyl: they are not lists but map returns a seq, lazy seq specifically

19:53 quizme: so it seems like i should just use lists unless I want specific performance guarantees...

19:57 (clojure.test/is (= [1 2] '(1 2)))

19:57 true

19:57 that's kind of interesting

20:00 _fogus_: quizme: why?

20:01 quizme: _fogus_ cuz it's ignoring the type.

20:02 _fogus_: quizme: But it's not ignoring the equality partition.

20:02 quizme: _fogus_ and vectors aren't sequences from what i heard.

20:02 "partition" ?

20:05 _fogus_: quizme: so clojure determines equality along a number of "partitions" sequential, maps, and sets

20:06 quizme: ohh

20:06 (is (= #{1 2} [1 2 ])) ; => false

20:06 _fogus_: quizme: try it

20:07 quizme: ,(is (= #{1 2} [1 2 ]))

20:07 clojurebot: java.lang.Exception: Unable to resolve symbol: is in this context

20:07 quizme: ,(test.clojure/is (= #{1 2} [1 2 ]))

20:07 clojurebot: java.lang.ClassNotFoundException: test.clojure

20:07 tonyl: ,(= #{1 2} [1 2])

20:07 quizme: oops

20:07 clojurebot: false

20:09 _fogus_: ,(= '(1 2 3) (doto (java.util.ArrayList.) (.add 1) (.add 2) (.add 3)))

20:09 clojurebot: true

20:09 _fogus_: quizme: So you can see that other things also fall into the sequential partition

20:10 quizme: _fogus_ got it, thanks.

20:11 _fogus_ haven't read your book yet. ...

20:11 _fogus_: quizme: One final thing. Be very careful how you use predicates like seq? and sequential? as they are leaky abstractions

20:12 quizme: leaky?

20:12 _fogus_: quizme: No worries. Hopefully you will one day. We devote a lot of space to this stuff. :-)

20:13 quizme: _fogus_ it's sitting on my computer, waiting for me.

20:14 _fogus_: Well in this specific case check out section 5.1 (I think -- the title is "Persistence, Sequences, and Complexity")

21:05 amalloy: &(identical? [:a] [:a])

21:05 sexpbot: ⟹ false

21:05 tonyl: they are not the same object

21:07 &(let [a [:a] b a] (identical? a b))

21:07 sexpbot: ⟹ true

21:13 tonyl: "If init is supplied, it is evaluated, and the root binding of the var is set to the resulting value. If init is not supplied, the root binding of the var is unaffected"

21:13 what does this exactly mean in special_forms?

21:13 the evaluated value of init in the metadata is the value for the var?

21:14 amalloy: tonyl: (def x) vs (def x 1)

21:14 tonyl: oh *facepalm* i didn't see the init? in the args

21:16 I see (def x) is virtually the same as (declare x)

21:36 sproust: Having soem trouble with Leiningen tonight. The latest clojure is "1.3.0-master" isn't it?

21:40 hiredman: 1.3 has not been released

21:40 dysinger: yay

21:40 oh lol I thought you just sad HAD been released

21:40 s/sad/said

21:40 sexpbot: <dysinger> oh lol I thought you just said HAD been released

21:41 sproust: Is there a convenient way to use both Leiningen and a locally built Clojure? I find myself going back to the good old manual "create a makefile" approach way too often.

21:45 dysinger: You can build clojure and install it into your local maven repo

21:45 It's been a long time since I've done that

21:45 chouser: I do it constantly

21:45 dysinger: :)

21:45 ^ there's your man

21:46 chouser: ant -lib /your/path/to/maven-ant-tasks-2.1.1.jar ci-build

21:46 dysinger: or just put maven-ant-tasks jar in ~/.ant/lib/

21:46 * chouser does that now

21:48 chouser: then when you refer to whatever version it built, lein will hopefully pull it from your local repo

21:49 sproust: that's all for you ^^^

21:49 sproust: Thanks Chouser.

21:49 I'm not sure I get everything, lots of Java-related lingo.

21:50 I don't havea "maven-ant-tasks" jar. Do I need one?

21:50 So far the best approach has been to make my list of jars by hand and start clojure this way.

21:50 OR, just to use Leiningen.

21:51 chouser: sproust: I can't speak to "best", I just do what I'm told.

21:51 sproust: But now I want the bleeding edge Clojure, and with the Contrib all split up, I'll have a ton of libs to specify. Thinking about writing a stupid Python script to do it for me.

21:51 Hmm, I meant "best thing that works for me without wasting a lot of time."

21:51 chouser: sproust: if you're not making changes yourself, you should be able to use an alpha release of clojure and be pretty close to the bleeding edge

21:52 making changes to clojure itself, I mean

21:52 sproust: What do I tell Leningen for its version number?

21:52 I tried 1.3.0-master, wouldn't work.

21:52 Where do I find out what the allowable version strings are?

21:52 chouser: try 1.3.0-alpha3

21:52 sproust: Thanks. That's the fish, mium. Now can you teach me how to fish for that number?

21:53 chouser: I can try

21:53 sproust: Please :-)

21:54 Sorry man, don't mean to give you a hard time :-) It's one of those nights where I finally get a few hours of life back to me so I can get back into hacking LISP and I find myself fixing how to launch my Clojure again instead of hacking code. Just a bit frazzled.

21:56 1.3.0-alpha3 works for Clojure; the Contrib libraries have changed now, have they? Do I have to specify each of them as a separate dependency in project.clj?

21:57 chouser: no, it's fine, I just don't actually know

21:57 there's got to be some list of artifacts somewhere, but I don't know where

21:58 ah, here you go: http://clojure.org/downloads

21:58 sproust: chouser: How do you use the new contrib libraries then?

21:58 I meant _you_.

21:58 chouser: um

21:59 I'm not sure I do

22:00 each one should have it's own "coordinate", name and version number

22:11 sproust: chouser: thanks.

22:31 SirNick: Is it valid to have a ref nested somewhere inside a structure of another ref? Say (ref x) where x references some hash map with refs in it or something. From the clojure refs page it seems this is not recommended or doesn't work. Is that correct?

22:33 amalloy: SirNick: well...it certainly works, but i wouldn't often recommended it

22:33 SirNick: amalloy: Why's that?

22:34 amalloy: usually the system you're modeling can be modeled just fine with only one layer of indirection, and it's easier to manage with less immutability

22:34 er, mutability

22:36 SirNick: amalloy: Hmm I see, but what about if you wanted to make something like a mutable tree that needs atomic actions preformed on it?

22:37 amalloy: SirNick: then you definitely want only one reference-type thing involved. operate on a snapshot of the whole tree to create a new whole tree - no need to futz around with branches

22:38 SirNick: amalloy: Ah I see, makes sense. But you are saying that there is nothing about refs that would stop that from functioning correctly?

22:38 amalloy: a ref is just an object like any other: an immutable pointer to an object

22:39 SirNick: amalloy: Alright thanks, I was just confused by this statement on the refs page: "The values placed in Refs must be, or be considered, immutable!! Otherwise, Clojure can't help you."

22:39 amalloy: aha

22:39 he means, don't put a java.util.HashMap in a ref

22:40 SirNick: Ah yea I thought that's what he might of meant but I wasn't sure. Thanks

23:25 quizme: http://pastie.org/1296341 <-- is there a more elegant way to do this?

23:28 i'm just trying to just conj onto a deeply indexed hash.

23:32 amalloy: &(update-in {:a {:b {:c 1}}} [:a :b :c] conj 10)

23:32 sexpbot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IPersistentCollection

23:33 amalloy: (doc conj)

23:33 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

23:33 amalloy: &(update-in {:a {:b {:c [1]}}} [:a :b :c] conj 10)

23:33 sexpbot: ⟹ {:a {:b {:c [1 10]}}}

23:33 amalloy: or assoc-in if you want to add elements to the list itself

23:33 er, the hash

23:34 &(assoc-in {:a {:b {:c {}}}} [:a :b :c] :d 1)

23:34 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (4) passed to: core$assoc-in

23:34 amalloy: &(assoc-in {:a {:b {:c {}}}} [:a :b :c :d] 1)

23:34 sexpbot: ⟹ {:a {:b {:c {:d 1}}}}

23:35 quizme: amaloy: thanks !

23:38 amalloy: quizme: and you don't actually have to have the whole structure to start with: ##(assoc-in nil [:a :b :c :d] 1)

23:38 sexpbot: ⟹ {:a {:b {:c {:d 1}}}}

Logging service provided by n01se.net